X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gdk%2Fgdkcolor.c;h=53765f601019c87c72dd119264b03759e6dd5b71;hb=9d0febc9a64a5bfb0fcfc3a88de4757f6c1ff090;hp=3ad8df8d9d00122417c9af36e640578105a7c648;hpb=d5d01a5af9aaa11762d7ba86760796df00af3786;p=~andy%2Fgtk diff --git a/gdk/gdkcolor.c b/gdk/gdkcolor.c index 3ad8df8d9..53765f601 100644 --- a/gdk/gdkcolor.c +++ b/gdk/gdkcolor.c @@ -2,712 +2,190 @@ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. + * Lesser General Public License for more details. * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . */ -#include -#include "gdk.h" -#include "gdkprivate.h" +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ -static gint gdk_colormap_match_color (GdkColormap *cmap, - GdkColor *color, - const gchar *available); -static void gdk_colormap_add (GdkColormap *cmap); -static void gdk_colormap_remove (GdkColormap *cmap); -static guint gdk_colormap_hash (Colormap *cmap); -static gint gdk_colormap_cmp (Colormap *a, - Colormap *b); -static void gdk_colormap_real_destroy (GdkColormap *colormap); - -static GHashTable *colormap_hash = NULL; - - -GdkColormap* -gdk_colormap_new (GdkVisual *visual, - gint private_cmap) -{ - GdkColormap *colormap; - GdkColormapPrivate *private; - Visual *xvisual; - XColor default_colors[256]; - int size; - int i; - - g_return_val_if_fail (visual != NULL, NULL); - - private = g_new (GdkColormapPrivate, 1); - colormap = (GdkColormap*) private; - - private->xdisplay = gdk_display; - private->visual = visual; - private->next_color = 0; - private->ref_count = 1; - xvisual = ((GdkVisualPrivate*) visual)->xvisual; - - switch (visual->type) - { - case GDK_VISUAL_GRAYSCALE: - case GDK_VISUAL_PSEUDO_COLOR: - private->private_val = private_cmap; - private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window, - xvisual, (private_cmap) ? (AllocAll) : (AllocNone)); - - if (private_cmap) - { - for (i = 0; i < 256; i++) - default_colors[i].pixel = i; - - XQueryColors (private->xdisplay, - DefaultColormap (private->xdisplay, gdk_screen), - default_colors, visual->colormap_size); - - for (i = 0; i < visual->colormap_size; i++) - { - colormap->colors[i].pixel = default_colors[i].pixel; - colormap->colors[i].red = default_colors[i].red; - colormap->colors[i].green = default_colors[i].green; - colormap->colors[i].blue = default_colors[i].blue; - } - - gdk_colormap_change (colormap, visual->colormap_size); - } - break; - - case GDK_VISUAL_DIRECT_COLOR: - private->private_val = TRUE; - private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window, - xvisual, AllocAll); - - size = 1 << visual->red_prec; - for (i = 0; i < size; i++) - colormap->colors[i].red = i * 65535 / (size - 1); - - size = 1 << visual->green_prec; - for (i = 0; i < size; i++) - colormap->colors[i].green = i * 65535 / (size - 1); - - size = 1 << visual->blue_prec; - for (i = 0; i < size; i++) - colormap->colors[i].blue = i * 65535 / (size - 1); - - gdk_colormap_change (colormap, visual->colormap_size); - break; - - case GDK_VISUAL_STATIC_GRAY: - case GDK_VISUAL_STATIC_COLOR: - case GDK_VISUAL_TRUE_COLOR: - private->private_val = FALSE; - private->xcolormap = XCreateColormap (private->xdisplay, gdk_root_window, - xvisual, AllocNone); - break; - } - - gdk_colormap_add (colormap); - - return colormap; -} - -static void -gdk_colormap_real_destroy (GdkColormap *colormap) -{ - GdkColormapPrivate *private = (GdkColormapPrivate*) colormap; - - g_return_if_fail (colormap != NULL); - - if (private->ref_count > 0) - return; - - gdk_colormap_remove (colormap); - XFreeColormap (private->xdisplay, private->xcolormap); - g_free (colormap); -} - -GdkColormap* -gdk_colormap_ref (GdkColormap *cmap) -{ - GdkColormapPrivate *private = (GdkColormapPrivate *)cmap; - g_return_val_if_fail (cmap != NULL, NULL); - - private->ref_count += 1; - return cmap; -} - -void -gdk_colormap_unref (GdkColormap *cmap) -{ - GdkColormapPrivate *private = (GdkColormapPrivate *)cmap; - g_return_if_fail (cmap != NULL); - - private->ref_count -= 1; - if (private->ref_count == 0) - gdk_colormap_real_destroy (cmap); -} - -GdkColormap* -gdk_colormap_get_system (void) -{ - static GdkColormap *colormap = NULL; - GdkColormapPrivate *private; - XColor xpalette[256]; - gint i; - - if (!colormap) - { - private = g_new (GdkColormapPrivate, 1); - colormap = (GdkColormap*) private; - - private->xdisplay = gdk_display; - private->xcolormap = DefaultColormap (gdk_display, gdk_screen); - private->visual = gdk_visual_get_system (); - private->private_val = FALSE; - private->next_color = 0; - private->ref_count = 1; - - for (i = 0; i < 256; i++) - { - xpalette[i].pixel = i; - xpalette[i].red = 0; - xpalette[i].green = 0; - xpalette[i].blue = 0; - } - - XQueryColors (gdk_display, private->xcolormap, xpalette, 256); - - for (i = 0; i < 256; i++) - { - colormap->colors[i].pixel = xpalette[i].pixel; - colormap->colors[i].red = xpalette[i].red; - colormap->colors[i].green = xpalette[i].green; - colormap->colors[i].blue = xpalette[i].blue; - } - - gdk_colormap_add (colormap); - } - - return colormap; -} - -gint -gdk_colormap_get_system_size (void) -{ - return DisplayCells (gdk_display, gdk_screen); -} - -void -gdk_colormap_change (GdkColormap *colormap, - gint ncolors) -{ - GdkColormapPrivate *private; - GdkVisual *visual; - XColor palette[256]; - gint shift; - int max_colors; - int size; - int i; - - g_return_if_fail (colormap != NULL); - - private = (GdkColormapPrivate*) colormap; - switch (private->visual->type) - { - case GDK_VISUAL_GRAYSCALE: - case GDK_VISUAL_PSEUDO_COLOR: - for (i = 0; i < ncolors; i++) - { - palette[i].pixel = colormap->colors[i].pixel; - palette[i].red = colormap->colors[i].red; - palette[i].green = colormap->colors[i].green; - palette[i].blue = colormap->colors[i].blue; - palette[i].flags = DoRed | DoGreen | DoBlue; - } - - XStoreColors (private->xdisplay, private->xcolormap, palette, ncolors); - private->next_color = MAX (private->next_color, ncolors); - break; - - case GDK_VISUAL_DIRECT_COLOR: - visual = private->visual; - - shift = visual->red_shift; - max_colors = 1 << visual->red_prec; - size = (ncolors < max_colors) ? (ncolors) : (max_colors); - - for (i = 0; i < size; i++) - { - palette[i].pixel = i << shift; - palette[i].red = colormap->colors[i].red; - palette[i].flags = DoRed; - } - - XStoreColors (private->xdisplay, private->xcolormap, palette, size); - - shift = visual->green_shift; - max_colors = 1 << visual->green_prec; - size = (ncolors < max_colors) ? (ncolors) : (max_colors); - - for (i = 0; i < size; i++) - { - palette[i].pixel = i << shift; - palette[i].green = colormap->colors[i].green; - palette[i].flags = DoGreen; - } - - XStoreColors (private->xdisplay, private->xcolormap, palette, size); - - shift = visual->blue_shift; - max_colors = 1 << visual->blue_prec; - size = (ncolors < max_colors) ? (ncolors) : (max_colors); - - for (i = 0; i < size; i++) - { - palette[i].pixel = i << shift; - palette[i].blue = colormap->colors[i].blue; - palette[i].flags = DoBlue; - } +#include "config.h" - XStoreColors (private->xdisplay, private->xcolormap, palette, size); - break; +#include "gdkcolor.h" - default: - break; - } -} +#include "gdkscreen.h" +#include "gdkinternals.h" -void -gdk_colors_store (GdkColormap *colormap, - GdkColor *colors, - gint ncolors) -{ - gint i; +#include - for (i = 0; i < ncolors; i++) - { - colormap->colors[i].pixel = colors[i].pixel; - colormap->colors[i].red = colors[i].red; - colormap->colors[i].green = colors[i].green; - colormap->colors[i].blue = colors[i].blue; - } +/** + * SECTION:colors + * @Short_description: Manipulation of colors + * @Title: Colors + * + * A #GdkColor represents a color. + * + * When working with cairo, it is often more convenient + * to use a #GdkRGBA instead. + */ - gdk_colormap_change (colormap, ncolors); -} -gint -gdk_colors_alloc (GdkColormap *colormap, - gint contiguous, - gulong *planes, - gint nplanes, - gulong *pixels, - gint npixels) +/** + * gdk_color_copy: + * @color: a #GdkColor + * + * Makes a copy of a color structure. + * + * The result must be freed using gdk_color_free(). + * + * Return value: a copy of @color + */ +GdkColor* +gdk_color_copy (const GdkColor *color) { - GdkColormapPrivate *private; - gint return_val; + GdkColor *new_color; - g_return_val_if_fail (colormap != NULL, 0); + g_return_val_if_fail (color != NULL, NULL); - private = (GdkColormapPrivate*) colormap; - - return_val = XAllocColorCells (private->xdisplay, private->xcolormap, - contiguous, planes, nplanes, pixels, npixels); - - return return_val; + new_color = g_slice_new (GdkColor); + *new_color = *color; + return new_color; } +/** + * gdk_color_free: + * @color: a #GdkColor + * + * Frees a color structure created with gdk_color_copy(). + */ void -gdk_colors_free (GdkColormap *colormap, - gulong *pixels, - gint npixels, - gulong planes) -{ - GdkColormapPrivate *private; - - g_return_if_fail (colormap != NULL); - - private = (GdkColormapPrivate*) colormap; - - XFreeColors (private->xdisplay, private->xcolormap, - pixels, npixels, planes); -} - -gint -gdk_color_white (GdkColormap *colormap, - GdkColor *color) -{ - gint return_val; - - g_return_val_if_fail (colormap != NULL, FALSE); - - if (color) - { - color->pixel = WhitePixel (gdk_display, gdk_screen); - color->red = 65535; - color->green = 65535; - color->blue = 65535; - - return_val = gdk_color_alloc (colormap, color); - } - else - return_val = FALSE; - - return return_val; -} - -gint -gdk_color_black (GdkColormap *colormap, - GdkColor *color) -{ - gint return_val; - - g_return_val_if_fail (colormap != NULL, FALSE); - - if (color) - { - color->pixel = BlackPixel (gdk_display, gdk_screen); - color->red = 0; - color->green = 0; - color->blue = 0; - - return_val = gdk_color_alloc (colormap, color); - } - else - return_val = FALSE; - - return return_val; -} - -gint -gdk_color_parse (const gchar *spec, - GdkColor *color) -{ - Colormap xcolormap; - XColor xcolor; - gint return_val; - - g_return_val_if_fail (spec != NULL, FALSE); - g_return_val_if_fail (color != NULL, FALSE); - - xcolormap = DefaultColormap (gdk_display, gdk_screen); - - if (XParseColor (gdk_display, xcolormap, spec, &xcolor)) - { - return_val = TRUE; - color->red = xcolor.red; - color->green = xcolor.green; - color->blue = xcolor.blue; - } - else - return_val = FALSE; - - return return_val; -} - -gint -gdk_color_alloc (GdkColormap *colormap, - GdkColor *color) +gdk_color_free (GdkColor *color) { - GdkColormapPrivate *private; - GdkVisual *visual; - XColor xcolor; - gchar available[256]; - gint available_init; - gint return_val; - gint i, index; - - g_return_val_if_fail (colormap != NULL, FALSE); - g_return_val_if_fail (color != NULL, FALSE); - - xcolor.red = color->red; - xcolor.green = color->green; - xcolor.blue = color->blue; - xcolor.pixel = color->pixel; - xcolor.flags = DoRed | DoGreen | DoBlue; - - return_val = FALSE; - private = (GdkColormapPrivate*) colormap; - - switch (private->visual->type) - { - case GDK_VISUAL_GRAYSCALE: - case GDK_VISUAL_PSEUDO_COLOR: - if (private->private_val) - { - if (private->next_color > 255) - { - for (i = 0; i < 256; i++) - available[i] = TRUE; - - index = gdk_colormap_match_color (colormap, color, available); - if (index != -1) - { - available[index] = FALSE; - *color = colormap->colors[index]; - return_val = TRUE; - } - else - { - return_val = FALSE; - } - } - else - { - xcolor.pixel = 255 - private->next_color; - color->pixel = xcolor.pixel; - private->next_color += 1; - - XStoreColor (private->xdisplay, private->xcolormap, &xcolor); - return_val = TRUE; - } - } - else - { - available_init = 1; - - while (1) - { - if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor)) - { - color->pixel = xcolor.pixel; - color->red = xcolor.red; - color->green = xcolor.green; - color->blue = xcolor.blue; - - colormap->colors[color->pixel] = *color; - - return_val = TRUE; - break; - } - else - { - if (available_init) - { - available_init = 0; - for (i = 0; i < 256; i++) - available[i] = TRUE; - } - - index = gdk_colormap_match_color (colormap, color, available); - if (index != -1) - { - available[index] = FALSE; - xcolor.red = colormap->colors[index].red; - xcolor.green = colormap->colors[index].green; - xcolor.blue = colormap->colors[index].blue; - } - else - { - return_val = FALSE; - break; - } - } - } - } - break; - - case GDK_VISUAL_DIRECT_COLOR: - visual = private->visual; - xcolor.pixel = (((xcolor.red >> (16 - visual->red_prec)) << visual->red_shift) + - ((xcolor.green >> (16 - visual->green_prec)) << visual->green_shift) + - ((xcolor.blue >> (16 - visual->blue_prec)) << visual->blue_shift)); - color->pixel = xcolor.pixel; - return_val = TRUE; - break; + g_return_if_fail (color != NULL); - case GDK_VISUAL_STATIC_GRAY: - case GDK_VISUAL_STATIC_COLOR: - case GDK_VISUAL_TRUE_COLOR: - if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor)) - { - color->pixel = xcolor.pixel; - return_val = TRUE; - } - else - return_val = FALSE; - break; - } - - return return_val; + g_slice_free (GdkColor, color); } -gint -gdk_color_change (GdkColormap *colormap, - GdkColor *color) +/** + * gdk_color_hash: + * @color: a #GdkColor + * + * A hash function suitable for using for a hash + * table that stores #GdkColors. + * + * Return value: The hash function applied to @color + */ +guint +gdk_color_hash (const GdkColor *color) { - GdkColormapPrivate *private; - XColor xcolor; - - g_return_val_if_fail (colormap != NULL, FALSE); - g_return_val_if_fail (color != NULL, FALSE); - - xcolor.pixel = color->pixel; - xcolor.red = color->red; - xcolor.green = color->green; - xcolor.blue = color->blue; - xcolor.flags = DoRed | DoGreen | DoBlue; - - private = (GdkColormapPrivate*) colormap; - XStoreColor (private->xdisplay, private->xcolormap, &xcolor); - - return TRUE; + return ((color->red) + + (color->green << 11) + + (color->blue << 22) + + (color->blue >> 6)); } -gint -gdk_color_equal (GdkColor *colora, - GdkColor *colorb) +/** + * gdk_color_equal: + * @colora: a #GdkColor + * @colorb: another #GdkColor + * + * Compares two colors. + * + * Return value: %TRUE if the two colors compare equal + */ +gboolean +gdk_color_equal (const GdkColor *colora, + const GdkColor *colorb) { g_return_val_if_fail (colora != NULL, FALSE); g_return_val_if_fail (colorb != NULL, FALSE); return ((colora->red == colorb->red) && - (colora->green == colorb->green) && - (colora->blue == colorb->blue)); + (colora->green == colorb->green) && + (colora->blue == colorb->blue)); } -GdkColormap* -gdkx_colormap_get (Colormap xcolormap) -{ - GdkColormap *colormap; - GdkColormapPrivate *private; - XColor xpalette[256]; - gint i; - - colormap = gdk_colormap_lookup (xcolormap); - if (colormap) - return colormap; - - if (xcolormap == DefaultColormap (gdk_display, gdk_screen)) - return gdk_colormap_get_system (); - - private = g_new (GdkColormapPrivate, 1); - colormap = (GdkColormap*) private; - - private->xdisplay = gdk_display; - private->xcolormap = xcolormap; - private->visual = NULL; - private->private_val = TRUE; - private->next_color = 0; - - for (i = 0; i < 256; i++) - { - xpalette[i].pixel = i; - xpalette[i].red = 0; - xpalette[i].green = 0; - xpalette[i].blue = 0; - } - - XQueryColors (gdk_display, private->xcolormap, xpalette, 256); - - for (i = 0; i < 256; i++) - { - colormap->colors[i].pixel = xpalette[i].pixel; - colormap->colors[i].red = xpalette[i].red; - colormap->colors[i].green = xpalette[i].green; - colormap->colors[i].blue = xpalette[i].blue; - } - - gdk_colormap_add (colormap); +G_DEFINE_BOXED_TYPE (GdkColor, gdk_color, + gdk_color_copy, + gdk_color_free) - return colormap; -} - - -static gint -gdk_colormap_match_color (GdkColormap *cmap, - GdkColor *color, - const gchar *available) +/** + * gdk_color_parse: + * @spec: the string specifying the color + * @color: (out): the #GdkColor to fill in + * + * Parses a textual specification of a color and fill in the + * red, green, + * and blue fields of a #GdkColor + * structure. + * + * The string can either one of a large set of standard names + * (taken from the X11 rgb.txt file), or + * it can be a hex value in the form '#rgb' '#rrggbb' + * '#rrrgggbbb' or '#rrrrggggbbbb' where 'r', 'g' and + * 'b' are hex digits of the red, green, and blue components + * of the color, respectively. (White in the four forms is + * '#fff', '#ffffff', '#fffffffff' and + * '#ffffffffffff'). + * + * Return value: %TRUE if the parsing succeeded + */ +gboolean +gdk_color_parse (const gchar *spec, + GdkColor *color) { - GdkColor *colors; - guint sum, max; - gint rdiff, gdiff, bdiff; - gint i, index; - - g_return_val_if_fail (cmap != NULL, 0); - g_return_val_if_fail (color != NULL, 0); + PangoColor pango_color; - colors = cmap->colors; - max = 3 * (65536); - index = -1; - - for (i = 0; i < 256; i++) + if (pango_color_parse (&pango_color, spec)) { - if ((!available) || (available && available[i])) - { - rdiff = (color->red - colors[i].red); - gdiff = (color->green - colors[i].green); - bdiff = (color->blue - colors[i].blue); - - sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff); + color->red = pango_color.red; + color->green = pango_color.green; + color->blue = pango_color.blue; - if (sum < max) - { - index = i; - max = sum; - } - } + return TRUE; } - - return index; -} - - -GdkColormap* -gdk_colormap_lookup (Colormap xcolormap) -{ - GdkColormap *cmap; - - if (!colormap_hash) - return NULL; - - cmap = g_hash_table_lookup (colormap_hash, &xcolormap); - return cmap; -} - -static void -gdk_colormap_add (GdkColormap *cmap) -{ - GdkColormapPrivate *private; - - if (!colormap_hash) - colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash, - (GCompareFunc) gdk_colormap_cmp); - - private = (GdkColormapPrivate*) cmap; - - g_hash_table_insert (colormap_hash, &private->xcolormap, cmap); + else + return FALSE; } -static void -gdk_colormap_remove (GdkColormap *cmap) +/** + * gdk_color_to_string: + * @color: a #GdkColor + * + * Returns a textual specification of @color in the hexadecimal form + * #rrrrggggbbbb, where r, + * g and b are hex digits + * representing the red, green and blue components respectively. + * + * The returned string can be parsed by gdk_color_parse(). + * + * Return value: a newly-allocated text string + * + * Since: 2.12 + */ +gchar * +gdk_color_to_string (const GdkColor *color) { - GdkColormapPrivate *private; + PangoColor pango_color; - if (!colormap_hash) - colormap_hash = g_hash_table_new ((GHashFunc) gdk_colormap_hash, - (GCompareFunc) gdk_colormap_cmp); + g_return_val_if_fail (color != NULL, NULL); - private = (GdkColormapPrivate*) cmap; + pango_color.red = color->red; + pango_color.green = color->green; + pango_color.blue = color->blue; - g_hash_table_remove (colormap_hash, &private->xcolormap); -} - -static guint -gdk_colormap_hash (Colormap *cmap) -{ - return *cmap; -} - -static gint -gdk_colormap_cmp (Colormap *a, - Colormap *b) -{ - return (*a == *b); + return pango_color_to_string (&pango_color); }