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;
166 g_return_val_if_fail (cmap != NULL, NULL);
168 private->ref_count += 1;
173 gdk_colormap_unref (GdkColormap *cmap)
175 GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
177 g_return_if_fail (cmap != NULL);
178 g_return_if_fail (private->ref_count > 0);
180 private->ref_count -= 1;
181 if (private->ref_count == 0)
182 gdk_colormap_real_destroy (cmap);
186 gdk_colormap_get_visual (GdkColormap *colormap)
188 GdkColormapPrivate *private;
190 g_return_val_if_fail (colormap != NULL, NULL);
192 private = (GdkColormapPrivate *)colormap;
194 return private->visual;
197 #define MIN_SYNC_TIME 2
200 gdk_colormap_sync (GdkColormap *colormap,
204 GdkColormapPrivate *private = (GdkColormapPrivate *)colormap;
209 g_return_if_fail (colormap != NULL);
211 current_time = time (NULL);
212 if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
215 private->last_sync_time = current_time;
218 xpalette = g_new (XColor, colormap->size);
220 for (i = 0; i < colormap->size; i++)
222 if (private->info[i].ref_count == 0)
224 xpalette[nlookup].pixel = i;
225 xpalette[nlookup].red = 0;
226 xpalette[nlookup].green = 0;
227 xpalette[nlookup].blue = 0;
232 XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
234 for (i = 0; i < nlookup; i++)
236 gulong pixel = xpalette[i].pixel;
237 colormap->colors[pixel].pixel = pixel;
238 colormap->colors[pixel].red = xpalette[i].red;
239 colormap->colors[pixel].green = xpalette[i].green;
240 colormap->colors[pixel].blue = xpalette[i].blue;
248 gdk_colormap_get_system (void)
250 static GdkColormap *colormap = NULL;
251 GdkColormapPrivate *private;
255 private = g_new (GdkColormapPrivate, 1);
256 colormap = (GdkColormap*) private;
258 private->xdisplay = gdk_display;
259 private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
260 private->visual = gdk_visual_get_system ();
261 private->private_val = FALSE;
262 private->ref_count = 1;
264 private->hash = NULL;
265 private->last_sync_time = 0;
266 private->info = NULL;
268 colormap->colors = NULL;
269 colormap->size = private->visual->colormap_size;
271 if ((private->visual->type == GDK_VISUAL_GRAYSCALE) ||
272 (private->visual->type == GDK_VISUAL_PSEUDO_COLOR))
274 private->info = g_new0 (GdkColorInfo, colormap->size);
275 colormap->colors = g_new (GdkColor, colormap->size);
277 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
278 (GCompareFunc) gdk_color_equal);
280 gdk_colormap_sync (colormap, TRUE);
283 gdk_colormap_add (colormap);
290 gdk_colormap_get_system_size (void)
292 return DisplayCells (gdk_display, gdk_screen);
296 gdk_colormap_change (GdkColormap *colormap,
299 GdkColormapPrivate *private;
307 g_return_if_fail (colormap != NULL);
309 palette = g_new (XColor, ncolors);
311 private = (GdkColormapPrivate*) colormap;
312 switch (private->visual->type)
314 case GDK_VISUAL_GRAYSCALE:
315 case GDK_VISUAL_PSEUDO_COLOR:
316 for (i = 0; i < ncolors; i++)
318 palette[i].pixel = colormap->colors[i].pixel;
319 palette[i].red = colormap->colors[i].red;
320 palette[i].green = colormap->colors[i].green;
321 palette[i].blue = colormap->colors[i].blue;
322 palette[i].flags = DoRed | DoGreen | DoBlue;
325 XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
328 case GDK_VISUAL_DIRECT_COLOR:
329 visual = private->visual;
331 shift = visual->red_shift;
332 max_colors = 1 << visual->red_prec;
333 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
335 for (i = 0; i < size; i++)
337 palette[i].pixel = i << shift;
338 palette[i].red = colormap->colors[i].red;
339 palette[i].flags = DoRed;
342 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
344 shift = visual->green_shift;
345 max_colors = 1 << visual->green_prec;
346 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
348 for (i = 0; i < size; i++)
350 palette[i].pixel = i << shift;
351 palette[i].green = colormap->colors[i].green;
352 palette[i].flags = DoGreen;
355 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
357 shift = visual->blue_shift;
358 max_colors = 1 << visual->blue_prec;
359 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
361 for (i = 0; i < size; i++)
363 palette[i].pixel = i << shift;
364 palette[i].blue = colormap->colors[i].blue;
365 palette[i].flags = DoBlue;
368 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
379 gdk_colors_store (GdkColormap *colormap,
385 for (i = 0; i < ncolors; i++)
387 colormap->colors[i].pixel = colors[i].pixel;
388 colormap->colors[i].red = colors[i].red;
389 colormap->colors[i].green = colors[i].green;
390 colormap->colors[i].blue = colors[i].blue;
393 gdk_colormap_change (colormap, ncolors);
397 gdk_colors_alloc (GdkColormap *colormap,
404 GdkColormapPrivate *private;
408 g_return_val_if_fail (colormap != NULL, 0);
410 private = (GdkColormapPrivate*) colormap;
412 return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
413 contiguous, planes, nplanes, pixels, npixels);
417 for (i=0; i<npixels; i++)
419 private->info[pixels[i]].ref_count++;
420 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
427 /* This is almost identical to gdk_colormap_free_colors.
431 gdk_colors_free (GdkColormap *colormap,
436 GdkColormapPrivate *private;
441 g_return_if_fail (colormap != NULL);
442 g_return_if_fail (in_pixels != NULL);
444 private = (GdkColormapPrivate*) colormap;
446 if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
447 (private->visual->type != GDK_VISUAL_GRAYSCALE))
450 pixels = g_new (gulong, in_npixels);
452 for (i=0; i<in_npixels; i++)
454 gulong pixel = in_pixels[i];
456 if (private->info[pixel].ref_count)
458 private->info[pixel].ref_count--;
460 if (private->info[pixel].ref_count == 0)
462 pixels[npixels++] = pixel;
463 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
464 g_hash_table_remove (private->hash, &colormap->colors[in_pixels[i]]);
465 private->info[pixel].flags = 0;
471 XFreeColors (private->xdisplay, private->xcolormap,
472 pixels, npixels, planes);
477 *--------------------------------------------------------------
480 * Copy a color structure into new storage.
483 * "color" is the color struct to copy.
486 * A new color structure. Free it with gdk_color_free.
488 *--------------------------------------------------------------
491 static GMemChunk *color_chunk;
494 gdk_color_copy (GdkColor *color)
498 g_return_val_if_fail (color != NULL, NULL);
500 if (color_chunk == NULL)
501 color_chunk = g_mem_chunk_new ("colors",
506 new_color = g_chunk_new (GdkColor, color_chunk);
512 *--------------------------------------------------------------
515 * Free a color structure obtained from gdk_color_copy. Do not use
516 * with other color structures.
519 * "color" is the color struct to free.
521 *-------------------------------------------------------------- */
524 gdk_color_free (GdkColor *color)
526 g_assert (color_chunk != NULL);
527 g_return_if_fail (color != NULL);
529 g_mem_chunk_free (color_chunk, color);
533 gdk_color_white (GdkColormap *colormap,
538 g_return_val_if_fail (colormap != NULL, FALSE);
542 color->pixel = WhitePixel (gdk_display, gdk_screen);
544 color->green = 65535;
547 return_val = gdk_color_alloc (colormap, color);
556 gdk_color_black (GdkColormap *colormap,
561 g_return_val_if_fail (colormap != NULL, FALSE);
565 color->pixel = BlackPixel (gdk_display, gdk_screen);
570 return_val = gdk_color_alloc (colormap, color);
579 gdk_color_parse (const gchar *spec,
586 g_return_val_if_fail (spec != NULL, FALSE);
587 g_return_val_if_fail (color != NULL, FALSE);
589 xcolormap = DefaultColormap (gdk_display, gdk_screen);
591 if (XParseColor (gdk_display, xcolormap, spec, &xcolor))
594 color->red = xcolor.red;
595 color->green = xcolor.green;
596 color->blue = xcolor.blue;
604 /********************
606 ********************/
608 /* Try to allocate a single color using XAllocColor. If it succeeds,
609 * cache the result in our colormap, and store in ret.
612 gdk_colormap_alloc1 (GdkColormap *colormap,
616 GdkColormapPrivate *private;
619 private = (GdkColormapPrivate*) colormap;
621 xcolor.red = color->red;
622 xcolor.green = color->green;
623 xcolor.blue = color->blue;
624 xcolor.pixel = color->pixel;
625 xcolor.flags = DoRed | DoGreen | DoBlue;
627 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
629 ret->pixel = xcolor.pixel;
630 ret->red = xcolor.red;
631 ret->green = xcolor.green;
632 ret->blue = xcolor.blue;
634 if (ret->pixel < colormap->size)
636 if (private->info[ret->pixel].ref_count) /* got a duplicate */
638 XFreeColors (private->xdisplay, private->xcolormap,
643 colormap->colors[ret->pixel] = *color;
644 private->info[ret->pixel].ref_count = 1;
646 g_hash_table_insert (private->hash,
647 &colormap->colors[ret->pixel],
648 &colormap->colors[ret->pixel]);
660 gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
667 GdkColormapPrivate *private;
672 private = (GdkColormapPrivate*) colormap;
674 if (private->private_val)
677 for (i=0; i<ncolors; i++)
679 while ((index < colormap->size) && (private->info[index].ref_count != 0))
682 if (index < colormap->size)
684 colors[i].pixel = index;
686 private->info[index].ref_count++;
687 private->info[i].flags |= GDK_COLOR_WRITEABLE;
696 pixels = g_new (gulong, ncolors);
697 /* Allocation of a writeable color cells */
699 status = XAllocColorCells (private->xdisplay, private->xcolormap,
700 FALSE, NULL, 0, pixels, ncolors);
703 for (i=0; i<ncolors; i++)
705 colors[i].pixel = pixels[i];
706 private->info[pixels[i]].ref_count++;
707 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
713 return status ? ncolors : 0;
718 gdk_colormap_alloc_colors_private (GdkColormap *colormap,
725 GdkColormapPrivate *private;
727 XColor *store = g_new (XColor, ncolors);
731 private = (GdkColormapPrivate*) colormap;
734 /* First, store the colors we have room for */
737 for (i=0; i<ncolors; i++)
741 while ((index < colormap->size) && (private->info[index].ref_count != 0))
744 if (index < colormap->size)
746 store[nstore].red = colors[i].red;
747 store[nstore].blue = colors[i].blue;
748 store[nstore].green = colors[i].green;
749 store[nstore].pixel = index;
754 colors[i].pixel = index;
755 private->info[index].ref_count++;
762 XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
765 if (nremaining > 0 && best_match)
767 /* Get best matches for remaining colors */
769 gchar *available = g_new (gchar, colormap->size);
770 for (i = 0; i < colormap->size; i++)
773 for (i=0; i<ncolors; i++)
777 index = gdk_colormap_match_color (colormap,
782 colors[i] = colormap->colors[index];
783 private->info[index].ref_count++;
793 return (ncolors - nremaining);
797 gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
804 GdkColormapPrivate *private;
809 private = (GdkColormapPrivate*) colormap;
812 for (i=0; i<ncolors; i++)
816 if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
824 if (nremaining > 0 && best_match)
826 gchar *available = g_new (gchar, colormap->size);
827 for (i = 0; i < colormap->size; i++)
828 available[i] = ((private->info[i].ref_count == 0) ||
829 !(private->info[i].flags && GDK_COLOR_WRITEABLE));
830 gdk_colormap_sync (colormap, FALSE);
832 while (nremaining > 0)
834 for (i=0; i<ncolors; i++)
838 index = gdk_colormap_match_color (colormap, &colors[i], available);
841 if (private->info[index].ref_count)
843 private->info[index].ref_count++;
844 colors[i] = colormap->colors[index];
850 if (gdk_colormap_alloc1 (colormap,
851 &colormap->colors[index],
860 available[index] = FALSE;
868 success[i] = 2; /* flag as permanent failure */
876 /* Change back the values we flagged as permanent failures */
879 for (i=0; i<ncolors; i++)
882 nremaining = nfailed;
885 return (ncolors - nremaining);
889 gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
896 GdkColormapPrivate *private;
897 GdkColor *lookup_color;
901 private = (GdkColormapPrivate*) colormap;
903 /* Check for an exact match among previously allocated colors */
905 for (i=0; i<ncolors; i++)
909 lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
912 private->info[lookup_color->pixel].ref_count++;
913 colors[i].pixel = lookup_color->pixel;
921 /* If that failed, we try to allocate a new color, or approxmiate
922 * with what we can get if best_match is TRUE.
926 if (private->private_val)
927 return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
929 return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
936 gdk_colormap_alloc_colors (GdkColormap *colormap,
943 GdkColormapPrivate *private;
949 g_return_val_if_fail (colormap != NULL, FALSE);
950 g_return_val_if_fail (colors != NULL, FALSE);
952 private = (GdkColormapPrivate*) colormap;
954 for (i=0; i<ncolors; i++)
959 switch (private->visual->type)
961 case GDK_VISUAL_PSEUDO_COLOR:
962 case GDK_VISUAL_GRAYSCALE:
964 return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
965 writeable, best_match, success);
967 return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
968 writeable, best_match, success);
971 case GDK_VISUAL_DIRECT_COLOR:
972 case GDK_VISUAL_TRUE_COLOR:
973 visual = private->visual;
975 for (i=0; i<ncolors; i++)
977 colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
978 ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
979 ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
984 case GDK_VISUAL_STATIC_GRAY:
985 case GDK_VISUAL_STATIC_COLOR:
986 for (i=0; i<ncolors; i++)
988 xcolor.red = colors[i].red;
989 xcolor.green = colors[i].green;
990 xcolor.blue = colors[i].blue;
991 xcolor.pixel = colors[i].pixel;
992 xcolor.flags = DoRed | DoGreen | DoBlue;
994 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
996 colors[i].pixel = xcolor.pixel;
1008 gdk_colormap_alloc_color (GdkColormap *colormap,
1011 gboolean best_match)
1015 gdk_colormap_alloc_colors (colormap, color, 1, writeable, best_match,
1021 /* This is almost identical to gdk_colors_free.
1022 * Keep them in sync!
1025 gdk_colormap_free_colors (GdkColormap *colormap,
1029 GdkColormapPrivate *private;
1034 g_return_if_fail (colormap != NULL);
1035 g_return_if_fail (colors != NULL);
1037 private = (GdkColormapPrivate*) colormap;
1039 if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
1040 (private->visual->type != GDK_VISUAL_GRAYSCALE))
1043 pixels = g_new (gulong, ncolors);
1045 for (i=0; i<ncolors; i++)
1047 gulong pixel = colors[i].pixel;
1049 if (private->info[pixel].ref_count)
1051 private->info[pixel].ref_count--;
1053 if (private->info[pixel].ref_count == 0)
1055 pixels[npixels++] = pixel;
1056 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
1057 g_hash_table_remove (private->hash, &colors[i]);
1058 private->info[pixel].flags = 0;
1064 XFreeColors (private->xdisplay, private->xcolormap,
1065 pixels, npixels, 0);
1071 gdk_color_alloc (GdkColormap *colormap,
1076 gdk_colormap_alloc_colors (colormap, color, 1, FALSE, TRUE, &success);
1082 gdk_color_change (GdkColormap *colormap,
1085 GdkColormapPrivate *private;
1088 g_return_val_if_fail (colormap != NULL, FALSE);
1089 g_return_val_if_fail (color != NULL, FALSE);
1091 xcolor.pixel = color->pixel;
1092 xcolor.red = color->red;
1093 xcolor.green = color->green;
1094 xcolor.blue = color->blue;
1095 xcolor.flags = DoRed | DoGreen | DoBlue;
1097 private = (GdkColormapPrivate*) colormap;
1098 XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
1104 gdk_color_hash (const GdkColor *colora,
1105 const GdkColor *colorb)
1107 return ((colora->red) +
1108 (colora->green << 11) +
1109 (colora->blue << 22) +
1110 (colora->blue >> 6));
1114 gdk_color_equal (const GdkColor *colora,
1115 const GdkColor *colorb)
1117 g_return_val_if_fail (colora != NULL, FALSE);
1118 g_return_val_if_fail (colorb != NULL, FALSE);
1120 return ((colora->red == colorb->red) &&
1121 (colora->green == colorb->green) &&
1122 (colora->blue == colorb->blue));
1125 /* XXX: Do not use this function until it is fixed. An X Colormap
1126 * is useless unless we also have the visual.
1129 gdkx_colormap_get (Colormap xcolormap)
1131 GdkColormap *colormap;
1132 GdkColormapPrivate *private;
1134 colormap = gdk_colormap_lookup (xcolormap);
1138 if (xcolormap == DefaultColormap (gdk_display, gdk_screen))
1139 return gdk_colormap_get_system ();
1141 private = g_new (GdkColormapPrivate, 1);
1142 colormap = (GdkColormap*) private;
1144 private->xdisplay = gdk_display;
1145 private->xcolormap = xcolormap;
1146 private->visual = NULL;
1147 private->private_val = TRUE;
1149 /* To do the following safely, we would have to have some way of finding
1150 * out what the size or visual of the given colormap is. It seems
1151 * X doesn't allow this
1155 for (i = 0; i < 256; i++)
1157 xpalette[i].pixel = i;
1158 xpalette[i].red = 0;
1159 xpalette[i].green = 0;
1160 xpalette[i].blue = 0;
1163 XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
1165 for (i = 0; i < 256; i++)
1167 colormap->colors[i].pixel = xpalette[i].pixel;
1168 colormap->colors[i].red = xpalette[i].red;
1169 colormap->colors[i].green = xpalette[i].green;
1170 colormap->colors[i].blue = xpalette[i].blue;
1174 colormap->colors = NULL;
1177 gdk_colormap_add (colormap);
1184 gdk_colormap_match_color (GdkColormap *cmap,
1186 const gchar *available)
1190 gint rdiff, gdiff, bdiff;
1193 g_return_val_if_fail (cmap != NULL, 0);
1194 g_return_val_if_fail (color != NULL, 0);
1196 colors = cmap->colors;
1200 for (i = 0; i < cmap->size; i++)
1202 if ((!available) || (available && available[i]))
1204 rdiff = (color->red - colors[i].red);
1205 gdiff = (color->green - colors[i].green);
1206 bdiff = (color->blue - colors[i].blue);
1208 sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
1223 gdk_colormap_lookup (Colormap xcolormap)
1230 cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
1235 gdk_colormap_add (GdkColormap *cmap)
1237 GdkColormapPrivate *private;
1240 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1241 (GCompareFunc) gdk_colormap_cmp);
1243 private = (GdkColormapPrivate*) cmap;
1245 g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
1249 gdk_colormap_remove (GdkColormap *cmap)
1251 GdkColormapPrivate *private;
1254 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1255 (GCompareFunc) gdk_colormap_cmp);
1257 private = (GdkColormapPrivate*) cmap;
1259 g_hash_table_remove (colormap_hash, &private->xcolormap);
1263 gdk_colormap_hash (Colormap *cmap)
1269 gdk_colormap_cmp (Colormap *a,