Blame gdk/win32/gdkcolor-win32.c

Packit Service fb6fa5
/* GDK - The GIMP Drawing Kit
Packit Service fb6fa5
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit Service fb6fa5
 * Copyright (C) 1998-2002 Tor Lillqvist
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit Service fb6fa5
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit Service fb6fa5
 * files for a list of changes.  These files are distributed with
Packit Service fb6fa5
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include <stdio.h>
Packit Service fb6fa5
#include <stdlib.h>
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
Packit Service fb6fa5
#include "gdkcolor.h"
Packit Service fb6fa5
#include "gdkscreen.h"
Packit Service fb6fa5
#include "gdkinternals.h"
Packit Service fb6fa5
#include "gdkprivate-win32.h"
Packit Service fb6fa5
Packit Service fb6fa5
static gint     gdk_colormap_match_color (GdkColormap      *cmap,
Packit Service fb6fa5
					  GdkColor         *color,
Packit Service fb6fa5
					  const gchar      *available);
Packit Service fb6fa5
static void     gdk_colormap_init        (GdkColormap      *colormap);
Packit Service fb6fa5
static void     gdk_colormap_class_init  (GdkColormapClass *klass);
Packit Service fb6fa5
static void     gdk_colormap_finalize    (GObject          *object);
Packit Service fb6fa5
Packit Service fb6fa5
static gpointer parent_class = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
GType
Packit Service fb6fa5
gdk_colormap_get_type (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  static GType object_type = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!object_type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      const GTypeInfo object_info =
Packit Service fb6fa5
      {
Packit Service fb6fa5
        sizeof (GdkColormapClass),
Packit Service fb6fa5
        (GBaseInitFunc) NULL,
Packit Service fb6fa5
        (GBaseFinalizeFunc) NULL,
Packit Service fb6fa5
        (GClassInitFunc) gdk_colormap_class_init,
Packit Service fb6fa5
        NULL,           /* class_finalize */
Packit Service fb6fa5
        NULL,           /* class_data */
Packit Service fb6fa5
        sizeof (GdkColormap),
Packit Service fb6fa5
        0,              /* n_preallocs */
Packit Service fb6fa5
        (GInstanceInitFunc) gdk_colormap_init,
Packit Service fb6fa5
      };
Packit Service fb6fa5
      
Packit Service fb6fa5
      object_type = g_type_register_static (G_TYPE_OBJECT,
Packit Service fb6fa5
                                            "GdkColormap",
Packit Service fb6fa5
                                            &object_info, 0);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return object_type;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_colormap_init (GdkColormap *colormap)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
Packit Service fb6fa5
  private = g_new (GdkColormapPrivateWin32, 1);
Packit Service fb6fa5
Packit Service fb6fa5
  colormap->windowing_data = private;
Packit Service fb6fa5
  
Packit Service fb6fa5
  private->hpal = NULL;
Packit Service fb6fa5
  private->current_size = 0;
Packit Service fb6fa5
  private->use = NULL;
Packit Service fb6fa5
  private->hash = NULL;
Packit Service fb6fa5
  private->info = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
  colormap->size = 0;
Packit Service fb6fa5
  colormap->colors = NULL;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_colormap_class_init (GdkColormapClass *klass)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service fb6fa5
Packit Service fb6fa5
  parent_class = g_type_class_peek_parent (klass);
Packit Service fb6fa5
Packit Service fb6fa5
  object_class->finalize = gdk_colormap_finalize;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
gdk_colormap_finalize (GObject *object)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormap *colormap = GDK_COLORMAP (object);
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  GDI_CALL (DeleteObject, (private->hpal));
Packit Service fb6fa5
Packit Service fb6fa5
  if (private->hash)
Packit Service fb6fa5
    g_hash_table_destroy (private->hash);
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_free (private->info);
Packit Service fb6fa5
  g_free (colormap->colors);
Packit Service fb6fa5
  g_free (private);
Packit Service fb6fa5
  
Packit Service fb6fa5
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Mimics XAllocColorCells. Allocate read/write color cells. */
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean
Packit Service fb6fa5
alloc_color_cells (GdkColormap    *cmap,
Packit Service fb6fa5
		   gboolean        contig,
Packit Service fb6fa5
		   unsigned long   plane_masks_return[],
Packit Service fb6fa5
		   unsigned int    nplanes,
Packit Service fb6fa5
		   unsigned long   pixels_return[],
Packit Service fb6fa5
		   unsigned int	   npixels)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *cmapp = GDK_WIN32_COLORMAP_DATA (cmap);
Packit Service fb6fa5
  gint i, nfree, iret, start = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (COLORMAP, g_print ("alloc_color_cells: cmap=%p contig=%s npl=%d npix=%d",
Packit Service fb6fa5
			       cmapp, contig ? "TRUE" : "FALSE",
Packit Service fb6fa5
			       nplanes, npixels));
