⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdkcolor.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 2 页
字号:
	  private->info[pixel].ref_count--;	  if (private->info[pixel].ref_count == 0)	    {	      pixels[npixels++] = pixel;	      if (!(private->info[pixel].flags & GDK_COLOR_WRITEABLE))		g_hash_table_remove (private->hash, &colormap->colors[pixel]);	      private->info[pixel].flags = 0;	    }	}    }  if (npixels)    XFreeColors (private->xdisplay, private->xcolormap,		 pixels, npixels, 0);  g_free (pixels);}/******************** * Color allocation * ********************//* Try to allocate a single color using XAllocColor. If it succeeds, * cache the result in our colormap, and store in ret. */static gboolean gdk_colormap_alloc1 (GdkColormap *colormap,		     GdkColor    *color,		     GdkColor    *ret){  GdkColormapPrivate *private;  XColor xcolor;  private = (GdkColormapPrivate*) colormap;  xcolor.red = color->red;  xcolor.green = color->green;  xcolor.blue = color->blue;  xcolor.pixel = color->pixel;  xcolor.flags = DoRed | DoGreen | DoBlue;  if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))    {      ret->pixel = xcolor.pixel;      ret->red = xcolor.red;      ret->green = xcolor.green;      ret->blue = xcolor.blue;            if (ret->pixel < colormap->size)	{	  if (private->info[ret->pixel].ref_count) /* got a duplicate */	    {	      XFreeColors (private->xdisplay, private->xcolormap,			   &ret->pixel, 1, 0);	    }	  else	    {	      colormap->colors[ret->pixel] = *color;	      colormap->colors[ret->pixel].pixel = ret->pixel;	      private->info[ret->pixel].ref_count = 1;	      g_hash_table_insert (private->hash,				   &colormap->colors[ret->pixel],				   &colormap->colors[ret->pixel]);	    }	}      return TRUE;    }  else    {      return FALSE;    }}static gintgdk_colormap_alloc_colors_writeable (GdkColormap *colormap,				     GdkColor    *colors,				     gint         ncolors,				     gboolean     writeable,				     gboolean     best_match,				     gboolean    *success){  GdkColormapPrivate *private;  gulong *pixels;  Status status;  gint i, index;  private = (GdkColormapPrivate*) colormap;  if (private->private_val)    {      index = 0;      for (i=0; i<ncolors; i++)	{	  while ((index < colormap->size) && (private->info[index].ref_count != 0))	    index++;	  	  if (index < colormap->size)	    {	      colors[i].pixel = index;	      success[i] = TRUE;	      private->info[index].ref_count++;	      private->info[i].flags |= GDK_COLOR_WRITEABLE;	    }	  else	    break;	}      return i;    }  else    {      pixels = g_new (gulong, ncolors);      /* Allocation of a writeable color cells */            status =  XAllocColorCells (private->xdisplay, private->xcolormap,				  FALSE, NULL, 0, pixels, ncolors);      if (status)	{	  for (i=0; i<ncolors; i++)	    {	      colors[i].pixel = pixels[i];	      private->info[pixels[i]].ref_count++;	      private->info[pixels[i]].flags |= GDK_COLOR_WRITEABLE;	    }	}            g_free (pixels);      return status ? ncolors : 0;     }}static gintgdk_colormap_alloc_colors_private (GdkColormap *colormap,				   GdkColor    *colors,				   gint         ncolors,				   gboolean     writeable,				   gboolean     best_match,				   gboolean    *success){  GdkColormapPrivate *private;  gint i, index;  XColor *store = g_new (XColor, ncolors);  gint nstore = 0;  gint nremaining = 0;    private = (GdkColormapPrivate*) colormap;  index = -1;  /* First, store the colors we have room for */  index = 0;  for (i=0; i<ncolors; i++)    {      if (!success[i])	{	  while ((index < colormap->size) && (private->info[index].ref_count != 0))	    index++;	  if (index < colormap->size)	    {	      store[nstore].red = colors[i].red;	      store[nstore].blue = colors[i].blue;	      store[nstore].green = colors[i].green;	      store[nstore].pixel = index;	      nstore++;	      success[i] = TRUE;	      colors[i].pixel = index;	      private->info[index].ref_count++;	    }	  else	    nremaining++;	}    }    XStoreColors (private->xdisplay, private->xcolormap, store, nstore);  g_free (store);  if (nremaining > 0 && best_match)    {      /* Get best matches for remaining colors */      gchar *available = g_new (gchar, colormap->size);      for (i = 0; i < colormap->size; i++)	available[i] = TRUE;      for (i=0; i<ncolors; i++)	{	  if (!success[i])	    {	      index = gdk_colormap_match_color (colormap, 						&colors[i], 						available);	      if (index != -1)		{		  colors[i] = colormap->colors[index];		  private->info[index].ref_count++;		  success[i] = TRUE;		  nremaining--;		}	    }	}      g_free (available);    }  return (ncolors - nremaining);}static gintgdk_colormap_alloc_colors_shared (GdkColormap *colormap,				  GdkColor    *colors,				  gint         ncolors,				  gboolean     writeable,				  gboolean     best_match,				  gboolean    *success){  GdkColormapPrivate *private;  gint i, index;  gint nremaining = 0;  gint nfailed = 0;  private = (GdkColormapPrivate*) colormap;  index = -1;  for (i=0; i<ncolors; i++)    {      if (!success[i])	{	  if (gdk_colormap_alloc1 (colormap, &colors[i], &colors[i]))	    success[i] = TRUE;	  else	    nremaining++;	}    }  if (nremaining > 0 && best_match)    {      gchar *available = g_new (gchar, colormap->size);      for (i = 0; i < colormap->size; i++)	available[i] = ((private->info[i].ref_count == 0) ||			!(private->info[i].flags && GDK_COLOR_WRITEABLE));      gdk_colormap_sync (colormap, FALSE);            while (nremaining > 0)	{	  for (i=0; i<ncolors; i++)	    {	      if (!success[i])		{		  index = gdk_colormap_match_color (colormap, &colors[i], available);		  if (index != -1)		    {		      if (private->info[index].ref_count)			{			  private->info[index].ref_count++;			  colors[i] = colormap->colors[index];			  success[i] = TRUE;			  nremaining--;			}		      else			{			  if (gdk_colormap_alloc1 (colormap, 						   &colormap->colors[index],						   &colors[i]))			    {			      success[i] = TRUE;			      nremaining--;			      break;			    }			  else			    {			      available[index] = FALSE;			    }			}		    }		  else		    {		      nfailed++;		      nremaining--;		      success[i] = 2; /* flag as permanent failure */		    }		}	    }	}      g_free (available);    }  /* Change back the values we flagged as permanent failures */  if (nfailed > 0)    {      for (i=0; i<ncolors; i++)	if (success[i] == 2)	  success[i] = FALSE;      nremaining = nfailed;    }    return (ncolors - nremaining);}static gintgdk_colormap_alloc_colors_pseudocolor (GdkColormap *colormap,				       GdkColor    *colors,				       gint         ncolors,				       gboolean     writeable,				       gboolean     best_match,				       gboolean    *success){  GdkColormapPrivate *private;  GdkColor *lookup_color;  gint i;  gint nremaining = 0;  private = (GdkColormapPrivate*) colormap;  /* Check for an exact match among previously allocated colors */  for (i=0; i<ncolors; i++)    {      if (!success[i])	{	  lookup_color = g_hash_table_lookup (private->hash, &colors[i]);	  if (lookup_color)	    {	      private->info[lookup_color->pixel].ref_count++;	      colors[i].pixel = lookup_color->pixel;	      success[i] = TRUE;	    }	  else	    nremaining++;	}    }  /* If that failed, we try to allocate a new color, or approxmiate   * with what we can get if best_match is TRUE.   */  if (nremaining > 0)    {      if (private->private_val)	return gdk_colormap_alloc_colors_private (colormap, colors, ncolors, writeable, best_match, success);      else	return gdk_colormap_alloc_colors_shared (colormap, colors, ncolors, writeable, best_match, success);    }  else    return 0;}gintgdk_colormap_alloc_colors (GdkColormap *colormap,			   GdkColor    *colors,			   gint         ncolors,			   gboolean     writeable,			   gboolean     best_match,			   gboolean    *success){  GdkColormapPrivate *private;  GdkVisual *visual;  gint i;  gint nremaining = 0;  XColor xcolor;  g_return_val_if_fail (colormap != NULL, FALSE);  g_return_val_if_fail (colors != NULL, FALSE);  private = (GdkColormapPrivate*) colormap;  for (i=0; i<ncolors; i++)    {      success[i] = FALSE;    }  switch (private->visual->type)    {    case GDK_VISUAL_PSEUDO_COLOR:    case GDK_VISUAL_GRAYSCALE:      if (writeable)	return gdk_colormap_alloc_colors_writeable (colormap, colors, ncolors,						    writeable, best_match, success);      else	return gdk_colormap_alloc_colors_pseudocolor (colormap, colors, ncolors,						    writeable, best_match, success);      break;    case GDK_VISUAL_DIRECT_COLOR:    case GDK_VISUAL_TRUE_COLOR:      visual = private->visual;      for (i=0; i<ncolors; i++)	{	  colors[i].pixel = (((colors[i].red >> (16 - visual->red_prec)) << visual->red_shift) +			     ((colors[i].green >> (16 - visual->green_prec)) << visual->green_shift) +			     ((colors[i].blue >> (16 - visual->blue_prec)) << visual->blue_shift));	  success[i] = TRUE;	}      break;    case GDK_VISUAL_STATIC_GRAY:    case GDK_VISUAL_STATIC_COLOR:      for (i=0; i<ncolors; i++)	{	  xcolor.red = colors[i].red;	  xcolor.green = colors[i].green;	  xcolor.blue = colors[i].blue;	  xcolor.pixel = colors[i].pixel;	  xcolor.flags = DoRed | DoGreen | DoBlue;	  if (XAllocColor (private->xdisplay, private->xcolormap, &xcolor))	    {	      colors[i].pixel = xcolor.pixel;	      success[i] = TRUE;	    }	  else	    nremaining++;	}      break;    }  return nremaining;}gbooleangdk_colormap_alloc_color (GdkColormap *colormap,			  GdkColor    *color,			  gboolean     writeable,			  gboolean     best_match){  gboolean success;  gdk_colormap_alloc_colors (colormap, color, 1, writeable, best_match,			     &success);  return success;}gbooleangdk_color_alloc (GdkColormap *colormap,		 GdkColor    *color){  gboolean success;  gdk_colormap_alloc_colors (colormap, color, 1, FALSE, TRUE, &success);  return success;}gbooleangdk_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;}guintgdk_color_hash (const GdkColor *colora,		const GdkColor *colorb){  return ((colora->red) +	  (colora->green << 11) +	  (colora->blue << 22) +	  (colora->blue >> 6));}gintgdk_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));}/* XXX: Do not use this function until it is fixed. An X Colormap *      is useless unless we also have the visual. */GdkColormap*gdkx_colormap_get (Colormap xcolormap){  GdkColormap *colormap;  GdkColormapPrivate *private;  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;  /* To do the following safely, we would have to have some way of finding   * out what the size or visual of the given colormap is. It seems   * X doesn't allow this   */#if 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;    }#endif  colormap->colors = NULL;  colormap->size = 0;  gdk_colormap_add (colormap);  return colormap;}static gintgdk_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 < cmap->size; 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 voidgdk_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 voidgdk_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 guintgdk_colormap_hash (Colormap *cmap){  return *cmap;}static gintgdk_colormap_cmp (Colormap *a,		  Colormap *b){  return (*a == *b);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -