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.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdkprivate.h"
34 static gint gdk_colormap_match_color (GdkColormap *cmap,
36 const gchar *available);
37 static void gdk_colormap_add (GdkColormap *cmap);
38 static void gdk_colormap_remove (GdkColormap *cmap);
39 static guint gdk_colormap_hash (Colormap *cmap);
40 static gint gdk_colormap_cmp (Colormap *a,
42 static void gdk_colormap_real_destroy (GdkColormap *colormap);
44 static GHashTable *colormap_hash = NULL;
48 gdk_colormap_new (GdkVisual *visual,
51 GdkColormap *colormap;
52 GdkColormapPrivate *private;
57 g_return_val_if_fail (visual != NULL, NULL);
59 private = g_new (GdkColormapPrivate, 1);
60 colormap = (GdkColormap*) private;
62 private->xdisplay = gdk_display;
63 private->visual = visual;
64 private->ref_count = 1;
67 private->last_sync_time = 0;
70 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
72 colormap->size = visual->colormap_size;
73 colormap->colors = NULL;
77 case GDK_VISUAL_GRAYSCALE:
78 case GDK_VISUAL_PSEUDO_COLOR:
79 private->info = g_new0 (GdkColorInfo, colormap->size);
80 colormap->colors = g_new (GdkColor, colormap->size);
82 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
83 (GCompareFunc) gdk_color_equal);
85 private->private_val = private_cmap;
86 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
87 xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
91 XColor *default_colors;
93 default_colors = g_new (XColor, colormap->size);
95 for (i = 0; i < colormap->size; i++)
96 default_colors[i].pixel = i;
98 XQueryColors (private->xdisplay,
99 DefaultColormap (private->xdisplay, gdk_screen),
100 default_colors, colormap->size);
102 for (i = 0; i < colormap->size; i++)
104 colormap->colors[i].pixel = default_colors[i].pixel;
105 colormap->colors[i].red = default_colors[i].red;
106 colormap->colors[i].green = default_colors[i].green;
107 colormap->colors[i].blue = default_colors[i].blue;
110 gdk_colormap_change (colormap, colormap->size);
112 g_free (default_colors);
116 case GDK_VISUAL_DIRECT_COLOR:
117 private->private_val = TRUE;
118 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
120 colormap->colors = g_new (GdkColor, colormap->size);
122 size = 1 << visual->red_prec;
123 for (i = 0; i < size; i++)
124 colormap->colors[i].red = i * 65535 / (size - 1);
126 size = 1 << visual->green_prec;
127 for (i = 0; i < size; i++)
128 colormap->colors[i].green = i * 65535 / (size - 1);
130 size = 1 << visual->blue_prec;
131 for (i = 0; i < size; i++)
132 colormap->colors[i].blue = i * 65535 / (size - 1);
134 gdk_colormap_change (colormap, colormap->size);
137 case GDK_VISUAL_STATIC_GRAY:
138 case GDK_VISUAL_STATIC_COLOR:
139 case GDK_VISUAL_TRUE_COLOR:
140 private->private_val = FALSE;
141 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
146 gdk_colormap_add (colormap);
152 gdk_colormap_real_destroy (GdkColormap *colormap)
154 GdkColormapPrivate *private = (GdkColormapPrivate*) colormap;
156 g_return_if_fail (colormap != NULL);
157 g_return_if_fail (private->ref_count == 0);
159 gdk_colormap_remove (colormap);
160 XFreeColormap (private->xdisplay, private->xcolormap);
163 g_hash_table_destroy (private->hash);
165 g_free (private->info);
166 g_free (colormap->colors);
171 gdk_colormap_ref (GdkColormap *cmap)
173 GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
175 g_return_val_if_fail (cmap != NULL, NULL);
177 private->ref_count += 1;
182 gdk_colormap_unref (GdkColormap *cmap)
184 GdkColormapPrivate *private = (GdkColormapPrivate *)cmap;
186 g_return_if_fail (cmap != NULL);
187 g_return_if_fail (private->ref_count > 0);
189 private->ref_count -= 1;
190 if (private->ref_count == 0)
191 gdk_colormap_real_destroy (cmap);
195 gdk_colormap_get_visual (GdkColormap *colormap)
197 GdkColormapPrivate *private;
199 g_return_val_if_fail (colormap != NULL, NULL);
201 private = (GdkColormapPrivate *)colormap;
203 return private->visual;
206 #define MIN_SYNC_TIME 2
209 gdk_colormap_sync (GdkColormap *colormap,
213 GdkColormapPrivate *private = (GdkColormapPrivate *)colormap;
218 g_return_if_fail (colormap != NULL);
220 current_time = time (NULL);
221 if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
224 private->last_sync_time = current_time;
227 xpalette = g_new (XColor, colormap->size);
229 for (i = 0; i < colormap->size; i++)
231 if (private->info[i].ref_count == 0)
233 xpalette[nlookup].pixel = i;
234 xpalette[nlookup].red = 0;
235 xpalette[nlookup].green = 0;
236 xpalette[nlookup].blue = 0;
241 XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
243 for (i = 0; i < nlookup; i++)
245 gulong pixel = xpalette[i].pixel;
246 colormap->colors[pixel].pixel = pixel;
247 colormap->colors[pixel].red = xpalette[i].red;
248 colormap->colors[pixel].green = xpalette[i].green;
249 colormap->colors[pixel].blue = xpalette[i].blue;
257 gdk_colormap_get_system (void)
259 static GdkColormap *colormap = NULL;
260 GdkColormapPrivate *private;
264 private = g_new (GdkColormapPrivate, 1);
265 colormap = (GdkColormap*) private;
267 private->xdisplay = gdk_display;
268 private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
269 private->visual = gdk_visual_get_system ();
270 private->private_val = FALSE;
271 private->ref_count = 1;
273 private->hash = NULL;
274 private->last_sync_time = 0;
275 private->info = NULL;
277 colormap->colors = NULL;
278 colormap->size = private->visual->colormap_size;
280 if ((private->visual->type == GDK_VISUAL_GRAYSCALE) ||
281 (private->visual->type == GDK_VISUAL_PSEUDO_COLOR))
283 private->info = g_new0 (GdkColorInfo, colormap->size);
284 colormap->colors = g_new (GdkColor, colormap->size);
286 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
287 (GCompareFunc) gdk_color_equal);
289 gdk_colormap_sync (colormap, TRUE);
292 gdk_colormap_add (colormap);
299 gdk_colormap_get_system_size (void)
301 return DisplayCells (gdk_display, gdk_screen);
305 gdk_colormap_change (GdkColormap *colormap,
308 GdkColormapPrivate *private;
316 g_return_if_fail (colormap != NULL);
318 palette = g_new (XColor, ncolors);
320 private = (GdkColormapPrivate*) colormap;
321 switch (private->visual->type)
323 case GDK_VISUAL_GRAYSCALE:
324 case GDK_VISUAL_PSEUDO_COLOR:
325 for (i = 0; i < ncolors; i++)
327 palette[i].pixel = colormap->colors[i].pixel;
328 palette[i].red = colormap->colors[i].red;
329 palette[i].green = colormap->colors[i].green;
330 palette[i].blue = colormap->colors[i].blue;
331 palette[i].flags = DoRed | DoGreen | DoBlue;
334 XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
337 case GDK_VISUAL_DIRECT_COLOR:
338 visual = private->visual;
340 shift = visual->red_shift;
341 max_colors = 1 << visual->red_prec;
342 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
344 for (i = 0; i < size; i++)
346 palette[i].pixel = i << shift;
347 palette[i].red = colormap->colors[i].red;
348 palette[i].flags = DoRed;
351 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
353 shift = visual->green_shift;
354 max_colors = 1 << visual->green_prec;
355 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
357 for (i = 0; i < size; i++)
359 palette[i].pixel = i << shift;
360 palette[i].green = colormap->colors[i].green;
361 palette[i].flags = DoGreen;
364 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
366 shift = visual->blue_shift;
367 max_colors = 1 << visual->blue_prec;
368 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
370 for (i = 0; i < size; i++)
372 palette[i].pixel = i << shift;
373 palette[i].blue = colormap->colors[i].blue;
374 palette[i].flags = DoBlue;
377 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
388 gdk_colors_store (GdkColormap *colormap,
394 for (i = 0; i < ncolors; i++)
396 colormap->colors[i].pixel = colors[i].pixel;
397 colormap->colors[i].red = colors[i].red;
398 colormap->colors[i].green = colors[i].green;
399 colormap->colors[i].blue = colors[i].blue;
402 gdk_colormap_change (colormap, ncolors);
406 gdk_colors_alloc (GdkColormap *colormap,
413 GdkColormapPrivate *private;
417 g_return_val_if_fail (colormap != NULL, 0);
419 private = (GdkColormapPrivate*) colormap;
421 return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
422 contiguous, planes, nplanes, pixels, npixels);
426 for (i=0; i<npixels; i++)
428 private->info[pixels[i]].ref_count++;
429 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
433 return return_val != 0;
437 *--------------------------------------------------------------
440 * Copy a color structure into new storage.
443 * "color" is the color struct to copy.
446 * A new color structure. Free it with gdk_color_free.
448 *--------------------------------------------------------------
451 static GMemChunk *color_chunk;
454 gdk_color_copy (GdkColor *color)
458 g_return_val_if_fail (color != NULL, NULL);
460 if (color_chunk == NULL)
461 color_chunk = g_mem_chunk_new ("colors",
466 new_color = g_chunk_new (GdkColor, color_chunk);
472 *--------------------------------------------------------------
475 * Free a color structure obtained from gdk_color_copy. Do not use
476 * with other color structures.
479 * "color" is the color struct to free.
481 *-------------------------------------------------------------- */
484 gdk_color_free (GdkColor *color)
486 g_assert (color_chunk != NULL);
487 g_return_if_fail (color != NULL);
489 g_mem_chunk_free (color_chunk, color);
493 gdk_color_white (GdkColormap *colormap,
498 g_return_val_if_fail (colormap != NULL, FALSE);
502 color->pixel = WhitePixel (gdk_display, gdk_screen);
504 color->green = 65535;
507 return_val = gdk_color_alloc (colormap, color);
516 gdk_color_black (GdkColormap *colormap,
521 g_return_val_if_fail (colormap != NULL, FALSE);
525 color->pixel = BlackPixel (gdk_display, gdk_screen);
530 return_val = gdk_color_alloc (colormap, color);
539 gdk_color_parse (const gchar *spec,
546 g_return_val_if_fail (spec != NULL, FALSE);
547 g_return_val_if_fail (color != NULL, FALSE);
549 xcolormap = DefaultColormap (gdk_display, gdk_screen);
551 if (XParseColor (gdk_display, xcolormap, spec, &xcolor))
554 color->red = xcolor.red;
555 color->green = xcolor.green;
556 color->blue = xcolor.blue;
564 /* This is almost identical to gdk_colormap_free_colors.
568 gdk_colors_free (GdkColormap *colormap,
573 GdkColormapPrivate *private;
578 g_return_if_fail (colormap != NULL);
579 g_return_if_fail (in_pixels != NULL);
581 private = (GdkColormapPrivate*) colormap;
583 if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
584 (private->visual->type != GDK_VISUAL_GRAYSCALE))
587 pixels = g_new (gulong, in_npixels);
589 for (i=0; i<in_npixels; i++)
591 gulong pixel = in_pixels[i];
593 if (private->info[pixel].ref_count)
595 private->info[pixel].ref_count--;
597 if (private->info[pixel].ref_count == 0)
599 pixels[npixels++] = pixel;
600 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
601 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
602 private->info[pixel].flags = 0;
608 XFreeColors (private->xdisplay, private->xcolormap,
609 pixels, npixels, planes);
613 /* This is almost identical to gdk_colors_free.
617 gdk_colormap_free_colors (GdkColormap *colormap,
621 GdkColormapPrivate *private;
626 g_return_if_fail (colormap != NULL);
627 g_return_if_fail (colors != NULL);
629 private = (GdkColormapPrivate*) colormap;
631 if ((private->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
632 (private->visual->type != GDK_VISUAL_GRAYSCALE))
635 pixels = g_new (gulong, ncolors);
637 for (i=0; i<ncolors; i++)
639 gulong pixel = colors[i].pixel;
641 if (private->info[pixel].ref_count)
643 private->info[pixel].ref_count--;
645 if (private->info[pixel].ref_count == 0)
647 pixels[npixels++] = pixel;
648 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
649 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
650 private->info[pixel].flags = 0;
656 XFreeColors (private->xdisplay, private->xcolormap,
662 /********************
664 ********************/
666 /* Try to allocate a single color using XAllocColor. If it succeeds,
667 * cache the result in our colormap, and store in ret.
670 gdk_colormap_alloc1 (GdkColormap *colormap,
674 GdkColormapPrivate *private;
677 private = (GdkColormapPrivate*) colormap;
679 xcolor.red = color->red;
680 xcolor.green = color->green;
681 xcolor.blue = color->blue;
682 xcolor.pixel = color->pixel;
683 xcolor.flags = DoRed | DoGreen | DoBlue;
685 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
687 ret->pixel = xcolor.pixel;
688 ret->red = xcolor.red;
689 ret->green = xcolor.green;
690 ret->blue = xcolor.blue;
692 if (ret->pixel < colormap->size)
694 if (private->info[ret->pixel].ref_count) /* got a duplicate */
696 XFreeColors (private->xdisplay, private->xcolormap,
701 colormap->colors[ret->pixel] = *color;
702 colormap->colors[ret->pixel].pixel = ret->pixel;
703 private->info[ret->pixel].ref_count = 1;
705 g_hash_table_insert (private->hash,
706 &colormap->colors[ret->pixel],
707 &colormap->colors[ret->pixel]);
719 gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
726 GdkColormapPrivate *private;
731 private = (GdkColormapPrivate*) colormap;
733 if (private->private_val)
736 for (i=0; i<ncolors; i++)
738 while ((index < colormap->size) && (private->info[index].ref_count != 0))
741 if (index < colormap->size)
743 colors[i].pixel = index;
745 private->info[index].ref_count++;
746 private->info[i].flags |= GDK_COLOR_WRITEABLE;
755 pixels = g_new (gulong, ncolors);
756 /* Allocation of a writeable color cells */
758 status = XAllocColorCells (private->xdisplay, private->xcolormap,
759 FALSE, NULL, 0, pixels, ncolors);
762 for (i=0; i<ncolors; i++)
764 colors[i].pixel = pixels[i];
765 private->info[pixels[i]].ref_count++;
766 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
772 return status ? ncolors : 0;
777 gdk_colormap_alloc_colors_private (GdkColormap *colormap,
784 GdkColormapPrivate *private;
786 XColor *store = g_new (XColor, ncolors);
790 private = (GdkColormapPrivate*) colormap;
793 /* First, store the colors we have room for */
796 for (i=0; i<ncolors; i++)
800 while ((index < colormap->size) && (private->info[index].ref_count != 0))
803 if (index < colormap->size)
805 store[nstore].red = colors[i].red;
806 store[nstore].blue = colors[i].blue;
807 store[nstore].green = colors[i].green;
808 store[nstore].pixel = index;
813 colors[i].pixel = index;
814 private->info[index].ref_count++;
821 XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
824 if (nremaining > 0 && best_match)
826 /* Get best matches for remaining colors */
828 gchar *available = g_new (gchar, colormap->size);
829 for (i = 0; i < colormap->size; i++)
832 for (i=0; i<ncolors; i++)
836 index = gdk_colormap_match_color (colormap,
841 colors[i] = colormap->colors[index];
842 private->info[index].ref_count++;
852 return (ncolors - nremaining);
856 gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
863 GdkColormapPrivate *private;
868 private = (GdkColormapPrivate*) colormap;
871 for (i=0; i<ncolors; i++)
875 if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
883 if (nremaining > 0 && best_match)
885 gchar *available = g_new (gchar, colormap->size);
886 for (i = 0; i < colormap->size; i++)
887 available[i] = ((private->info[i].ref_count == 0) ||
888 !(private->info[i].flags && GDK_COLOR_WRITEABLE));
889 gdk_colormap_sync (colormap, FALSE);
891 while (nremaining > 0)
893 for (i=0; i<ncolors; i++)
897 index = gdk_colormap_match_color (colormap, &colors[i], available);
900 if (private->info[index].ref_count)
902 private->info[index].ref_count++;
903 colors[i] = colormap->colors[index];
909 if (gdk_colormap_alloc1 (colormap,
910 &colormap->colors[index],
919 available[index] = FALSE;
927 success[i] = 2; /* flag as permanent failure */
935 /* Change back the values we flagged as permanent failures */
938 for (i=0; i<ncolors; i++)
941 nremaining = nfailed;
944 return (ncolors - nremaining);
948 gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
955 GdkColormapPrivate *private;
956 GdkColor *lookup_color;
960 private = (GdkColormapPrivate*) colormap;
962 /* Check for an exact match among previously allocated colors */
964 for (i=0; i<ncolors; i++)
968 lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
971 private->info[lookup_color->pixel].ref_count++;
972 colors[i].pixel = lookup_color->pixel;
980 /* If that failed, we try to allocate a new color, or approxmiate
981 * with what we can get if best_match is TRUE.
985 if (private->private_val)
986 return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
988 return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
995 gdk_colormap_alloc_colors (GdkColormap *colormap,
1002 GdkColormapPrivate *private;
1005 gint nremaining = 0;
1008 g_return_val_if_fail (colormap != NULL, FALSE);
1009 g_return_val_if_fail (colors != NULL, FALSE);
1011 private = (GdkColormapPrivate*) colormap;
1013 for (i=0; i<ncolors; i++)
1018 switch (private->visual->type)
1020 case GDK_VISUAL_PSEUDO_COLOR:
1021 case GDK_VISUAL_GRAYSCALE:
1023 return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
1024 writeable, best_match, success);
1026 return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
1027 writeable, best_match, success);
1030 case GDK_VISUAL_DIRECT_COLOR:
1031 case GDK_VISUAL_TRUE_COLOR:
1032 visual = private->visual;
1034 for (i=0; i<ncolors; i++)
1036 colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
1037 ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
1038 ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
1043 case GDK_VISUAL_STATIC_GRAY:
1044 case GDK_VISUAL_STATIC_COLOR:
1045 for (i=0; i<ncolors; i++)
1047 xcolor.red = colors[i].red;
1048 xcolor.green = colors[i].green;
1049 xcolor.blue = colors[i].blue;
1050 xcolor.pixel = colors[i].pixel;
1051 xcolor.flags = DoRed | DoGreen | DoBlue;
1053 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
1055 colors[i].pixel = xcolor.pixel;
1067 gdk_colormap_alloc_color (GdkColormap *colormap,
1070 gboolean best_match)
1074 gdk_colormap_alloc_colors (colormap, color, 1, writeable, best_match,
1081 gdk_color_alloc (GdkColormap *colormap,
1086 gdk_colormap_alloc_colors (colormap, color, 1, FALSE, TRUE, &success);
1092 gdk_color_change (GdkColormap *colormap,
1095 GdkColormapPrivate *private;
1098 g_return_val_if_fail (colormap != NULL, FALSE);
1099 g_return_val_if_fail (color != NULL, FALSE);
1101 xcolor.pixel = color->pixel;
1102 xcolor.red = color->red;
1103 xcolor.green = color->green;
1104 xcolor.blue = color->blue;
1105 xcolor.flags = DoRed | DoGreen | DoBlue;
1107 private = (GdkColormapPrivate*) colormap;
1108 XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
1114 gdk_color_hash (const GdkColor *colora)
1116 return ((colora->red) +
1117 (colora->green << 11) +
1118 (colora->blue << 22) +
1119 (colora->blue >> 6));
1123 gdk_color_equal (const GdkColor *colora,
1124 const GdkColor *colorb)
1126 g_return_val_if_fail (colora != NULL, FALSE);
1127 g_return_val_if_fail (colorb != NULL, FALSE);
1129 return ((colora->red == colorb->red) &&
1130 (colora->green == colorb->green) &&
1131 (colora->blue == colorb->blue));
1134 /* XXX: Do not use this function until it is fixed. An X Colormap
1135 * is useless unless we also have the visual.
1138 gdkx_colormap_get (Colormap xcolormap)
1140 GdkColormap *colormap;
1141 GdkColormapPrivate *private;
1143 colormap = gdk_colormap_lookup (xcolormap);
1147 if (xcolormap == DefaultColormap (gdk_display, gdk_screen))
1148 return gdk_colormap_get_system ();
1150 private = g_new (GdkColormapPrivate, 1);
1151 colormap = (GdkColormap*) private;
1153 private->xdisplay = gdk_display;
1154 private->xcolormap = xcolormap;
1155 private->visual = NULL;
1156 private->private_val = TRUE;
1158 /* To do the following safely, we would have to have some way of finding
1159 * out what the size or visual of the given colormap is. It seems
1160 * X doesn't allow this
1164 for (i = 0; i < 256; i++)
1166 xpalette[i].pixel = i;
1167 xpalette[i].red = 0;
1168 xpalette[i].green = 0;
1169 xpalette[i].blue = 0;
1172 XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
1174 for (i = 0; i < 256; i++)
1176 colormap->colors[i].pixel = xpalette[i].pixel;
1177 colormap->colors[i].red = xpalette[i].red;
1178 colormap->colors[i].green = xpalette[i].green;
1179 colormap->colors[i].blue = xpalette[i].blue;
1183 colormap->colors = NULL;
1186 gdk_colormap_add (colormap);
1193 gdk_colormap_match_color (GdkColormap *cmap,
1195 const gchar *available)
1199 gint rdiff, gdiff, bdiff;
1202 g_return_val_if_fail (cmap != NULL, 0);
1203 g_return_val_if_fail (color != NULL, 0);
1205 colors = cmap->colors;
1209 for (i = 0; i < cmap->size; i++)
1211 if ((!available) || (available && available[i]))
1213 rdiff = (color->red - colors[i].red);
1214 gdiff = (color->green - colors[i].green);
1215 bdiff = (color->blue - colors[i].blue);
1217 sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
1232 gdk_colormap_lookup (Colormap xcolormap)
1239 cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
1244 gdk_colormap_add (GdkColormap *cmap)
1246 GdkColormapPrivate *private;
1249 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1250 (GCompareFunc) gdk_colormap_cmp);
1252 private = (GdkColormapPrivate*) cmap;
1254 g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
1258 gdk_colormap_remove (GdkColormap *cmap)
1260 GdkColormapPrivate *private;
1263 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1264 (GCompareFunc) gdk_colormap_cmp);
1266 private = (GdkColormapPrivate*) cmap;
1268 g_hash_table_remove (colormap_hash, &private->xcolormap);
1272 gdk_colormap_hash (Colormap *cmap)
1278 gdk_colormap_cmp (Colormap *a,