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

📄 gdkcc.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* Color Context module * Copyright 1994,1995 John L. Cwikla * Copyright (C) 1997 by Ripley Software Development * Copyright (C) 1997 by Federico Mena (port to Gtk/Gdk) *//* Copyright 1994,1995 John L. Cwikla * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation, and that the name of John L. Cwikla or * Wolfram Research, Inc not be used in advertising or publicity * pertaining to distribution of the software without specific, written * prior permission.  John L. Cwikla and Wolfram Research, Inc make no * representations about the suitability of this software for any * purpose.  It is provided "as is" without express or implied warranty. * * John L. Cwikla and Wolfram Research, Inc disclaim all warranties with * regard to this software, including all implied warranties of * merchantability and fitness, in no event shall John L. Cwikla or * Wolfram Research, Inc be liable for any special, indirect or * consequential damages or any damages whatsoever resulting from loss of * use, data or profits, whether in an action of contract, negligence or * other tortious action, arising out of or in connection with the use or * performance of this software. * * Author: *  John L. Cwikla *  X Programmer *  Wolfram Research Inc. * *  cwikla@wri.com *//* * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS * file for a list of people on the GTK+ Team.  See the ChangeLog * files for a list of changes.  These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/.  */#include <X11/Xlib.h>#include <stdlib.h>#include <string.h>#include "gdk.h"#include "gdkprivate.h"#include "gdkx.h"#define MAX_IMAGE_COLORS 256static guinthash_color (gconstpointer key){  const GdkColor *color = key;    return (color->red * 33023 + color->green * 30013 + color->blue * 27011);}static gintcompare_colors (gconstpointer a,		gconstpointer b){  const GdkColor *aa = a;  const GdkColor *bb = b;    return ((aa->red == bb->red) && (aa->green == bb->green) && (aa->blue == bb->blue));}static voidfree_hash_entry (gpointer key,		 gpointer value,		 gpointer user_data){  g_free (key); /* key and value are the same GdkColor */}static intpixel_sort (const void *a, const void *b){  return ((GdkColor *) a)->pixel - ((GdkColor *) b)->pixel;}/* XXX: This function does an XQueryColors() the hard way, because there is * no corresponding function in Gdk. */static voidmy_x_query_colors (GdkColormap *colormap,		   GdkColor    *colors,		   gint         ncolors){  XColor *xcolors;  gint    i;    xcolors = g_new (XColor, ncolors);  for (i = 0; i < ncolors; i++)    xcolors[i].pixel = colors[i].pixel;    XQueryColors (gdk_display, GDK_COLORMAP_XCOLORMAP (colormap), xcolors, ncolors);    for (i = 0; i < ncolors; i++)    {      colors[i].red   = xcolors[i].red;      colors[i].green = xcolors[i].green;      colors[i].blue  = xcolors[i].blue;    }    g_free (xcolors);}static voidquery_colors (GdkColorContext *cc){  gint i;  GdkColorContextPrivate *ccp = (GdkColorContextPrivate *) cc;  cc->cmap = g_new (GdkColor, cc->num_colors);    for (i = 0; i < cc->num_colors; i++)    cc->cmap[i].pixel = cc->clut ? cc->clut[i] : ccp->std_cmap.base_pixel + i;    my_x_query_colors (cc->colormap, cc->cmap, cc->num_colors);    qsort (cc->cmap, cc->num_colors, sizeof (GdkColor), pixel_sort);}static voidinit_bw (GdkColorContext *cc){  GdkColor color;    g_warning ("init_bw: failed to allocate colors, falling back to black and white");    cc->mode = GDK_CC_MODE_BW;    color.red = color.green = color.blue = 0;    if (!gdk_color_alloc (cc->colormap, &color))    cc->black_pixel = 0;  else    cc->black_pixel = color.pixel;    color.red = color.green = color.blue = 0xffff;    if (!gdk_color_alloc (cc->colormap, &color))    cc->white_pixel = cc->black_pixel ? 0 : 1;  else    cc->white_pixel = color.pixel;    cc->num_colors = 2;}static voidinit_gray (GdkColorContext *cc){  GdkColorContextPrivate *ccp = (GdkColorContextPrivate *) cc;  GdkColor *clrs, *cstart;  gint i;  gdouble dinc;    cc->num_colors = GDK_VISUAL_XVISUAL (cc->visual)->map_entries;    cc->clut = g_new (gulong, cc->num_colors);  cstart = g_new (GdkColor, cc->num_colors);   retrygray:    dinc = 65535.0 / (cc->num_colors - 1);    clrs = cstart;    for (i = 0; i < cc->num_colors; i++)    {      clrs->red = clrs->green = clrs->blue = dinc * i;            if (!gdk_color_alloc (cc->colormap, clrs))	{	  gdk_colors_free (cc->colormap, cc->clut, i, 0);	  	  cc->num_colors /= 2;	  	  if (cc->num_colors > 1)	    goto retrygray;	  else	    {	      g_free (cc->clut);	      cc->clut = NULL;	      init_bw (cc);	      g_free (cstart);	      return;	    }	}            cc->clut[i] = clrs++->pixel;    }    g_free (cstart);    /* XXX: is this the right thing to do? */  ccp->std_cmap.colormap = GDK_COLORMAP_XCOLORMAP (cc->colormap);  ccp->std_cmap.base_pixel = 0;  ccp->std_cmap.red_max = cc->num_colors - 1;  ccp->std_cmap.green_max = 0;  ccp->std_cmap.blue_max = 0;  ccp->std_cmap.red_mult = 1;  ccp->std_cmap.green_mult = 0;  ccp->std_cmap.blue_mult = 0;    cc->white_pixel = WhitePixel (ccp->xdisplay, gdk_screen);  cc->black_pixel = BlackPixel (ccp->xdisplay, gdk_screen);    query_colors (cc);    cc->mode = GDK_CC_MODE_MY_GRAY;}static voidinit_color (GdkColorContext *cc){  GdkColorContextPrivate *ccp = (GdkColorContextPrivate *) cc;  gint cubeval;    cubeval = 1;  while ((cubeval * cubeval * cubeval) < GDK_VISUAL_XVISUAL (cc->visual)->map_entries)    cubeval++;  cubeval--;    cc->num_colors = cubeval * cubeval * cubeval;    ccp->std_cmap.red_max    = cubeval - 1;  ccp->std_cmap.green_max  = cubeval - 1;  ccp->std_cmap.blue_max   = cubeval - 1;  ccp->std_cmap.red_mult   = cubeval * cubeval;  ccp->std_cmap.green_mult = cubeval;  ccp->std_cmap.blue_mult  = 1;  ccp->std_cmap.base_pixel = 0;    cc->white_pixel = WhitePixel (ccp->xdisplay, gdk_screen);  cc->black_pixel = BlackPixel (ccp->xdisplay, gdk_screen);  cc->num_colors = DisplayCells (ccp->xdisplay, gdk_screen);    /* a CLUT for storing allocated pixel indices */    cc->max_colors = cc->num_colors;  cc->clut = g_new (gulong, cc->max_colors);    for (cubeval = 0; cubeval < cc->max_colors; cubeval++)    cc->clut[cubeval] = cubeval;    query_colors (cc);    cc->mode = GDK_CC_MODE_STD_CMAP;}static voidinit_true_color (GdkColorContext *cc){  GdkColorContextPrivate *ccp = (GdkColorContextPrivate *) cc;  gulong rmask, gmask, bmask;    cc->mode = GDK_CC_MODE_TRUE;    /* Red */    rmask = cc->masks.red = cc->visual->red_mask;    cc->shifts.red = 0;  cc->bits.red = 0;    while (!(rmask & 1))    {      rmask >>= 1;      cc->shifts.red++;    }    while (rmask & 1)    {      rmask >>= 1;      cc->bits.red++;    }    /* Green */    gmask = cc->masks.green = cc->visual->green_mask;    cc->shifts.green = 0;  cc->bits.green = 0;    while (!(gmask & 1))    {      gmask >>= 1;      cc->shifts.green++;    }    while (gmask & 1)    {      gmask >>= 1;      cc->bits.green++;    }    /* Blue */    bmask = cc->masks.blue = cc->visual->blue_mask;    cc->shifts.blue = 0;  cc->bits.blue = 0;    while (!(bmask & 1))    {      bmask >>= 1;      cc->shifts.blue++;    }    while (bmask & 1)    {      bmask >>= 1;      cc->bits.blue++;    }    cc->num_colors = (cc->visual->red_mask | cc->visual->green_mask | cc->visual->blue_mask) + 1;  cc->white_pixel = WhitePixel (ccp->xdisplay, gdk_screen);  cc->black_pixel = BlackPixel (ccp->xdisplay, gdk_screen);}static voidinit_direct_color (GdkColorContext *cc){  gint n, count;  GdkColor *clrs, *cstart;  gulong rval, gval, bval;  gulong *rtable;  gulong *gtable;  gulong *btable;  gdouble dinc;    init_true_color (cc); /* for shift stuff */    rval = cc->visual->red_mask >> cc->shifts.red;  gval = cc->visual->green_mask >> cc->shifts.green;  bval = cc->visual->blue_mask >> cc->shifts.blue;    rtable = g_new (gulong, rval + 1);  gtable = g_new (gulong, gval + 1);  btable = g_new (gulong, bval + 1);    cc->max_entry = MAX (rval, gval);  cc->max_entry = MAX (cc->max_entry, bval);    cstart = g_new (GdkColor, cc->max_entry + 1);  cc->clut = g_new (gulong, cc->max_entry + 1);   retrydirect:    for (n = 0; n < rval; n++)    rtable[n] = rval ? (65535.0 / rval * n) : 0;    for (n = 0; n < gval; n++)    gtable[n] = gval ? (65535.0 / gval * n) : 0;    for (n = 0; n < bval; n++)    btable[n] = bval ? (65535.0 / bval * n) : 0;    cc->max_entry = MAX (rval, gval);  cc->max_entry = MAX (cc->max_entry, bval);    count = 0;  clrs = cstart;  cc->num_colors = (rval + 1) * (gval + 1) * (bval + 1);    for (n = 0; n < cc->max_entry; n++)    {      dinc = (double) n / cc->max_entry;            clrs->red   = rtable[(int) (dinc * rval)];      clrs->green = gtable[(int) (dinc * gval)];      clrs->blue  = btable[(int) (dinc * bval)];            if (gdk_color_alloc (cc->colormap, clrs))	{	  cc->clut[count++] = clrs->pixel;	  clrs++;	}      else	{	  gdk_colors_free (cc->colormap, cc->clut, count, 0);	  	  rval >>= 1;	  gval >>= 1;	  bval >>= 1;	  	  cc->masks.red   = (cc->masks.red >> 1) & cc->visual->red_mask;	  cc->masks.green = (cc->masks.green >> 1) & cc->visual->green_mask;	  cc->masks.blue  = (cc->masks.blue >> 1) & cc->visual->blue_mask;	  	  cc->shifts.red++;	  cc->shifts.green++;	  cc->shifts.blue++;	  	  cc->bits.red--;	  cc->bits.green--;	  cc->bits.blue--;	  	  cc->num_colors = (rval + 1) * (gval + 1) * (bval + 1);	  	  if (cc->num_colors >1)	    goto retrydirect;	  else	    {	      g_free (cc->clut);	      cc->clut = NULL;	      init_bw (cc);	      break;	    }	}    }    /* Update allocated color count; original num_colors is max_entry, which   * is not necessarily the same as the really allocated number of colors.   */    cc->num_colors = count;    g_free (rtable);  g_free (gtable);  g_free (btable);  g_free (cstart);}static voidinit_palette (GdkColorContext *cc){  /* restore correct mode for this cc */    switch (cc->visual->type)    {    case GDK_VISUAL_STATIC_GRAY:    case GDK_VISUAL_GRAYSCALE:      if (GDK_VISUAL_XVISUAL (cc->visual)->map_entries == 2)	cc->mode = GDK_CC_MODE_BW;      else	cc->mode = GDK_CC_MODE_MY_GRAY;      break;          case GDK_VISUAL_TRUE_COLOR:    case GDK_VISUAL_DIRECT_COLOR:      cc->mode = GDK_CC_MODE_TRUE;      break;          case GDK_VISUAL_STATIC_COLOR:    case GDK_VISUAL_PSEUDO_COLOR:      cc->mode = GDK_CC_MODE_STD_CMAP;      break;          default:      cc->mode = GDK_CC_MODE_UNDEFINED;      break;    }    /* previous palette */    if (cc->num_palette)    g_free (cc->palette);    if (cc->fast_dither)    g_free (cc->fast_dither);    /* clear hash table if present */    if (cc->color_hash)    {      g_hash_table_foreach (cc->color_hash,			    free_hash_entry,			    NULL);      g_hash_table_destroy (cc->color_hash);      cc->color_hash = NULL;    }    cc->palette = NULL;  cc->num_palette = 0;  cc->fast_dither = NULL;}GdkColorContext *gdk_color_context_new (GdkVisual   *visual,		       GdkColormap *colormap){  GdkColorContextPrivate *ccp;  gint use_private_colormap = FALSE; /* XXX: maybe restore full functionality later? */  GdkColorContext *cc;  gint retry_count;  GdkColormap *default_colormap;    g_assert (visual != NULL);  g_assert (colormap != NULL);    ccp = g_new (GdkColorContextPrivate, 1);  cc = (GdkColorContext *) ccp;  ccp->xdisplay = gdk_display;  cc->visual = visual;  cc->colormap = colormap;  cc->clut = NULL;  cc->cmap = NULL;  cc->mode = GDK_CC_MODE_UNDEFINED;  cc->need_to_free_colormap = FALSE;    cc->color_hash = NULL;  cc->palette = NULL;  cc->num_palette = 0;  cc->fast_dither = NULL;    default_colormap = gdk_colormap_get_system ();    retry_count = 0;    while (retry_count < 2)    {      /* Only create a private colormap if the visual found isn't equal       * to the default visual and we don't have a private colormap,       * -or- if we are instructed to create a private colormap (which       * never is the case for XmHTML).       */            if (use_private_colormap	  || ((cc->visual != gdk_visual_get_system ()) /* default visual? */	      && (GDK_COLORMAP_XCOLORMAP (colormap) == GDK_COLORMAP_XCOLORMAP (default_colormap))))	{	  g_warning ("gdk_color_context_new: non-default visual detected, "		     "using private colormap");	  	  cc->colormap = gdk_colormap_new (cc->visual, FALSE);	  	  cc->need_to_free_colormap = (GDK_COLORMAP_XCOLORMAP (colormap)				       != GDK_COLORMAP_XCOLORMAP (default_colormap));	}            switch (visual->type)	{	case GDK_VISUAL_STATIC_GRAY:	case GDK_VISUAL_GRAYSCALE:	  GDK_NOTE (COLOR_CONTEXT,		    g_message ("gdk_color_context_new: visual class is %s\n",			       (visual->type == GDK_VISUAL_STATIC_GRAY) ?			       "GDK_VISUAL_STATIC_GRAY" :			       "GDK_VISUAL_GRAYSCALE"));	  	  if (GDK_VISUAL_XVISUAL (cc->visual)->map_entries == 2)	    init_bw (cc);	  else	    init_gray (cc);

⌨️ 快捷键说明

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