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 "gdkinternals.h"
31 #include "gdkprivate-x11.h"
33 typedef struct _GdkColormapPrivateX11 GdkColormapPrivateX11;
35 struct _GdkColormapPrivateX11
43 time_t last_sync_time;
46 #define GDK_COLORMAP_PRIVATE_DATA(cmap) ((GdkColormapPrivateX11 *) GDK_COLORMAP (cmap)->windowing_data)
48 static gint gdk_colormap_match_color (GdkColormap *cmap,
50 const gchar *available);
51 static void gdk_colormap_add (GdkColormap *cmap);
52 static void gdk_colormap_remove (GdkColormap *cmap);
53 static guint gdk_colormap_hash (Colormap *cmap);
54 static gboolean gdk_colormap_equal (Colormap *a,
56 static void gdk_colormap_sync (GdkColormap *colormap,
59 static void gdk_colormap_init (GdkColormap *colormap);
60 static void gdk_colormap_class_init (GdkColormapClass *klass);
61 static void gdk_colormap_finalize (GObject *object);
63 static gpointer parent_class = NULL;
65 static GHashTable *colormap_hash = NULL;
68 gdk_colormap_get_type (void)
70 static GType object_type = 0;
74 static const GTypeInfo object_info =
76 sizeof (GdkColormapClass),
78 (GBaseFinalizeFunc) NULL,
79 (GClassInitFunc) gdk_colormap_class_init,
80 NULL, /* class_finalize */
81 NULL, /* class_data */
84 (GInstanceInitFunc) gdk_colormap_init,
87 object_type = g_type_register_static (G_TYPE_OBJECT,
96 gdk_colormap_init (GdkColormap *colormap)
98 GdkColormapPrivateX11 *private;
100 private = g_new (GdkColormapPrivateX11, 1);
102 colormap->windowing_data = private;
104 private->xdisplay = gdk_display;
105 private->hash = NULL;
106 private->last_sync_time = 0;
107 private->info = NULL;
110 colormap->colors = NULL;
114 gdk_colormap_class_init (GdkColormapClass *klass)
116 GObjectClass *object_class = G_OBJECT_CLASS (klass);
118 parent_class = g_type_class_peek_parent (klass);
120 object_class->finalize = gdk_colormap_finalize;
124 gdk_colormap_finalize (GObject *object)
126 GdkColormap *colormap = GDK_COLORMAP (object);
127 GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap);
129 gdk_colormap_remove (colormap);
131 XFreeColormap (private->xdisplay, private->xcolormap);
134 g_hash_table_destroy (private->hash);
136 g_free (private->info);
137 g_free (colormap->colors);
139 G_OBJECT_CLASS (parent_class)->finalize (object);
143 gdk_colormap_new (GdkVisual *visual,
144 gboolean private_cmap)
146 GdkColormap *colormap;
147 GdkColormapPrivateX11 *private;
152 /* FIXME when object properties settle down, there needs to be some
153 * kind of default construction (and construct-only arguments)
156 g_return_val_if_fail (visual != NULL, NULL);
158 colormap = g_object_new (gdk_colormap_get_type (), NULL);
159 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
161 colormap->visual = visual;
163 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
165 colormap->size = visual->colormap_size;
167 switch (visual->type)
169 case GDK_VISUAL_GRAYSCALE:
170 case GDK_VISUAL_PSEUDO_COLOR:
171 private->info = g_new0 (GdkColorInfo, colormap->size);
172 colormap->colors = g_new (GdkColor, colormap->size);
174 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
175 (GEqualFunc) gdk_color_equal);
177 private->private_val = private_cmap;
178 private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
179 xvisual, (private_cmap) ? (AllocAll) : (AllocNone));
183 XColor *default_colors;
185 default_colors = g_new (XColor, colormap->size);
187 for (i = 0; i < colormap->size; i++)
188 default_colors[i].pixel = i;
190 XQueryColors (private->xdisplay,
191 DefaultColormap (private->xdisplay, _gdk_screen),
192 default_colors, colormap->size);
194 for (i = 0; i < colormap->size; i++)
196 colormap->colors[i].pixel = default_colors[i].pixel;
197 colormap->colors[i].red = default_colors[i].red;
198 colormap->colors[i].green = default_colors[i].green;
199 colormap->colors[i].blue = default_colors[i].blue;
202 gdk_colormap_change (colormap, colormap->size);
204 g_free (default_colors);
208 case GDK_VISUAL_DIRECT_COLOR:
209 private->private_val = TRUE;
210 private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
212 colormap->colors = g_new (GdkColor, colormap->size);
214 size = 1 << visual->red_prec;
215 for (i = 0; i < size; i++)
216 colormap->colors[i].red = i * 65535 / (size - 1);
218 size = 1 << visual->green_prec;
219 for (i = 0; i < size; i++)
220 colormap->colors[i].green = i * 65535 / (size - 1);
222 size = 1 << visual->blue_prec;
223 for (i = 0; i < size; i++)
224 colormap->colors[i].blue = i * 65535 / (size - 1);
226 gdk_colormap_change (colormap, colormap->size);
229 case GDK_VISUAL_STATIC_GRAY:
230 case GDK_VISUAL_STATIC_COLOR:
231 private->private_val = FALSE;
232 private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
235 colormap->colors = g_new (GdkColor, colormap->size);
236 gdk_colormap_sync (colormap, TRUE);
239 case GDK_VISUAL_TRUE_COLOR:
240 private->private_val = FALSE;
241 private->xcolormap = XCreateColormap (private->xdisplay, _gdk_root_window,
246 gdk_colormap_add (colormap);
251 #define MIN_SYNC_TIME 2
254 gdk_colormap_sync (GdkColormap *colormap,
258 GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap);
263 g_return_if_fail (GDK_IS_COLORMAP (colormap));
265 current_time = time (NULL);
266 if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME))
269 private->last_sync_time = current_time;
272 xpalette = g_new (XColor, colormap->size);
274 for (i = 0; i < colormap->size; i++)
276 if (!private->info || private->info[i].ref_count == 0)
278 xpalette[nlookup].pixel = i;
279 xpalette[nlookup].red = 0;
280 xpalette[nlookup].green = 0;
281 xpalette[nlookup].blue = 0;
286 XQueryColors (gdk_display, private->xcolormap, xpalette, nlookup);
288 for (i = 0; i < nlookup; i++)
290 gulong pixel = xpalette[i].pixel;
291 colormap->colors[pixel].pixel = pixel;
292 colormap->colors[pixel].red = xpalette[i].red;
293 colormap->colors[pixel].green = xpalette[i].green;
294 colormap->colors[pixel].blue = xpalette[i].blue;
302 gdk_colormap_get_system (void)
304 static GdkColormap *colormap = NULL;
305 GdkColormapPrivateX11 *private;
309 colormap = g_object_new (gdk_colormap_get_type (), NULL);
310 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
312 private->xdisplay = gdk_display;
313 private->xcolormap = DefaultColormap (gdk_display, _gdk_screen);
314 colormap->visual = gdk_visual_get_system ();
315 private->private_val = FALSE;
317 private->hash = NULL;
318 private->last_sync_time = 0;
319 private->info = NULL;
321 colormap->colors = NULL;
322 colormap->size = colormap->visual->colormap_size;
324 switch (colormap->visual->type)
326 case GDK_VISUAL_GRAYSCALE:
327 case GDK_VISUAL_PSEUDO_COLOR:
328 private->info = g_new0 (GdkColorInfo, colormap->size);
329 private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
330 (GEqualFunc) gdk_color_equal);
332 case GDK_VISUAL_STATIC_GRAY:
333 case GDK_VISUAL_STATIC_COLOR:
334 colormap->colors = g_new (GdkColor, colormap->size);
335 gdk_colormap_sync (colormap, TRUE);
337 case GDK_VISUAL_DIRECT_COLOR:
338 case GDK_VISUAL_TRUE_COLOR:
342 gdk_colormap_add (colormap);
349 gdk_colormap_get_system_size (void)
351 return DisplayCells (gdk_display, _gdk_screen);
355 gdk_colormap_change (GdkColormap *colormap,
358 GdkColormapPrivateX11 *private;
366 g_return_if_fail (GDK_IS_COLORMAP (colormap));
368 palette = g_new (XColor, ncolors);
370 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
371 switch (colormap->visual->type)
373 case GDK_VISUAL_GRAYSCALE:
374 case GDK_VISUAL_PSEUDO_COLOR:
375 for (i = 0; i < ncolors; i++)
377 palette[i].pixel = colormap->colors[i].pixel;
378 palette[i].red = colormap->colors[i].red;
379 palette[i].green = colormap->colors[i].green;
380 palette[i].blue = colormap->colors[i].blue;
381 palette[i].flags = DoRed | DoGreen | DoBlue;
384 XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors);
387 case GDK_VISUAL_DIRECT_COLOR:
388 visual = colormap->visual;
390 shift = visual->red_shift;
391 max_colors = 1 << visual->red_prec;
392 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
394 for (i = 0; i < size; i++)
396 palette[i].pixel = i << shift;
397 palette[i].red = colormap->colors[i].red;
398 palette[i].flags = DoRed;
401 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
403 shift = visual->green_shift;
404 max_colors = 1 << visual->green_prec;
405 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
407 for (i = 0; i < size; i++)
409 palette[i].pixel = i << shift;
410 palette[i].green = colormap->colors[i].green;
411 palette[i].flags = DoGreen;
414 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
416 shift = visual->blue_shift;
417 max_colors = 1 << visual->blue_prec;
418 size = (ncolors < max_colors) ? (ncolors) : (max_colors);
420 for (i = 0; i < size; i++)
422 palette[i].pixel = i << shift;
423 palette[i].blue = colormap->colors[i].blue;
424 palette[i].flags = DoBlue;
427 XStoreColors (private->xdisplay, private->xcolormap, palette, size);
438 gdk_colors_alloc (GdkColormap *colormap,
445 GdkColormapPrivateX11 *private;
449 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), 0);
451 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
453 return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
454 contiguous, planes, nplanes, pixels, npixels);
458 for (i=0; i<npixels; i++)
460 private->info[pixels[i]].ref_count++;
461 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
465 return return_val != 0;
468 /* This is almost identical to gdk_colormap_free_colors.
472 gdk_colors_free (GdkColormap *colormap,
477 GdkColormapPrivateX11 *private;
482 g_return_if_fail (GDK_IS_COLORMAP (colormap));
483 g_return_if_fail (in_pixels != NULL);
485 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
487 if ((colormap->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
488 (colormap->visual->type != GDK_VISUAL_GRAYSCALE))
491 pixels = g_new (gulong, in_npixels);
493 for (i=0; i<in_npixels; i++)
495 gulong pixel = in_pixels[i];
497 if (private->info[pixel].ref_count)
499 private->info[pixel].ref_count--;
501 if (private->info[pixel].ref_count == 0)
503 pixels[npixels++] = pixel;
504 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
505 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
506 private->info[pixel].flags = 0;
512 XFreeColors (private->xdisplay, private->xcolormap,
513 pixels, npixels, planes);
517 /* This is almost identical to gdk_colors_free.
521 gdk_colormap_free_colors (GdkColormap *colormap,
525 GdkColormapPrivateX11 *private;
530 g_return_if_fail (GDK_IS_COLORMAP (colormap));
531 g_return_if_fail (colors != NULL);
533 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
535 if ((colormap->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
536 (colormap->visual->type != GDK_VISUAL_GRAYSCALE))
539 pixels = g_new (gulong, ncolors);
541 for (i=0; i<ncolors; i++)
543 gulong pixel = colors[i].pixel;
545 if (private->info[pixel].ref_count)
547 private->info[pixel].ref_count--;
549 if (private->info[pixel].ref_count == 0)
551 pixels[npixels++] = pixel;
552 if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
553 g_hash_table_remove (private->hash, &colormap->colors[pixel]);
554 private->info[pixel].flags = 0;
560 XFreeColors (private->xdisplay, private->xcolormap,
566 /********************
568 ********************/
570 /* Try to allocate a single color using XAllocColor. If it succeeds,
571 * cache the result in our colormap, and store in ret.
574 gdk_colormap_alloc1 (GdkColormap *colormap,
578 GdkColormapPrivateX11 *private;
581 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
583 xcolor.red = color->red;
584 xcolor.green = color->green;
585 xcolor.blue = color->blue;
586 xcolor.pixel = color->pixel;
587 xcolor.flags = DoRed | DoGreen | DoBlue;
589 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
591 ret->pixel = xcolor.pixel;
592 ret->red = xcolor.red;
593 ret->green = xcolor.green;
594 ret->blue = xcolor.blue;
596 if (ret->pixel < colormap->size)
598 if (private->info[ret->pixel].ref_count) /* got a duplicate */
600 XFreeColors (private->xdisplay, private->xcolormap,
601 &xcolor.pixel, 1, 0);
605 colormap->colors[ret->pixel] = *color;
606 colormap->colors[ret->pixel].pixel = ret->pixel;
607 private->info[ret->pixel].ref_count = 1;
609 g_hash_table_insert (private->hash,
610 &colormap->colors[ret->pixel],
611 &colormap->colors[ret->pixel]);
623 gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
630 GdkColormapPrivateX11 *private;
635 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
637 if (private->private_val)
640 for (i=0; i<ncolors; i++)
642 while ((index < colormap->size) && (private->info[index].ref_count != 0))
645 if (index < colormap->size)
647 colors[i].pixel = index;
649 private->info[index].ref_count++;
650 private->info[i].flags |= GDK_COLOR_WRITEABLE;
659 pixels = g_new (gulong, ncolors);
660 /* Allocation of a writeable color cells */
662 status = XAllocColorCells (private->xdisplay, private->xcolormap,
663 FALSE, NULL, 0, pixels, ncolors);
666 for (i=0; i<ncolors; i++)
668 colors[i].pixel = pixels[i];
669 private->info[pixels[i]].ref_count++;
670 private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
676 return status ? ncolors : 0;
681 gdk_colormap_alloc_colors_private (GdkColormap *colormap,
688 GdkColormapPrivateX11 *private;
690 XColor *store = g_new (XColor, ncolors);
694 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
697 /* First, store the colors we have room for */
700 for (i=0; i<ncolors; i++)
704 while ((index < colormap->size) && (private->info[index].ref_count != 0))
707 if (index < colormap->size)
709 store[nstore].red = colors[i].red;
710 store[nstore].blue = colors[i].blue;
711 store[nstore].green = colors[i].green;
712 store[nstore].pixel = index;
717 colors[i].pixel = index;
718 private->info[index].ref_count++;
725 XStoreColors (private->xdisplay, private->xcolormap, store, nstore);
728 if (nremaining > 0 && best_match)
730 /* Get best matches for remaining colors */
732 gchar *available = g_new (gchar, colormap->size);
733 for (i = 0; i < colormap->size; i++)
736 for (i=0; i<ncolors; i++)
740 index = gdk_colormap_match_color (colormap,
745 colors[i] = colormap->colors[index];
746 private->info[index].ref_count++;
756 return (ncolors - nremaining);
760 gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
767 GdkColormapPrivateX11 *private;
772 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
775 for (i=0; i<ncolors; i++)
779 if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
787 if (nremaining > 0 && best_match)
789 gchar *available = g_new (gchar, colormap->size);
790 for (i = 0; i < colormap->size; i++)
791 available[i] = ((private->info[i].ref_count == 0) ||
792 !(private->info[i].flags & GDK_COLOR_WRITEABLE));
793 gdk_colormap_sync (colormap, FALSE);
795 while (nremaining > 0)
797 for (i=0; i<ncolors; i++)
801 index = gdk_colormap_match_color (colormap, &colors[i], available);
804 if (private->info[index].ref_count)
806 private->info[index].ref_count++;
807 colors[i] = colormap->colors[index];
813 if (gdk_colormap_alloc1 (colormap,
814 &colormap->colors[index],
823 available[index] = FALSE;
831 success[i] = 2; /* flag as permanent failure */
839 /* Change back the values we flagged as permanent failures */
842 for (i=0; i<ncolors; i++)
845 nremaining = nfailed;
848 return (ncolors - nremaining);
852 gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
859 GdkColormapPrivateX11 *private;
860 GdkColor *lookup_color;
864 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
866 /* Check for an exact match among previously allocated colors */
868 for (i=0; i<ncolors; i++)
872 lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
875 private->info[lookup_color->pixel].ref_count++;
876 colors[i].pixel = lookup_color->pixel;
884 /* If that failed, we try to allocate a new color, or approxmiate
885 * with what we can get if best_match is TRUE.
889 if (private->private_val)
890 return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
892 return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
899 gdk_colormap_alloc_colors (GdkColormap *colormap,
906 GdkColormapPrivateX11 *private;
912 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), FALSE);
913 g_return_val_if_fail (colors != NULL, FALSE);
915 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
917 for (i=0; i<ncolors; i++)
922 switch (colormap->visual->type)
924 case GDK_VISUAL_PSEUDO_COLOR:
925 case GDK_VISUAL_GRAYSCALE:
927 return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
928 writeable, best_match, success);
930 return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
931 writeable, best_match, success);
934 case GDK_VISUAL_DIRECT_COLOR:
935 case GDK_VISUAL_TRUE_COLOR:
936 visual = colormap->visual;
938 for (i=0; i<ncolors; i++)
940 colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
941 ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
942 ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
947 case GDK_VISUAL_STATIC_GRAY:
948 case GDK_VISUAL_STATIC_COLOR:
949 for (i=0; i<ncolors; i++)
951 xcolor.red = colors[i].red;
952 xcolor.green = colors[i].green;
953 xcolor.blue = colors[i].blue;
954 xcolor.pixel = colors[i].pixel;
955 xcolor.flags = DoRed | DoGreen | DoBlue;
957 if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))
959 colors[i].pixel = xcolor.pixel;
971 * gdk_colormap_query_color:
972 * @colormap: a #GdkColormap
973 * @pixel: pixel value in hardware display format
974 * @result: #GdkColor with red, green, blue fields initialized
976 * Locates the RGB color in @colormap corresponding to the given
977 * hardware pixel @pixel. @pixel must be a valid pixel in the
978 * colormap; it's a programmer error to call this function with a
979 * pixel which is not in the colormap. Hardware pixels are normally
980 * obtained from gdk_colormap_alloc_colors(), or from a #GdkImage. (A
981 * #GdkImage contains image data in hardware format, a #GdkPixbuf
982 * contains image data in a canonical 24-bit RGB format.)
984 * This function is rarely useful, it's used for example to
985 * implement the eyedropper feature in #GtkColorSelection.
989 gdk_colormap_query_color (GdkColormap *colormap,
995 GdkColormapPrivateX11 *private;
997 g_return_if_fail (GDK_IS_COLORMAP (colormap));
999 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
1001 visual = gdk_colormap_get_visual (colormap);
1003 switch (visual->type) {
1004 case GDK_VISUAL_DIRECT_COLOR:
1005 case GDK_VISUAL_TRUE_COLOR:
1006 result->red = 65535. * (double)((pixel & visual->red_mask) >> visual->red_shift) / ((1 << visual->red_prec) - 1);
1007 result->green = 65535. * (double)((pixel & visual->green_mask) >> visual->green_shift) / ((1 << visual->green_prec) - 1);
1008 result->blue = 65535. * (double)((pixel & visual->blue_mask) >> visual->blue_shift) / ((1 << visual->blue_prec) - 1);
1010 case GDK_VISUAL_STATIC_GRAY:
1011 case GDK_VISUAL_GRAYSCALE:
1012 result->red = result->green = result->blue = 65535. * (double)pixel/((1<<visual->depth) - 1);
1014 case GDK_VISUAL_STATIC_COLOR:
1015 xcolor.pixel = pixel;
1016 XQueryColor (private->xdisplay, private->xcolormap, &xcolor);
1017 result->red = xcolor.red;
1018 result->green = xcolor.green;
1019 result->blue = xcolor.blue;
1021 case GDK_VISUAL_PSEUDO_COLOR:
1022 g_return_if_fail (pixel < colormap->size);
1023 result->red = colormap->colors[pixel].red;
1024 result->green = colormap->colors[pixel].green;
1025 result->blue = colormap->colors[pixel].blue;
1028 g_assert_not_reached ();
1034 gdk_color_change (GdkColormap *colormap,
1037 GdkColormapPrivateX11 *private;
1040 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), FALSE);
1041 g_return_val_if_fail (color != NULL, FALSE);
1043 xcolor.pixel = color->pixel;
1044 xcolor.red = color->red;
1045 xcolor.green = color->green;
1046 xcolor.blue = color->blue;
1047 xcolor.flags = DoRed | DoGreen | DoBlue;
1049 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
1050 XStoreColor (private->xdisplay, private->xcolormap, &xcolor);
1055 /* XXX: Do not use this function until it is fixed. An X Colormap
1056 * is useless unless we also have the visual.
1059 gdkx_colormap_get (Colormap xcolormap)
1061 GdkColormap *colormap;
1062 GdkColormapPrivateX11 *private;
1064 colormap = gdk_colormap_lookup (xcolormap);
1068 if (xcolormap == DefaultColormap (gdk_display, _gdk_screen))
1069 return gdk_colormap_get_system ();
1071 colormap = g_object_new (gdk_colormap_get_type (), NULL);
1072 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
1074 private->xdisplay = gdk_display;
1075 private->xcolormap = xcolormap;
1076 colormap->visual = NULL;
1077 private->private_val = TRUE;
1079 /* To do the following safely, we would have to have some way of finding
1080 * out what the size or visual of the given colormap is. It seems
1081 * X doesn't allow this
1085 for (i = 0; i < 256; i++)
1087 xpalette[i].pixel = i;
1088 xpalette[i].red = 0;
1089 xpalette[i].green = 0;
1090 xpalette[i].blue = 0;
1093 XQueryColors (gdk_display, private->xcolormap, xpalette, 256);
1095 for (i = 0; i < 256; i++)
1097 colormap->colors[i].pixel = xpalette[i].pixel;
1098 colormap->colors[i].red = xpalette[i].red;
1099 colormap->colors[i].green = xpalette[i].green;
1100 colormap->colors[i].blue = xpalette[i].blue;
1104 colormap->colors = NULL;
1107 gdk_colormap_add (colormap);
1114 gdk_colormap_match_color (GdkColormap *cmap,
1116 const gchar *available)
1120 gint rdiff, gdiff, bdiff;
1123 g_return_val_if_fail (cmap != NULL, 0);
1124 g_return_val_if_fail (color != NULL, 0);
1126 colors = cmap->colors;
1130 for (i = 0; i < cmap->size; i++)
1132 if ((!available) || (available && available[i]))
1134 rdiff = (color->red - colors[i].red);
1135 gdiff = (color->green - colors[i].green);
1136 bdiff = (color->blue - colors[i].blue);
1138 sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
1153 gdk_colormap_lookup (Colormap xcolormap)
1160 cmap = g_hash_table_lookup (colormap_hash, &xcolormap);
1165 gdk_colormap_add (GdkColormap *cmap)
1167 GdkColormapPrivateX11 *private;
1170 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1171 (GEqualFunc) gdk_colormap_equal);
1173 private = GDK_COLORMAP_PRIVATE_DATA (cmap);
1175 g_hash_table_insert (colormap_hash, &private->xcolormap, cmap);
1179 gdk_colormap_remove (GdkColormap *cmap)
1181 GdkColormapPrivateX11 *private;
1184 colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash,
1185 (GEqualFunc) gdk_colormap_equal);
1187 private = GDK_COLORMAP_PRIVATE_DATA (cmap);
1189 g_hash_table_remove (colormap_hash, &private->xcolormap);
1193 gdk_colormap_hash (Colormap *cmap)
1199 gdk_colormap_equal (Colormap *a,
1206 gdk_x11_colormap_get_xdisplay (GdkColormap *colormap)
1208 GdkColormapPrivateX11 *private;
1210 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), NULL);
1212 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
1214 return private->xdisplay;
1218 gdk_x11_colormap_get_xcolormap (GdkColormap *colormap)
1220 GdkColormapPrivateX11 *private;
1222 g_return_val_if_fail (GDK_IS_COLORMAP (colormap), None);
1224 private = GDK_COLORMAP_PRIVATE_DATA (colormap);
1226 return private->xcolormap;