 1b6fb00808
			
		
	
	1b6fb00808
	
	
	
		
			
			Most of testgtk runs on 1 bpp. Nothing much else will work until gdkcc is used for gtk_preview and other color-intensive things. -Shawn
		
			
				
	
	
		
			715 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			715 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GDK - The GIMP Drawing Kit
 | |
|  * 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
 | |
|  * 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.
 | |
|  *
 | |
|  * 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.
 | |
|  */
 | |
| #include <X11/Xlib.h>
 | |
| #include "gdk.h"
 | |
| #include "gdkprivate.h"
 | |
| 
 | |
| 
 | |
| 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, 
 | |
|                     private->visual->colormap_size);
 | |
| 
 | |
|       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;
 | |
| 	}
 | |
| 
 | |
|       XStoreColors (private->xdisplay, private->xcolormap, palette, size);
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_colors_store (GdkColormap   *colormap,
 | |
| 		  GdkColor      *colors,
 | |
| 		  gint           ncolors)
 | |
| {
 | |
|   gint i;
 | |
| 
 | |
|   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;
 | |
|     }
 | |
| 
 | |
|   gdk_colormap_change (colormap, ncolors);
 | |
| }
 | |
| 
 | |
| gint
 | |
| gdk_colors_alloc (GdkColormap   *colormap,
 | |
| 		  gint           contiguous,
 | |
| 		  gulong        *planes,
 | |
| 		  gint           nplanes,
 | |
| 		  gulong        *pixels,
 | |
| 		  gint           npixels)
 | |
| {
 | |
|   GdkColormapPrivate *private;
 | |
|   gint return_val;
 | |
| 
 | |
|   g_return_val_if_fail (colormap != NULL, 0);
 | |
| 
 | |
|   private = (GdkColormapPrivate*) colormap;
 | |
| 
 | |
|   return_val = XAllocColorCells (private->xdisplay, private->xcolormap,
 | |
| 				 contiguous, planes, nplanes, pixels, npixels);
 | |
| 
 | |
|   return return_val;
 | |
| }
 | |
| 
 | |
| 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)
 | |
| {
 | |
|   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;
 | |
| 
 | |
|     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;
 | |
| }
 | |
| 
 | |
| gint
 | |
| gdk_color_change (GdkColormap *colormap,
 | |
| 		  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;
 | |
| }
 | |
| 
 | |
| gint
 | |
| gdk_color_equal (GdkColor *colora,
 | |
| 		 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));
 | |
| }
 | |
| 
 | |
| 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);
 | |
| 
 | |
|   return colormap;
 | |
| }
 | |
| 
 | |
| 
 | |
| static gint
 | |
| gdk_colormap_match_color (GdkColormap *cmap,
 | |
| 			  GdkColor    *color,
 | |
| 			  const gchar *available)
 | |
| {
 | |
|   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);
 | |
| 
 | |
|   colors = cmap->colors;
 | |
|   max = 3 * (65536);
 | |
|   index = -1;
 | |
| 
 | |
|   for (i = 0; i < 256; i++)
 | |
|     {
 | |
|       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);
 | |
| 
 | |
| 	  if (sum < max)
 | |
| 	    {
 | |
| 	      index = i;
 | |
| 	      max = sum;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   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);
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_colormap_remove (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_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);
 | |
| }
 |