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 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.
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.
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.
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/.
30 #include "gdkprivate-x11.h"
32 #define GDK_COLORMAP_PRIVATE_DATA(cmap) ((GdkColormapPrivateX11 *) GDK_COLORMAP (cmap)->windowing_data)
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 gboolean gdk_colormap_equal (Colormap *a,
43 static void gdk_colormap_init (GdkColormap *colormap);
44 static void gdk_colormap_class_init (GdkColormapClass *klass);
45 static void gdk_colormap_finalize (GObject *object);
47 static gpointer parent_class = NULL;
49 static GHashTable *colormap_hash = NULL;
52 gdk_colormap_get_type (void)
54 static GType object_type = 0;
58 static const GTypeInfo object_info =
60 sizeof (GdkColormapClass),
62 (GBaseFinalizeFunc) NULL,
63 (GClassInitFunc) gdk_colormap_class_init,
64 NULL, /* class_finalize */
65 NULL, /* class_data */
68 (GInstanceInitFunc) gdk_colormap_init,
71 object_type = g_type_register_static (G_TYPE_OBJECT,
80 gdk_colormap_init (GdkColormap *colormap)
82 GdkColormapPrivateX11 *private;
84 private = g_new (GdkColormapPrivateX11, 1);
86 colormap->windowing_data = private;
88 private->xdisplay = gdk_display;
90 private->last_sync_time = 0;
94 colormap->colors = NULL;
98 gdk_colormap_class_init (GdkColormapClass *klass)
100 GObjectClass *object_class = G_OBJECT_CLASS (klass);
102 parent_class = g_type_class_peek_parent (klass);
104 object_class->finalize = gdk_colormap_finalize;
108 gdk_colormap_finalize (GObject *object)
110 GdkColormap *colormap = GDK_COLORMAP (object);
111 GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap);
113 gdk_colormap_remove (colormap);
115 XFreeColormap (private->xdisplay, private->xcolormap);
118 g_hash_table_destroy (private->hash);
120 g_free (private->info);
121 g_free (colormap->colors);
123 G_OBJECT_CLASS (parent_class)->finalize (object);
127 gdk_colormap_new (GdkVisual *visual,
128 gboolean private_cmap)
130 GdkColormap *colormap;
131 GdkColormapPrivateX11 *private;
136 /* FIXME when object properties settle down, there needs to be some
137 * kind of default construction (and construct-only arguments)
140 g_return_val_if_fail (visual != NULL, NULL);
142 colormap = g_object_new (gdk_colormap_get_type (), NULL);
143 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
145 colormap->visual = visual;
147 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
149 colormap->size = visual->colormap_size;
151 switch (visual->type)
153 case GDK_VISUAL_GRAYSCALE:
154 case GDK_VISUAL_PSEUDO_COLOR:
155 private->info = g_new0 (GdkColorInfo, colormap->size);
156 colormap->colors = g_new (GdkColor, colormap->size);
158 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
159 (GEqualFunc) gdk_color_equal);
161 private->private_val = private_cmap;
162 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
163 xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
167 XColor *default_colors;
169 default_colors = g_new (XColor, colormap->size);
171 for (i = 0; i < colormap->size; i++)
172 default_colors[i].pixel = i;
174 XQueryColors (private->xdisplay,
175 DefaultColormap (private->xdisplay, gdk_screen),
176 default_colors, colormap->size);
178 for (i = 0; i < colormap->size; i++)
180 colormap->colors[i].pixel = default_colors[i].pixel;
181 colormap->colors[i].red = default_colors[i].red;
182 colormap->colors[i].green = default_colors[i].green;
183 colormap->colors[i].blue = default_colors[i].blue;
186 gdk_colormap_change (colormap, colormap->size);
188 g_free (default_colors);
192 case GDK_VISUAL_DIRECT_COLOR:
193 private->private_val = TRUE;
194 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
196 colormap->colors = g_new (GdkColor, colormap->size);
198 size = 1 << visual->red_prec;
199 for (i = 0; i < size; i++)
200 colormap->colors[i].red = i * 65535 / (size - 1);
202 size = 1 << visual->green_prec;
203 for (i = 0; i < size; i++)
204 colormap->colors[i].green = i * 65535 / (size - 1);
206 size = 1 << visual->blue_prec;
207 for (i = 0; i < size; i++)
208 colormap->colors[i].blue = i * 65535 / (size - 1);
210 gdk_colormap_change (colormap, colormap->size);
213 case GDK_VISUAL_STATIC_GRAY:
214 case GDK_VISUAL_STATIC_COLOR:
215 private->private_val = FALSE;
216 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
219 colormap->colors = g_new (GdkColor, colormap->size);
220 gdk_colormap_sync (colormap);
223 case GDK_VISUAL_TRUE_COLOR:
224 private->private_val = FALSE;
225 private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window,
230 gdk_colormap_add (colormap);
235 #define MIN_SYNC_TIME 2
238 gdk_colormap_sync (GdkColormap *colormap,
242 GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap);
247 g_return_if_fail (GDK_IS_COLORMAP (colormap));
249 current_time = time (NULL);
250 if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
253 private->last_sync_time = current_time;
256 xpalette = g_new (XColor, colormap->size);
258 for (i = 0; i < colormap->size; i++)
260 if (!private->info || private->info[i].ref_count == 0)
262 xpalette[nlookup].pixel = i;
263 xpalette[nlookup].red = 0;
264 xpalette[nlookup].green = 0;
265 xpalette[nlookup].blue = 0;
270 XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
272 for (i = 0; i < nlookup; i++)
274 gulong pixel = xpalette[i].pixel;
275 colormap->colors[pixel].pixel = pixel;
276 colormap->colors[pixel].red = xpalette[i].red;
277 colormap->colors[pixel].green = xpalette[i].green;
278 colormap->colors[pixel].blue = xpalette[i].blue;
286 gdk_colormap_get_system (void)
288 static GdkColormap *colormap = NULL;
289 GdkColormapPrivateX11 *private;
293 colormap = g_object_new (gdk_colormap_get_type (), NULL);
294 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
296 private->xdisplay = gdk_display;
297 private->xcolormap = DefaultColormap (gdk_display, gdk_screen);
298 colormap->visual = gdk_visual_get_system ();
299 private->private_val = FALSE;
301 private->hash = NULL;
302 private->last_sync_time = 0;
303 private->info = NULL;
305 colormap->colors = NULL;
306 colormap->size = colormap->visual->colormap_size;
308 switch (colormap->visual->type)
310 case GDK_VISUAL_GRAYSCALE:
311 case GDK_VISUAL_PSEUDO_COLOR:
312 private->info = g_new0 (GdkColorInfo, colormap->size);
313 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
314 (GEqualFunc) gdk_color_equal);
316 case GDK_VISUAL_STATIC_GRAY:
317 case GDK_VISUAL_STATIC_COLOR:
318 colormap->colors = g_new (GdkColor, colormap->size);
319 gdk_colormap_sync (colormap, TRUE);
321 case GDK_VISUAL_DIRECT_COLOR:
322 case GDK_VISUAL_TRUE_COLOR:
326 gdk_colormap_add (colormap);
333 gdk_colormap_get_system_size (void)
335 return DisplayCells (gdk_display, gdk_screen);
339 gdk_colormap_change (GdkColormap *colormap,
342 GdkColormapPrivateX11 *private;
350 g_return_if_fail (GDK_IS_COLORMAP (colormap));
352 palette = g_new (XColor, ncolors);
354 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
355 switch (colormap->visual->type)
357 case GDK_VISUAL_GRAYSCALE:
358 case GDK_VISUAL_PSEUDO_COLOR:
359 for (i = 0; i < ncolors; i++)
361 palette[i].pixel = colormap->colors[i].pixel;
362 palette[i].red = colormap->colors[i].red;
363 palette[i].green = colormap->colors[i].green;
364 palette[i].blue = colormap->colors[i].blue;
365 palette[i].flags = DoRed | DoGreen | DoBlue;
368 XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
371 case GDK_VISUAL_DIRECT_COLOR:
372 visual = colormap->visual;
374 shift = visual->red_shift;
375 max_colors = 1 << visual->red_prec;
376 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
378 for (i = 0; i < size; i++)
380 palette[i].pixel = i << shift;
381 palette[i].red = colormap->colors[i].red;
382 palette[i].flags = DoRed;
385 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
387 shift = visual->green_shift;
388 max_colors = 1 << visual->green_prec;
389 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
391 for (i = 0; i < size; i++)
393 palette[i].pixel = i << shift;
394 palette[i].green = colormap->colors[i].green;
395 palette[i].flags = DoGreen;
398 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
400 shift = visual->blue_shift;
401 max_colors = 1 << visual->blue_prec;
402 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
404 for (i = 0; i < size; i++)
406 palette[i].pixel = i << shift;
407 palette[i].blue = colormap->colors[i].blue;
408 palette[i].flags = DoBlue;
411 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
422 gdk_colors_alloc (GdkColormap *colormap,
429 GdkColormapPrivateX11 *private;
433 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), 0);
435 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
437 return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
438 contiguous, planes, nplanes, pixels, npixels);
442 for (i=0; i<npixels; i++)
444 private->info[pixels[i]].ref_count++;
445 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
449 return return_val != 0;
453 gdk_color_parse (const gchar *spec,
460 g_return_val_if_fail (spec != NULL, FALSE);
461 g_return_val_if_fail (color != NULL, FALSE);
463 xcolormap = DefaultColormap (gdk_display, gdk_screen);
465 if (XParseColor (gdk_display, xcolormap, spec, &xcolor))
468 color->red = xcolor.red;
469 color->green = xcolor.green;
470 color->blue = xcolor.blue;
478 /* This is almost identical to gdk_colormap_free_colors.
482 gdk_colors_free (GdkColormap *colormap,
487 GdkColormapPrivateX11 *private;
492 g_return_if_fail (GDK_IS_COLORMAP (colormap));
493 g_return_if_fail (in_pixels != NULL);
495 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
497 if ((colormap->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
498 (colormap->visual->type != GDK_VISUAL_GRAYSCALE))
501 pixels = g_new (gulong, in_npixels);
503 for (i=0; i<in_npixels; i++)
505 gulong pixel = in_pixels[i];
507 if (private->info[pixel].ref_count)
509 private->info[pixel].ref_count--;
511 if (private->info[pixel].ref_count == 0)
513 pixels[npixels++] = pixel;
514 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
515 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
516 private->info[pixel].flags = 0;
522 XFreeColors (private->xdisplay, private->xcolormap,
523 pixels, npixels, planes);
527 /* This is almost identical to gdk_colors_free.
531 gdk_colormap_free_colors (GdkColormap *colormap,
535 GdkColormapPrivateX11 *private;
540 g_return_if_fail (GDK_IS_COLORMAP (colormap));
541 g_return_if_fail (colors != NULL);
543 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
545 if ((colormap->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
546 (colormap->visual->type != GDK_VISUAL_GRAYSCALE))
549 pixels = g_new (gulong, ncolors);
551 for (i=0; i<ncolors; i++)
553 gulong pixel = colors[i].pixel;
555 if (private->info[pixel].ref_count)
557 private->info[pixel].ref_count--;
559 if (private->info[pixel].ref_count == 0)
561 pixels[npixels++] = pixel;
562 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
563 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
564 private->info[pixel].flags = 0;
570 XFreeColors (private->xdisplay, private->xcolormap,
576 /********************
578 ********************/
580 /* Try to allocate a single color using XAllocColor. If it succeeds,
581 * cache the result in our colormap, and store in ret.
584 gdk_colormap_alloc1 (GdkColormap *colormap,
588 GdkColormapPrivateX11 *private;
591 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
593 xcolor.red = color->red;
594 xcolor.green = color->green;
595 xcolor.blue = color->blue;
596 xcolor.pixel = color->pixel;
597 xcolor.flags = DoRed | DoGreen | DoBlue;
599 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
601 ret->pixel = xcolor.pixel;
602 ret->red = xcolor.red;
603 ret->green = xcolor.green;
604 ret->blue = xcolor.blue;
606 if (ret->pixel < colormap->size)
608 if (private->info[ret->pixel].ref_count) /* got a duplicate */
610 XFreeColors (private->xdisplay, private->xcolormap,
615 colormap->colors[ret->pixel] = *color;
616 colormap->colors[ret->pixel].pixel = ret->pixel;
617 private->info[ret->pixel].ref_count = 1;
619 g_hash_table_insert (private->hash,
620 &colormap->colors[ret->pixel],
621 &colormap->colors[ret->pixel]);
633 gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
640 GdkColormapPrivateX11 *private;
645 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
647 if (private->private_val)
650 for (i=0; i<ncolors; i++)
652 while ((index < colormap->size) && (private->info[index].ref_count != 0))
655 if (index < colormap->size)
657 colors[i].pixel = index;
659 private->info[index].ref_count++;
660 private->info[i].flags |= GDK_COLOR_WRITEABLE;
669 pixels = g_new (gulong, ncolors);
670 /* Allocation of a writeable color cells */
672 status = XAllocColorCells (private->xdisplay, private->xcolormap,
673 FALSE, NULL, 0, pixels, ncolors);
676 for (i=0; i<ncolors; i++)
678 colors[i].pixel = pixels[i];
679 private->info[pixels[i]].ref_count++;
680 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
686 return status ? ncolors : 0;
691 gdk_colormap_alloc_colors_private (GdkColormap *colormap,
698 GdkColormapPrivateX11 *private;
700 XColor *store = g_new (XColor, ncolors);
704 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
707 /* First, store the colors we have room for */
710 for (i=0; i<ncolors; i++)
714 while ((index < colormap->size) && (private->info[index].ref_count != 0))
717 if (index < colormap->size)
719 store[nstore].red = colors[i].red;
720 store[nstore].blue = colors[i].blue;
721 store[nstore].green = colors[i].green;
722 store[nstore].pixel = index;
727 colors[i].pixel = index;
728 private->info[index].ref_count++;
735 XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
738 if (nremaining > 0 && best_match)
740 /* Get best matches for remaining colors */
742 gchar *available = g_new (gchar, colormap->size);
743 for (i = 0; i < colormap->size; i++)
746 for (i=0; i<ncolors; i++)
750 index = gdk_colormap_match_color (colormap,
755 colors[i] = colormap->colors[index];
756 private->info[index].ref_count++;
766 return (ncolors - nremaining);
770 gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
777 GdkColormapPrivateX11 *private;
782 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
785 for (i=0; i<ncolors; i++)
789 if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
797 if (nremaining > 0 && best_match)
799 gchar *available = g_new (gchar, colormap->size);
800 for (i = 0; i < colormap->size; i++)
801 available[i] = ((private->info[i].ref_count == 0) ||
802 !(private->info[i].flags && GDK_COLOR_WRITEABLE));
803 gdk_colormap_sync (colormap, FALSE);
805 while (nremaining > 0)
807 for (i=0; i<ncolors; i++)
811 index = gdk_colormap_match_color (colormap, &colors[i], available);
814 if (private->info[index].ref_count)
816 private->info[index].ref_count++;
817 colors[i] = colormap->colors[index];
823 if (gdk_colormap_alloc1 (colormap,
824 &colormap->colors[index],
833 available[index] = FALSE;
841 success[i] = 2; /* flag as permanent failure */
849 /* Change back the values we flagged as permanent failures */
852 for (i=0; i<ncolors; i++)
855 nremaining = nfailed;
858 return (ncolors - nremaining);
862 gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
869 GdkColormapPrivateX11 *private;
870 GdkColor *lookup_color;
874 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
876 /* Check for an exact match among previously allocated colors */
878 for (i=0; i<ncolors; i++)
882 lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
885 private->info[lookup_color->pixel].ref_count++;
886 colors[i].pixel = lookup_color->pixel;
894 /* If that failed, we try to allocate a new color, or approxmiate
895 * with what we can get if best_match is TRUE.
899 if (private->private_val)
900 return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
902 return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
909 gdk_colormap_alloc_colors (GdkColormap *colormap,
916 GdkColormapPrivateX11 *private;
922 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), FALSE);
923 g_return_val_if_fail (colors != NULL, FALSE);
925 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
927 for (i=0; i<ncolors; i++)
932 switch (colormap->visual->type)
934 case GDK_VISUAL_PSEUDO_COLOR:
935 case GDK_VISUAL_GRAYSCALE:
937 return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
938 writeable, best_match, success);
940 return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
941 writeable, best_match, success);
944 case GDK_VISUAL_DIRECT_COLOR:
945 case GDK_VISUAL_TRUE_COLOR:
946 visual = colormap->visual;
948 for (i=0; i<ncolors; i++)
950 colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
951 ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
952 ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
957 case GDK_VISUAL_STATIC_GRAY:
958 case GDK_VISUAL_STATIC_COLOR:
959 for (i=0; i<ncolors; i++)
961 xcolor.red = colors[i].red;
962 xcolor.green = colors[i].green;
963 xcolor.blue = colors[i].blue;
964 xcolor.pixel = colors[i].pixel;
965 xcolor.flags = DoRed | DoGreen | DoBlue;
967 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
969 colors[i].pixel = xcolor.pixel;
981 gdk_colormap_query_color (GdkColormap *colormap,
988 g_return_if_fail (GDK_IS_COLORMAP (colormap));
990 visual = gdk_colormap_get_visual (colormap);
992 switch (visual->type) {
993 case GDK_VISUAL_DIRECT_COLOR:
994 case GDK_VISUAL_TRUE_COLOR:
995 result->red = 65535. * (double)((pixel & visual->red_mask) >> visual->red_shift) / ((1 << visual->red_prec) - 1);
996 result->green = 65535. * (double)((pixel & visual->green_mask) >> visual->green_shift) / ((1 << visual->green_prec) - 1);
997 result->blue = 65535. * (double)((pixel & visual->blue_mask) >> visual->blue_shift) / ((1 << visual->blue_prec) - 1);
999 case GDK_VISUAL_STATIC_GRAY:
1000 case GDK_VISUAL_GRAYSCALE:
1001 result->red = result->green = result->blue = 65535. * (double)pixel/((1<<visual->depth) - 1);
1003 case GDK_VISUAL_STATIC_COLOR:
1004 xcolor.pixel = pixel;
1005 XQueryColor (GDK_DISPLAY (), GDK_COLORMAP_XCOLORMAP (colormap), &xcolor);
1006 result->red = xcolor.red;
1007 result->green = xcolor.green;
1008 result->blue = xcolor.blue;
1010 case GDK_VISUAL_PSEUDO_COLOR:
1011 result->red = colormap->colors[pixel].red;
1012 result->green = colormap->colors[pixel].green;
1013 result->blue = colormap->colors[pixel].blue;
1016 g_assert_not_reached ();
1022 gdk_color_change (GdkColormap *colormap,
1025 GdkColormapPrivateX11 *private;
1028 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), FALSE);
1029 g_return_val_if_fail (color != NULL, FALSE);
1031 xcolor.pixel = color->pixel;
1032 xcolor.red = color->red;
1033 xcolor.green = color->green;
1034 xcolor.blue = color->blue;
1035 xcolor.flags = DoRed | DoGreen | DoBlue;
1037 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
1038 XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
1043 /* XXX: Do not use this function until it is fixed. An X Colormap
1044 * is useless unless we also have the visual.
1047 gdkx_colormap_get (Colormap xcolormap)
1049 GdkColormap *colormap;
1050 GdkColormapPrivateX11 *private;
1052 colormap = gdk_colormap_lookup (xcolormap);
1056 if (xcolormap == DefaultColormap (gdk_display, gdk_screen))
1057 return gdk_colormap_get_system ();
1059 colormap = g_object_new (gdk_colormap_get_type (), NULL);
1060 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
1062 private->xdisplay = gdk_display;
1063 private->xcolormap = xcolormap;
1064 colormap->visual = NULL;
1065 private->private_val = TRUE;
1067 /* To do the following safely, we would have to have some way of finding
1068 * out what the size or visual of the given colormap is. It seems
1069 * X doesn't allow this
1073 for (i = 0; i < 256; i++)
1075 xpalette[i].pixel = i;
1076 xpalette[i].red = 0;
1077 xpalette[i].green = 0;
1078 xpalette[i].blue = 0;
1081 XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
1083 for (i = 0; i < 256; i++)
1085 colormap->colors[i].pixel = xpalette[i].pixel;
1086 colormap->colors[i].red = xpalette[i].red;
1087 colormap->colors[i].green = xpalette[i].green;
1088 colormap->colors[i].blue = xpalette[i].blue;
1092 colormap->colors = NULL;
1095 gdk_colormap_add (colormap);
1102 gdk_colormap_match_color (GdkColormap *cmap,
1104 const gchar *available)
1108 gint rdiff, gdiff, bdiff;
1111 g_return_val_if_fail (cmap != NULL, 0);
1112 g_return_val_if_fail (color != NULL, 0);
1114 colors = cmap->colors;
1118 for (i = 0; i < cmap->size; i++)
1120 if ((!available) || (available && available[i]))
1122 rdiff = (color->red - colors[i].red);
1123 gdiff = (color->green - colors[i].green);
1124 bdiff = (color->blue - colors[i].blue);
1126 sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
1141 gdk_colormap_lookup (Colormap xcolormap)
1148 cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
1153 gdk_colormap_add (GdkColormap *cmap)
1155 GdkColormapPrivateX11 *private;
1158 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1159 (GEqualFunc) gdk_colormap_equal);
1161 private = GDK_COLORMAP_PRIVATE_DATA (cmap);
1163 g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
1167 gdk_colormap_remove (GdkColormap *cmap)
1169 GdkColormapPrivateX11 *private;
1172 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1173 (GEqualFunc) gdk_colormap_equal);
1175 private = GDK_COLORMAP_PRIVATE_DATA (cmap);
1177 g_hash_table_remove (colormap_hash, &private->xcolormap);
1181 gdk_colormap_hash (Colormap *cmap)
1187 gdk_colormap_equal (Colormap *a,