Packit Service fb6fa5
Packit Service fb6fa5
  switch (cmap->visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_GRAYSCALE:
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
      nfree = 0;
Packit Service fb6fa5
      for (i = 0; i < cmap->size && nfree < npixels; i++)
Packit Service fb6fa5
	if (cmapp->use[i] == GDK_WIN32_PE_AVAILABLE &&
Packit Service fb6fa5
	    (!contig ||
Packit Service fb6fa5
	     (nfree == 0 || cmapp->use[i-1] == GDK_WIN32_PE_AVAILABLE)))
Packit Service fb6fa5
	  {
Packit Service fb6fa5
	    if (nfree == 0)
Packit Service fb6fa5
	      start = i;
Packit Service fb6fa5
	    nfree++;
Packit Service fb6fa5
	  }
Packit Service fb6fa5
	else if (contig)
Packit Service fb6fa5
	  nfree = 0;
Packit Service fb6fa5
Packit Service fb6fa5
      if (npixels > nfree)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  GDK_NOTE (COLORMAP, g_print ("... nope (%d > %d)\n",
Packit Service fb6fa5
				       npixels, nfree));
Packit Service fb6fa5
	  return FALSE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	GDK_NOTE (COLORMAP, g_print ("... ok\n"));
Packit Service fb6fa5
Packit Service fb6fa5
      iret = 0;
Packit Service fb6fa5
      for (i = start; i < cmap->size && iret < npixels; i++)
Packit Service fb6fa5
	if (cmapp->use[i] == GDK_WIN32_PE_AVAILABLE)
Packit Service fb6fa5
	  {
Packit Service fb6fa5
	    cmapp->use[i] = GDK_WIN32_PE_INUSE;
Packit Service fb6fa5
	    pixels_return[iret] = i;
Packit Service fb6fa5
	    iret++;
Packit Service fb6fa5
	  }
Packit Service fb6fa5
      g_assert (iret == npixels);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_assert_not_reached ();
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* The following functions are originally from Tk8.0, but heavily
Packit Service fb6fa5
   modified.  Here are tk's licensing terms. I hope these terms don't
Packit Service fb6fa5
   conflict with the GNU Lesser General Public License? They
Packit Service fb6fa5
   shouldn't, as they are looser that the GLPL, yes? */
Packit Service fb6fa5
Packit Service fb6fa5
/*
Packit Service fb6fa5
This software is copyrighted by the Regents of the University of
Packit Service fb6fa5
California, Sun Microsystems, Inc., and other parties.  The following
Packit Service fb6fa5
terms apply to all files associated with the software unless explicitly
Packit Service fb6fa5
disclaimed in individual files.
Packit Service fb6fa5
Packit Service fb6fa5
The authors hereby grant permission to use, copy, modify, distribute,
Packit Service fb6fa5
and license this software and its documentation for any purpose, provided
Packit Service fb6fa5
that existing copyright notices are retained in all copies and that this
Packit Service fb6fa5
notice is included verbatim in any distributions. No written agreement,
Packit Service fb6fa5
license, or royalty fee is required for any of the authorized uses.
Packit Service fb6fa5
Modifications to this software may be copyrighted by their authors
Packit Service fb6fa5
and need not follow the licensing terms described here, provided that
Packit Service fb6fa5
the new terms are clearly indicated on the first page of each file where
Packit Service fb6fa5
they apply.
Packit Service fb6fa5
Packit Service fb6fa5
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
Packit Service fb6fa5
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
Packit Service fb6fa5
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
Packit Service fb6fa5
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
Packit Service fb6fa5
POSSIBILITY OF SUCH DAMAGE.
Packit Service fb6fa5
Packit Service fb6fa5
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
Packit Service fb6fa5
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
Packit Service fb6fa5
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
Packit Service fb6fa5
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
Packit Service fb6fa5
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
Packit Service fb6fa5
MODIFICATIONS.
Packit Service fb6fa5
Packit Service fb6fa5
GOVERNMENT USE: If you are acquiring this software on behalf of the
Packit Service fb6fa5
U.S. government, the Government shall have only "Restricted Rights"
Packit Service fb6fa5
in the software and related documentation as defined in the Federal 
Packit Service fb6fa5
Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
Packit Service fb6fa5
are acquiring the software on behalf of the Department of Defense, the
Packit Service fb6fa5
software shall be classified as "Commercial Computer Software" and the
Packit Service fb6fa5
Government shall have only "Restricted Rights" as defined in Clause
Packit Service fb6fa5
252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
Packit Service fb6fa5
authors grant the U.S. Government and others acting in its behalf
Packit Service fb6fa5
permission to use and distribute the software in accordance with the
Packit Service fb6fa5
terms specified in this license.
Packit Service fb6fa5
*/
Packit Service fb6fa5
Packit Service fb6fa5
/* Mimics XAllocColor. Allocate a read-only colormap entry. */
Packit Service fb6fa5
Packit Service fb6fa5
static int
Packit Service fb6fa5
alloc_color (GdkColormap  *cmap,
Packit Service fb6fa5
	     PALETTEENTRY *color,
Packit Service fb6fa5
	     guint        *pixelp)
Packit Service fb6fa5
{
Packit Service fb6fa5
  PALETTEENTRY entry, close_entry;
Packit Service fb6fa5
  COLORREF new_pixel;
Packit Service fb6fa5
  UINT index;
Packit Service fb6fa5
  GdkColormapPrivateWin32 *cmapp = GDK_WIN32_COLORMAP_DATA (cmap);
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
    
Packit Service fb6fa5
  entry = *color;
Packit Service fb6fa5
  entry.peFlags = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  new_pixel = RGB (entry.peRed, entry.peGreen, entry.peBlue);
Packit Service fb6fa5
Packit Service fb6fa5
  switch (cmap->visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
      /* Find the nearest existing palette entry. */
Packit Service fb6fa5
      index = GetNearestPaletteIndex (cmapp->hpal, new_pixel);
Packit Service fb6fa5
      GetPaletteEntries (cmapp->hpal, index, 1, &close_entry);
Packit Service fb6fa5
Packit Service fb6fa5
      GDK_NOTE (COLORMAP,
Packit Service fb6fa5
		g_print ("alloc_color: new_pixel=%06lx index=%d=%02x close=%06lx\n",
Packit Service fb6fa5
			 new_pixel, index, index,
Packit Service fb6fa5
			 RGB (close_entry.peRed, close_entry.peGreen, close_entry.peBlue)));
Packit Service fb6fa5
Packit Service fb6fa5
      if (new_pixel != RGB (close_entry.peRed, close_entry.peGreen,
Packit Service fb6fa5
			    close_entry.peBlue))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* Not a perfect match. */
Packit Service fb6fa5
	  if (cmapp->use[index] == GDK_WIN32_PE_AVAILABLE)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      /* It was a nonused entry anyway, so we can use it, and
Packit Service fb6fa5
	       * set it to the correct color.
Packit Service fb6fa5
	       */
Packit Service fb6fa5
	      GDK_NOTE (COLORMAP, g_print ("... was free\n"));
Packit Service fb6fa5
	      GDI_CALL (SetPaletteEntries, (cmapp->hpal, index, 1, &entry));
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      /* The close entry found is in use, so search for a
Packit Service fb6fa5
	       * available slot.
Packit Service fb6fa5
	       */
Packit Service fb6fa5
	      gboolean done = FALSE;
Packit Service fb6fa5
	      for (i = 0; i < cmap->size; i++)
Packit Service fb6fa5
		if (cmapp->use[i] == GDK_WIN32_PE_AVAILABLE)
Packit Service fb6fa5
		  {
Packit Service fb6fa5
		    /* An available slot, use it. */
Packit Service fb6fa5
		    GDK_NOTE (COLORMAP,
Packit Service fb6fa5
			      g_print ("... use free slot %d%s\n",
Packit Service fb6fa5
				       i, (i >= cmapp->current_size) ?
Packit Service fb6fa5
				       ", will resize palette" : ""));
Packit Service fb6fa5
		    if (i >= cmapp->current_size)
Packit Service fb6fa5
		      {
Packit Service fb6fa5
			if (!ResizePalette (cmapp->hpal, i + 1))
Packit Service fb6fa5
			  {
Packit Service fb6fa5
			    WIN32_GDI_FAILED ("ResizePalette");
Packit Service fb6fa5
			    break;
Packit Service fb6fa5
			  }
Packit Service fb6fa5
			cmapp->current_size = i + 1;
Packit Service fb6fa5
		      }
Packit Service fb6fa5
		    if (!SetPaletteEntries (cmapp->hpal, i, 1, &entry))
Packit Service fb6fa5
		      {
Packit Service fb6fa5
			WIN32_GDI_FAILED ("SetPaletteEntries");
Packit Service fb6fa5
			i = cmap->size;
Packit Service fb6fa5
		      }
Packit Service fb6fa5
		    else
Packit Service fb6fa5
		      {
Packit Service fb6fa5
			done = TRUE;
Packit Service fb6fa5
			index = i;
Packit Service fb6fa5
		      }
Packit Service fb6fa5
		    break;
Packit Service fb6fa5
		  }
Packit Service fb6fa5
	      if (!done)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  /* No free slots available, or failed to resize
Packit Service fb6fa5
		   * palette or set palette entry.
Packit Service fb6fa5
		   */
Packit Service fb6fa5
		  GDK_NOTE (COLORMAP, g_print ("... failure\n"));
Packit Service fb6fa5
		  return FALSE;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      else
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  /* We got a match, so use it. */
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      *pixelp = index;
Packit Service fb6fa5
      cmapp->use[index] = GDK_WIN32_PE_INUSE;
Packit Service fb6fa5
      GDK_NOTE (COLORMAP, g_print ("alloc_color: %p: "
Packit Service fb6fa5
				   "index=%3d=%02x for %02x %02x %02x: "
Packit Service fb6fa5
				   "%02x %02x %02x\n",
Packit Service fb6fa5
				   cmapp->hpal, index, index,
Packit Service fb6fa5
				   entry.peRed, entry.peGreen, entry.peBlue,
Packit Service fb6fa5
				   color->peRed, color->peGreen, color->peBlue));
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_STATIC_COLOR:
Packit Service fb6fa5
      /* Find the nearest existing palette entry. */
Packit Service fb6fa5
      index = GetNearestPaletteIndex (cmapp->hpal, new_pixel);
Packit Service fb6fa5
      GetPaletteEntries (cmapp->hpal, index, 1, &close_entry);
Packit Service fb6fa5
      *color = close_entry;
Packit Service fb6fa5
      *pixelp = index;
Packit Service fb6fa5
      GDK_NOTE (COLORMAP, g_print ("alloc_color %p: "
Packit Service fb6fa5
				   "index=%3d=%02x for %02x %02x %02x: "
Packit Service fb6fa5
				   "%02x %02x %02x\n",
Packit Service fb6fa5
				   cmapp->hpal, index, index,
Packit Service fb6fa5
				   entry.peRed, entry.peGreen, entry.peBlue,
Packit Service fb6fa5
				   color->peRed, color->peGreen, color->peBlue));
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_TRUE_COLOR:
Packit Service fb6fa5
      /* Determine what color will actually be used on non-colormap systems. */
Packit Service fb6fa5
Packit Service fb6fa5
      *pixelp = GetNearestColor (_gdk_display_hdc, new_pixel);
Packit Service fb6fa5
      color->peRed = GetRValue (*pixelp);
Packit Service fb6fa5
      color->peGreen = GetGValue (*pixelp);
Packit Service fb6fa5
      color->peBlue = GetBValue (*pixelp);
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_assert_not_reached ();
Packit Service fb6fa5
      return FALSE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Mimics XFreeColors. */
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
free_colors (GdkColormap *cmap,
Packit Service fb6fa5
	     gulong  	 *pixels,
Packit Service fb6fa5
	     gint    	  npixels,
Packit Service fb6fa5
	     gulong  	  planes)
Packit Service fb6fa5
{
Packit Service fb6fa5
  PALETTEENTRY pe;
Packit Service fb6fa5
  GdkColormapPrivateWin32 *cmapp = GDK_WIN32_COLORMAP_DATA (cmap);
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
#ifdef G_ENABLE_DEBUG
Packit Service fb6fa5
  gint set_black_count = 0;
Packit Service fb6fa5
#endif
Packit Service fb6fa5
  gboolean *cleared_entries;
Packit Service fb6fa5
Packit Service fb6fa5
  cleared_entries = g_new0 (gboolean, cmap->size);
Packit Service fb6fa5
Packit Service fb6fa5
  /* We don't have to do anything for non-palette devices. */
Packit Service fb6fa5
  
Packit Service fb6fa5
  switch (cmap->visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_GRAYSCALE:
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
      for (i = 0; i < npixels; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (pixels[i] >= cmap->size)
Packit Service fb6fa5
	    ; /* Nothing */
Packit Service fb6fa5
	  else if (cmapp->use[pixels[i]] == GDK_WIN32_PE_STATIC)
Packit Service fb6fa5
	    ; /* Nothing either*/
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      cmapp->use[pixels[i]] = GDK_WIN32_PE_AVAILABLE;
Packit Service fb6fa5
	      cleared_entries[pixels[i]] = TRUE;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      for (i = cmapp->current_size - 1; i >= 0; i--)
Packit Service fb6fa5
	if (cmapp->use[i] != GDK_WIN32_PE_AVAILABLE)
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
      if (i < cmapp->current_size - 1)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  GDK_NOTE (COLORMAP, g_print ("free_colors: hpal=%p resize=%d\n",
Packit Service fb6fa5
				       cmapp->hpal, i + 1));
Packit Service fb6fa5
	  if (!ResizePalette (cmapp->hpal, i + 1))
Packit Service fb6fa5
	    WIN32_GDI_FAILED ("ResizePalette");
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    cmapp->current_size = i + 1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      pe.peRed = pe.peGreen = pe.peBlue = pe.peFlags = 0;
Packit Service fb6fa5
      for (i = 0; i < cmapp->current_size; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (cleared_entries[i])
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      GDI_CALL (SetPaletteEntries, (cmapp->hpal, i, 1, &pe);;
Packit Service fb6fa5
	      GDK_NOTE (COLORMAP, set_black_count++);
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
#if 0
Packit Service fb6fa5
      GDK_NOTE (COLORMAP, _gdk_win32_print_hpalette (cmapp->hpal));
Packit Service fb6fa5
#else
Packit Service fb6fa5
      GDK_NOTE (COLORMAP, (set_black_count > 0 ?
Packit Service fb6fa5
			   g_print ("free_colors: %d (%d) set to black\n",
Packit Service fb6fa5
				    set_black_count, cmapp->current_size)
Packit Service fb6fa5
			   : (void) 0));
Packit Service fb6fa5
#endif
Packit Service fb6fa5
      g_free (cleared_entries);
Packit Service fb6fa5
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_assert_not_reached ();
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/* Mimics XCreateColormap. */
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
create_colormap (GdkColormap *cmap,
Packit Service fb6fa5
		 gboolean     writeable)
Packit Service fb6fa5
{
Packit Service fb6fa5
  struct {
Packit Service fb6fa5
    LOGPALETTE pal;
Packit Service fb6fa5
    PALETTEENTRY pe[256-1];
Packit Service fb6fa5
  } lp;
Packit Service fb6fa5
  HPALETTE hpal;
Packit Service fb6fa5
  GdkColormapPrivateWin32 *cmapp = GDK_WIN32_COLORMAP_DATA (cmap);
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  /* Allocate a starting palette with all the static colors. */
Packit Service fb6fa5
  hpal = GetStockObject (DEFAULT_PALETTE);
Packit Service fb6fa5
  lp.pal.palVersion = 0x300;
Packit Service fb6fa5
  lp.pal.palNumEntries = GetPaletteEntries (hpal, 0, 256, lp.pal.palPalEntry);
Packit Service fb6fa5
Packit Service fb6fa5
  if (cmap->visual->type == GDK_VISUAL_STATIC_COLOR &&
Packit Service fb6fa5
      cmap->visual->depth == 4)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* Use only 16 colors */
Packit Service fb6fa5
      for (i = 8; i < 16; i++)
Packit Service fb6fa5
	lp.pal.palPalEntry[i] = lp.pal.palPalEntry[i+4];
Packit Service fb6fa5
      lp.pal.palNumEntries = 16;
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < lp.pal.palNumEntries; i++)
Packit Service fb6fa5
    lp.pal.palPalEntry[i].peFlags = 0;
Packit Service fb6fa5
  GDK_NOTE (COLORMAP, (g_print ("Default palette %p: %d entries\n",
Packit Service fb6fa5
				hpal, lp.pal.palNumEntries),
Packit Service fb6fa5
		       _gdk_win32_print_paletteentries (lp.pal.palPalEntry,
Packit Service fb6fa5
						       lp.pal.palNumEntries)));
Packit Service fb6fa5
  DeleteObject (hpal);
Packit Service fb6fa5
  
Packit Service fb6fa5
  /* For writeable colormaps, allow all 256 entries to be set. They won't
Packit Service fb6fa5
   * set all 256 system palette entries anyhow, of course, but we shouldn't
Packit Service fb6fa5
   * let the app see that, I think.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  if (writeable)
Packit Service fb6fa5
    cmapp->current_size = 0;
Packit Service fb6fa5
  else
Packit Service fb6fa5
    cmapp->current_size = lp.pal.palNumEntries;
Packit Service fb6fa5
Packit Service fb6fa5
  cmapp->private_val = writeable;
Packit Service fb6fa5
Packit Service fb6fa5
  if (!(cmapp->hpal = CreatePalette (&lp.pal)))
Packit Service fb6fa5
    WIN32_GDI_FAILED ("CreatePalette");
Packit Service fb6fa5
  else
Packit Service fb6fa5
    GDK_NOTE (COLORMAP, g_print ("Created palette %p\n", cmapp->hpal));
Packit Service fb6fa5
Packit Service fb6fa5
  switch (cmap->visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
      cmapp->use = g_new (GdkWin32PalEntryState, cmap->size);
Packit Service fb6fa5
Packit Service fb6fa5
      /* Mark static colors in use. */
Packit Service fb6fa5
      for (i = 0; i < cmapp->current_size; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  cmapp->use[i] = GDK_WIN32_PE_STATIC;
Packit Service fb6fa5
	  cmapp->info[i].ref_count = G_MAXUINT/2;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      /* Mark rest not in use */
Packit Service fb6fa5
      for (; i < cmap->size; i++)
Packit Service fb6fa5
	cmapp->use[i] = GDK_WIN32_PE_AVAILABLE;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void
Packit Service fb6fa5
sync_colors (GdkColormap *colormap)
Packit Service fb6fa5
{
Packit Service fb6fa5
  PALETTEENTRY *pe;
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
  gint nlookup;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  
Packit Service fb6fa5
  pe = g_new (PALETTEENTRY, colormap->size);
Packit Service fb6fa5
  nlookup = GetPaletteEntries (private->hpal, 0, colormap->size, pe);
Packit Service fb6fa5
	  
Packit Service fb6fa5
  GDK_NOTE (COLORMAP, (g_print ("sync_colors: %p hpal=%p: %d entries\n",
Packit Service fb6fa5
				private, private->hpal, nlookup),
Packit Service fb6fa5
		       _gdk_win32_print_paletteentries (pe, nlookup)));
Packit Service fb6fa5
	  
Packit Service fb6fa5
  for (i = 0; i < nlookup; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      colormap->colors[i].pixel = i;
Packit Service fb6fa5
      colormap->colors[i].red = (pe[i].peRed * 65535) / 255;
Packit Service fb6fa5
      colormap->colors[i].green = (pe[i].peGreen * 65535) / 255;
Packit Service fb6fa5
      colormap->colors[i].blue = (pe[i].peBlue * 65535) / 255;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  for ( ; i < colormap->size; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      colormap->colors[i].pixel = i;
Packit Service fb6fa5
      colormap->colors[i].red = 0;
Packit Service fb6fa5
      colormap->colors[i].green = 0;
Packit Service fb6fa5
      colormap->colors[i].blue = 0;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  g_free (pe);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkColormap*
Packit Service fb6fa5
gdk_colormap_new (GdkVisual *visual,
Packit Service fb6fa5
		  gboolean   private_cmap)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormap *colormap;
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (visual != NULL, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  colormap = g_object_new (gdk_colormap_get_type (), NULL);
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  colormap->visual = visual;
Packit Service fb6fa5
Packit Service fb6fa5
  colormap->size = visual->colormap_size;
Packit Service fb6fa5
Packit Service fb6fa5
  switch (visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_GRAYSCALE:
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
      private->info = g_new0 (GdkColorInfo, colormap->size);
Packit Service fb6fa5
      colormap->colors = g_new (GdkColor, colormap->size);
Packit Service fb6fa5
      
Packit Service fb6fa5
      private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
Packit Service fb6fa5
					(GEqualFunc) gdk_color_equal);
Packit Service fb6fa5
      
Packit Service fb6fa5
      create_colormap (colormap, private_cmap);
Packit Service fb6fa5
Packit Service fb6fa5
      if (private_cmap)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  sync_colors (colormap);
Packit Service fb6fa5
#if 0 /* XXX is this needed or not? Seems redundant */
Packit Service fb6fa5
	  gdk_colormap_change (colormap, colormap->size);
Packit Service fb6fa5
#endif
Packit Service fb6fa5
	}
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_STATIC_GRAY:
Packit Service fb6fa5
    case GDK_VISUAL_STATIC_COLOR:
Packit Service fb6fa5
      create_colormap (colormap, FALSE);
Packit Service fb6fa5
      colormap->colors = g_new (GdkColor, colormap->size);
Packit Service fb6fa5
      sync_colors (colormap);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_TRUE_COLOR:
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_assert_not_reached ();
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return colormap;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkColormap*
Packit Service fb6fa5
gdk_screen_get_system_colormap (GdkScreen *screen)
Packit Service fb6fa5
{
Packit Service fb6fa5
  static GdkColormap *colormap = NULL;
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (screen == _gdk_screen, NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if (!colormap)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      colormap = g_object_new (gdk_colormap_get_type (), NULL);
Packit Service fb6fa5
      private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
      colormap->visual = gdk_visual_get_system ();
Packit Service fb6fa5
Packit Service fb6fa5
      colormap->size = colormap->visual->colormap_size;
Packit Service fb6fa5
Packit Service fb6fa5
      private->private_val = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
      switch (colormap->visual->type)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	case GDK_VISUAL_GRAYSCALE:
Packit Service fb6fa5
	case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
	  private->info = g_new0 (GdkColorInfo, colormap->size);
Packit Service fb6fa5
	  private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash,
Packit Service fb6fa5
					    (GEqualFunc) gdk_color_equal);
Packit Service fb6fa5
	  /* Fallthrough */
Packit Service fb6fa5
Packit Service fb6fa5
	case GDK_VISUAL_STATIC_GRAY:
Packit Service fb6fa5
	case GDK_VISUAL_STATIC_COLOR:
Packit Service fb6fa5
	  create_colormap (colormap, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
	  colormap->colors = g_new (GdkColor, colormap->size);
Packit Service fb6fa5
	  sync_colors (colormap);
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
Packit Service fb6fa5
	case GDK_VISUAL_TRUE_COLOR:
Packit Service fb6fa5
	  break;
Packit Service fb6fa5
Packit Service fb6fa5
	default:
Packit Service fb6fa5
	  g_assert_not_reached ();
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return colormap;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gint
Packit Service fb6fa5
gdk_colormap_get_system_size (void)
Packit Service fb6fa5
{
Packit Service fb6fa5
  return gdk_colormap_get_system ()->size;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
gdk_colormap_change (GdkColormap *colormap,
Packit Service fb6fa5
		     gint         ncolors)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *cmapp;
Packit Service fb6fa5
  PALETTEENTRY *pe;
Packit Service fb6fa5
  int i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_COLORMAP (colormap));
Packit Service fb6fa5
Packit Service fb6fa5
  cmapp = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  GDK_NOTE (COLORMAP, g_print ("gdk_colormap_change: hpal=%p ncolors=%d\n",
Packit Service fb6fa5
			       cmapp->hpal, ncolors));
Packit Service fb6fa5
Packit Service fb6fa5
  switch (colormap->visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_GRAYSCALE:
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
      pe = g_new (PALETTEENTRY, ncolors);
Packit Service fb6fa5
Packit Service fb6fa5
      for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  pe[i].peRed = (colormap->colors[i].red >> 8);
Packit Service fb6fa5
	  pe[i].peGreen = (colormap->colors[i].green >> 8);
Packit Service fb6fa5
	  pe[i].peBlue = (colormap->colors[i].blue >> 8);
Packit Service fb6fa5
	  pe[i].peFlags = 0;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
      GDI_CALL (SetPaletteEntries, (cmapp->hpal, 0, ncolors, pe));
Packit Service fb6fa5
      g_free (pe);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gdk_colors_alloc (GdkColormap   *colormap,
Packit Service fb6fa5
		  gboolean       contiguous,
Packit Service fb6fa5
		  gulong        *planes,
Packit Service fb6fa5
		  gint           nplanes,
Packit Service fb6fa5
		  gulong        *pixels,
Packit Service fb6fa5
		  gint           npixels)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  gint return_val;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_COLORMAP (colormap), FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  return_val = alloc_color_cells (colormap, contiguous,
Packit Service fb6fa5
				  planes, nplanes, pixels, npixels);
Packit Service fb6fa5
Packit Service fb6fa5
  if (return_val)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      for (i = 0; i < npixels; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  private->info[pixels[i]].ref_count++;
Packit Service fb6fa5
	  private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return return_val != 0;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
gdk_colors_free (GdkColormap *colormap,
Packit Service fb6fa5
		 gulong      *in_pixels,
Packit Service fb6fa5
		 gint         in_npixels,
Packit Service fb6fa5
		 gulong       planes)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  gulong *pixels;
Packit Service fb6fa5
  gint npixels = 0;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_COLORMAP (colormap));
Packit Service fb6fa5
  g_return_if_fail (in_pixels != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  if ((colormap->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
Packit Service fb6fa5
      (colormap->visual->type != GDK_VISUAL_GRAYSCALE))
Packit Service fb6fa5
    return;
Packit Service fb6fa5
  
Packit Service fb6fa5
  pixels = g_new (gulong, in_npixels);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < in_npixels; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gulong pixel = in_pixels[i];
Packit Service fb6fa5
      
Packit Service fb6fa5
      if (private->use[pixel] == GDK_WIN32_PE_STATIC)
Packit Service fb6fa5
	continue;
Packit Service fb6fa5
Packit Service fb6fa5
      if (private->info[pixel].ref_count)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  private->info[pixel].ref_count--;
Packit Service fb6fa5
Packit Service fb6fa5
	  if (private->info[pixel].ref_count == 0)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      pixels[npixels++] = pixel;
Packit Service fb6fa5
	      if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))
Packit Service fb6fa5
		g_hash_table_remove (private->hash, &colormap->colors[pixel]);
Packit Service fb6fa5
	      private->info[pixel].flags = 0;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  if (npixels)
Packit Service fb6fa5
    free_colors (colormap, pixels, npixels, planes);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (pixels);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
gdk_colormap_free_colors (GdkColormap    *colormap,
Packit Service fb6fa5
			  const GdkColor *colors,
Packit Service fb6fa5
			  gint            ncolors)
Packit Service fb6fa5
{
Packit Service fb6fa5
  gulong *pixels;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_COLORMAP (colormap));
Packit Service fb6fa5
  g_return_if_fail (colors != NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  if ((colormap->visual->type != GDK_VISUAL_PSEUDO_COLOR) &&
Packit Service fb6fa5
      (colormap->visual->type != GDK_VISUAL_GRAYSCALE))
Packit Service fb6fa5
    return;
Packit Service fb6fa5
Packit Service fb6fa5
  pixels = g_new (gulong, ncolors);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
    pixels[i] =  colors[i].pixel;
Packit Service fb6fa5
Packit Service fb6fa5
  gdk_colors_free (colormap, pixels, ncolors, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  g_free (pixels);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
/********************
Packit Service fb6fa5
 * Color allocation *
Packit Service fb6fa5
 ********************/
Packit Service fb6fa5
Packit Service fb6fa5
/* Try to allocate a single color using alloc_color. If it succeeds,
Packit Service fb6fa5
 * cache the result in our colormap, and store in ret.
Packit Service fb6fa5
 */
Packit Service fb6fa5
static gboolean 
Packit Service fb6fa5
gdk_colormap_alloc1 (GdkColormap *colormap,
Packit Service fb6fa5
		     GdkColor    *color,
Packit Service fb6fa5
		     GdkColor    *ret)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  PALETTEENTRY pe;
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  pe.peRed = color->red >> 8;
Packit Service fb6fa5
  pe.peGreen = color->green >> 8;
Packit Service fb6fa5
  pe.peBlue = color->blue >> 8;
Packit Service fb6fa5
Packit Service fb6fa5
  if (alloc_color (colormap, &pe, &ret->pixel))
Packit Service fb6fa5
    {
Packit Service fb6fa5
      ret->red = (pe.peRed * 65535) / 255;
Packit Service fb6fa5
      ret->green = (pe.peGreen * 65535) / 255;
Packit Service fb6fa5
      ret->blue = (pe.peBlue * 65535) / 255;
Packit Service fb6fa5
      
Packit Service fb6fa5
      if ((guint) ret->pixel < colormap->size)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (private->info[ret->pixel].ref_count) /* got a duplicate */
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      colormap->colors[ret->pixel] = *color;
Packit Service fb6fa5
	      colormap->colors[ret->pixel].pixel = ret->pixel;
Packit Service fb6fa5
	      private->info[ret->pixel].ref_count = 1;
Packit Service fb6fa5
Packit Service fb6fa5
	      g_hash_table_insert (private->hash,
Packit Service fb6fa5
				   &colormap->colors[ret->pixel],
Packit Service fb6fa5
				   &colormap->colors[ret->pixel]);
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      return TRUE;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  return FALSE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gdk_colormap_alloc_colors_writeable (GdkColormap *colormap,
Packit Service fb6fa5
				     GdkColor    *colors,
Packit Service fb6fa5
				     gint         ncolors,
Packit Service fb6fa5
				     gboolean     writeable,
Packit Service fb6fa5
				     gboolean     best_match,
Packit Service fb6fa5
				     gboolean    *success)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  gulong *pixels;
Packit Service fb6fa5
  gboolean status;
Packit Service fb6fa5
  gint i, index;
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  if (private->private_val)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      index = 0;
Packit Service fb6fa5
      for (i=0; i
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  while ((index < colormap->size) &&
Packit Service fb6fa5
		 (private->info[index].ref_count != 0))
Packit Service fb6fa5
	    index++;
Packit Service fb6fa5
	  
Packit Service fb6fa5
	  if (index < colormap->size)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      colors[i].pixel = index;
Packit Service fb6fa5
	      success[i] = TRUE;
Packit Service fb6fa5
	      private->info[index].ref_count++;
Packit Service fb6fa5
	      private->info[i].flags |= GDK_COLOR_WRITEABLE;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    break;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      return i;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    {
Packit Service fb6fa5
      pixels = g_new (gulong, ncolors);
Packit Service fb6fa5
Packit Service fb6fa5
      /* Allocation of a writeable color cells */
Packit Service fb6fa5
      status =  alloc_color_cells (colormap, FALSE, NULL, 0, pixels, ncolors);
Packit Service fb6fa5
      if (status)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      colors[i].pixel = pixels[i];
Packit Service fb6fa5
	      private->info[pixels[i]].ref_count++;
Packit Service fb6fa5
	      private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      
Packit Service fb6fa5
      g_free (pixels);
Packit Service fb6fa5
Packit Service fb6fa5
      return status ? ncolors : 0; 
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gdk_colormap_alloc_colors_private (GdkColormap *colormap,
Packit Service fb6fa5
				   GdkColor    *colors,
Packit Service fb6fa5
				   gint         ncolors,
Packit Service fb6fa5
				   gboolean     writeable,
Packit Service fb6fa5
				   gboolean     best_match,
Packit Service fb6fa5
				   gboolean    *success)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *cmapp;
Packit Service fb6fa5
  gint i, index;
Packit Service fb6fa5
  PALETTEENTRY pe;
Packit Service fb6fa5
  gint nremaining = 0;
Packit Service fb6fa5
  
Packit Service fb6fa5
  cmapp = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
  index = -1;
Packit Service fb6fa5
Packit Service fb6fa5
  /* First, store the colors we have room for */
Packit Service fb6fa5
Packit Service fb6fa5
  index = 0;
Packit Service fb6fa5
  for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (!success[i])
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  while ((index < colormap->size) &&
Packit Service fb6fa5
		 (cmapp->info[index].ref_count != 0))
Packit Service fb6fa5
	    index++;
Packit Service fb6fa5
Packit Service fb6fa5
	  if (index < colormap->size)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      if (index >= cmapp->current_size)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  if (!ResizePalette (cmapp->hpal, index + 1))
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      WIN32_GDI_FAILED ("ResizePalette");
Packit Service fb6fa5
		      nremaining++;
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		  else
Packit Service fb6fa5
		    cmapp->current_size = index + 1;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	      if (index < cmapp->current_size)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  pe.peRed = colors[i].red >> 8;
Packit Service fb6fa5
		  pe.peBlue = colors[i].blue >> 8;
Packit Service fb6fa5
		  pe.peGreen = colors[i].green >> 8;
Packit Service fb6fa5
		  pe.peFlags = 0;
Packit Service fb6fa5
		  
Packit Service fb6fa5
		  if (!SetPaletteEntries (cmapp->hpal, index, 1, &pe))
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      WIN32_GDI_FAILED ("SetPaletteEntries");
Packit Service fb6fa5
		      nremaining++;
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		  else
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      success[i] = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
		      colors[i].pixel = index;
Packit Service fb6fa5
		      colormap->colors[index] = colors[i];
Packit Service fb6fa5
		      cmapp->info[index].ref_count++;
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    nremaining++;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  if (nremaining > 0 && best_match)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      /* Get best matches for remaining colors */
Packit Service fb6fa5
Packit Service fb6fa5
      gchar *available = g_new (gchar, colormap->size);
Packit Service fb6fa5
      for (i = 0; i < colormap->size; i++)
Packit Service fb6fa5
	available[i] = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
      for (i=0; i
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (!success[i])
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      index = gdk_colormap_match_color (colormap, 
Packit Service fb6fa5
						&colors[i], 
Packit Service fb6fa5
						available);
Packit Service fb6fa5
	      if (index != -1)
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  colors[i] = colormap->colors[index];
Packit Service fb6fa5
		  cmapp->info[index].ref_count++;
Packit Service fb6fa5
Packit Service fb6fa5
		  success[i] = TRUE;
Packit Service fb6fa5
		  nremaining--;
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      g_free (available);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return (ncolors - nremaining);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gdk_colormap_alloc_colors_shared (GdkColormap *colormap,
Packit Service fb6fa5
				  GdkColor    *colors,
Packit Service fb6fa5
				  gint         ncolors,
Packit Service fb6fa5
				  gboolean     writeable,
Packit Service fb6fa5
				  gboolean     best_match,
Packit Service fb6fa5
				  gboolean    *success)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  gint i, index;
Packit Service fb6fa5
  gint nremaining = 0;
Packit Service fb6fa5
  gint nfailed = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
  index = -1;
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (!success[i])
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))
Packit Service fb6fa5
	    success[i] = TRUE;
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    nremaining++;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
Packit Service fb6fa5
  if (nremaining > 0 && best_match)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      gchar *available = g_new (gchar, colormap->size);
Packit Service fb6fa5
      for (i = 0; i < colormap->size; i++)
Packit Service fb6fa5
	available[i] = ((private->info[i].ref_count == 0) ||
Packit Service fb6fa5
			!(private->info[i].flags & GDK_COLOR_WRITEABLE));
Packit Service fb6fa5
      while (nremaining > 0)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      if (!success[i])
Packit Service fb6fa5
		{
Packit Service fb6fa5
		  index = gdk_colormap_match_color (colormap, &colors[i], available);
Packit Service fb6fa5
		  if (index != -1)
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      if (private->info[index].ref_count)
Packit Service fb6fa5
			{
Packit Service fb6fa5
			  private->info[index].ref_count++;
Packit Service fb6fa5
			  colors[i] = colormap->colors[index];
Packit Service fb6fa5
			  success[i] = TRUE;
Packit Service fb6fa5
			  nremaining--;
Packit Service fb6fa5
			}
Packit Service fb6fa5
		      else
Packit Service fb6fa5
			{
Packit Service fb6fa5
			  if (gdk_colormap_alloc1 (colormap, 
Packit Service fb6fa5
						   &colormap->colors[index],
Packit Service fb6fa5
						   &colors[i]))
Packit Service fb6fa5
			    {
Packit Service fb6fa5
			      success[i] = TRUE;
Packit Service fb6fa5
			      nremaining--;
Packit Service fb6fa5
			      break;
Packit Service fb6fa5
			    }
Packit Service fb6fa5
			  else
Packit Service fb6fa5
			    {
Packit Service fb6fa5
			      available[index] = FALSE;
Packit Service fb6fa5
			    }
Packit Service fb6fa5
			}
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		  else
Packit Service fb6fa5
		    {
Packit Service fb6fa5
		      nfailed++;
Packit Service fb6fa5
		      nremaining--;
Packit Service fb6fa5
		      success[i] = 2; /* flag as permanent failure */
Packit Service fb6fa5
		    }
Packit Service fb6fa5
		}
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
      g_free (available);
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /* Change back the values we flagged as permanent failures */
Packit Service fb6fa5
  if (nfailed > 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
	if (success[i] == 2)
Packit Service fb6fa5
	  success[i] = FALSE;
Packit Service fb6fa5
      nremaining = nfailed;
Packit Service fb6fa5
    }
Packit Service fb6fa5
  
Packit Service fb6fa5
  return (ncolors - nremaining);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,
Packit Service fb6fa5
				       GdkColor    *colors,
Packit Service fb6fa5
				       gint         ncolors,
Packit Service fb6fa5
				       gboolean     writeable,
Packit Service fb6fa5
				       gboolean     best_match,
Packit Service fb6fa5
				       gboolean    *success)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  GdkColor *lookup_color;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  gint nremaining = 0;
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  /* Check for an exact match among previously allocated colors */
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (!success[i])
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  lookup_color = g_hash_table_lookup (private->hash, &colors[i]);
Packit Service fb6fa5
	  if (lookup_color)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      private->info[lookup_color->pixel].ref_count++;
Packit Service fb6fa5
	      colors[i].pixel = lookup_color->pixel;
Packit Service fb6fa5
	      success[i] = TRUE;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    nremaining++;
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  /* If that failed, we try to allocate a new color, or approxmiate
Packit Service fb6fa5
   * with what we can get if best_match is TRUE.
Packit Service fb6fa5
   */
Packit Service fb6fa5
  if (nremaining > 0)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if (private->private_val)
Packit Service fb6fa5
	return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);
Packit Service fb6fa5
      else
Packit Service fb6fa5
	return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);
Packit Service fb6fa5
    }
Packit Service fb6fa5
  else
Packit Service fb6fa5
    return 0;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gint
Packit Service fb6fa5
gdk_colormap_alloc_colors (GdkColormap *colormap,
Packit Service fb6fa5
			   GdkColor    *colors,
Packit Service fb6fa5
			   gint         ncolors,
Packit Service fb6fa5
			   gboolean     writeable,
Packit Service fb6fa5
			   gboolean     best_match,
Packit Service fb6fa5
			   gboolean    *success)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  GdkVisual *visual;
Packit Service fb6fa5
  gint i;
Packit Service fb6fa5
  gint nremaining = 0;
Packit Service fb6fa5
  PALETTEENTRY pe;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_COLORMAP (colormap), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (colors != NULL, FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (success != NULL, ncolors);
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
    success[i] = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  switch (colormap->visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
    case GDK_VISUAL_GRAYSCALE:
Packit Service fb6fa5
      if (writeable)
Packit Service fb6fa5
	return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,
Packit Service fb6fa5
						    writeable, best_match, success);
Packit Service fb6fa5
      else
Packit Service fb6fa5
	return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,
Packit Service fb6fa5
						    writeable, best_match, success);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_TRUE_COLOR:
Packit Service fb6fa5
      visual = colormap->visual;
Packit Service fb6fa5
Packit Service fb6fa5
      for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  colors[i].pixel =
Packit Service fb6fa5
	    (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +
Packit Service fb6fa5
	     ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +
Packit Service fb6fa5
	     ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));
Packit Service fb6fa5
	  success[i] = TRUE;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_STATIC_GRAY:
Packit Service fb6fa5
    case GDK_VISUAL_STATIC_COLOR:
Packit Service fb6fa5
      for (i = 0; i < ncolors; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  pe.peRed = colors[i].red >> 8;
Packit Service fb6fa5
	  pe.peGreen = colors[i].green >> 8;
Packit Service fb6fa5
	  pe.peBlue = colors[i].blue >> 8;
Packit Service fb6fa5
	  if (alloc_color (colormap, &pe, &colors[i].pixel))
Packit Service fb6fa5
	    success[i] = TRUE;
Packit Service fb6fa5
	  else
Packit Service fb6fa5
	    nremaining++;
Packit Service fb6fa5
	}
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_DIRECT_COLOR:
Packit Service fb6fa5
      g_assert_not_reached ();
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return nremaining;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
void
Packit Service fb6fa5
gdk_colormap_query_color (GdkColormap *colormap,
Packit Service fb6fa5
			  gulong       pixel,
Packit Service fb6fa5
			  GdkColor    *result)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkVisual *visual;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_if_fail (GDK_IS_COLORMAP (colormap));
Packit Service fb6fa5
  
Packit Service fb6fa5
  visual = gdk_colormap_get_visual (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  switch (visual->type)
Packit Service fb6fa5
    {
Packit Service fb6fa5
    case GDK_VISUAL_DIRECT_COLOR:
Packit Service fb6fa5
    case GDK_VISUAL_TRUE_COLOR:
Packit Service fb6fa5
      result->red = 65535. * (double)((pixel & visual->red_mask) >> visual->red_shift) / ((1 << visual->red_prec) - 1);
Packit Service fb6fa5
      result->green = 65535. * (double)((pixel & visual->green_mask) >> visual->green_shift) / ((1 << visual->green_prec) - 1);
Packit Service fb6fa5
      result->blue = 65535. * (double)((pixel & visual->blue_mask) >> visual->blue_shift) / ((1 << visual->blue_prec) - 1);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_STATIC_GRAY:
Packit Service fb6fa5
    case GDK_VISUAL_GRAYSCALE:
Packit Service fb6fa5
      result->red = result->green = result->blue = 65535. * (double)pixel/((1<<visual->depth) - 1);
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    case GDK_VISUAL_STATIC_COLOR:
Packit Service fb6fa5
    case GDK_VISUAL_PSEUDO_COLOR:
Packit Service fb6fa5
      result->red = colormap->colors[pixel].red;
Packit Service fb6fa5
      result->green = colormap->colors[pixel].green;
Packit Service fb6fa5
      result->blue = colormap->colors[pixel].blue;
Packit Service fb6fa5
      break;
Packit Service fb6fa5
Packit Service fb6fa5
    default:
Packit Service fb6fa5
      g_assert_not_reached ();
Packit Service fb6fa5
      break;
Packit Service fb6fa5
    }
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gboolean
Packit Service fb6fa5
gdk_color_change (GdkColormap *colormap,
Packit Service fb6fa5
		  GdkColor    *color)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColormapPrivateWin32 *private;
Packit Service fb6fa5
  PALETTEENTRY pe;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_COLORMAP (colormap), FALSE);
Packit Service fb6fa5
  g_return_val_if_fail (color != NULL, FALSE);
Packit Service fb6fa5
Packit Service fb6fa5
  private = GDK_WIN32_COLORMAP_DATA (colormap);
Packit Service fb6fa5
Packit Service fb6fa5
  if (color->pixel < 0 || color->pixel >= colormap->size)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  if (private->use[color->pixel] == GDK_WIN32_PE_STATIC)
Packit Service fb6fa5
    return FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
  pe.peRed = color->red >> 8;
Packit Service fb6fa5
  pe.peGreen = color->green >> 8;
Packit Service fb6fa5
  pe.peBlue = color->blue >> 8;
Packit Service fb6fa5
Packit Service fb6fa5
  GDI_CALL (SetPaletteEntries, (private->hpal, color->pixel, 1, &pe);;
Packit Service fb6fa5
Packit Service fb6fa5
  return TRUE;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint
Packit Service fb6fa5
gdk_colormap_match_color (GdkColormap *cmap,
Packit Service fb6fa5
			  GdkColor    *color,
Packit Service fb6fa5
			  const gchar *available)
Packit Service fb6fa5
{
Packit Service fb6fa5
  GdkColor *colors;
Packit Service fb6fa5
  guint sum, min;
Packit Service fb6fa5
  gint rdiff, gdiff, bdiff;
Packit Service fb6fa5
  gint i, index;
Packit Service fb6fa5
Packit Service fb6fa5
  g_return_val_if_fail (cmap != NULL, 0);
Packit Service fb6fa5
  g_return_val_if_fail (color != NULL, 0);
Packit Service fb6fa5
Packit Service fb6fa5
  colors = cmap->colors;
Packit Service fb6fa5
  min = 3 * (65536);
Packit Service fb6fa5
  index = -1;
Packit Service fb6fa5
Packit Service fb6fa5
  for (i = 0; i < cmap->size; i++)
Packit Service fb6fa5
    {
Packit Service fb6fa5
      if ((!available) || (available && available[i]))
Packit Service fb6fa5
	{
Packit Service fb6fa5
	  rdiff = (color->red - colors[i].red);
Packit Service fb6fa5
	  gdiff = (color->green - colors[i].green);
Packit Service fb6fa5
	  bdiff = (color->blue - colors[i].blue);
Packit Service fb6fa5
Packit Service fb6fa5
	  sum = ABS (rdiff) + ABS (gdiff) + ABS (bdiff);
Packit Service fb6fa5
Packit Service fb6fa5
	  if (sum < min)
Packit Service fb6fa5
	    {
Packit Service fb6fa5
	      index = i;
Packit Service fb6fa5
	      min = sum;
Packit Service fb6fa5
	    }
Packit Service fb6fa5
	}
Packit Service fb6fa5
    }
Packit Service fb6fa5
Packit Service fb6fa5
  return index;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
GdkScreen*
Packit Service fb6fa5
gdk_colormap_get_screen (GdkColormap *cmap)
Packit Service fb6fa5
{
Packit Service fb6fa5
  g_return_val_if_fail (GDK_IS_COLORMAP (cmap), NULL);
Packit Service fb6fa5
Packit Service fb6fa5
  return _gdk_screen;
Packit Service fb6fa5
}
Packit Service fb6fa5