📄 gdkcolor-x11.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 Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser 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. *//* * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <config.h>#include <time.h>#include "gdkcolor.h"#include "gdkinternals.h"#include "gdkx.h"#include "gdkprivate-x11.h"#include "gdkscreen-x11.h"#include "gdkalias.h"typedef struct _GdkColormapPrivateX11 GdkColormapPrivateX11;struct _GdkColormapPrivateX11{ GdkScreen *screen; Colormap xcolormap; gint private_val; GHashTable *hash; GdkColorInfo *info; time_t last_sync_time; guint foreign : 1;};#define GDK_COLORMAP_PRIVATE_DATA(cmap) ((GdkColormapPrivateX11 *) GDK_COLORMAP (cmap)->windowing_data)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 GdkColormap *gdk_colormap_lookup (GdkScreen *screen, Colormap xcolormap);static guint gdk_colormap_hash (Colormap *cmap);static gboolean gdk_colormap_equal (Colormap *a, Colormap *b);static void gdk_colormap_sync (GdkColormap *colormap, gboolean force);static void gdk_colormap_init (GdkColormap *colormap);static void gdk_colormap_class_init (GdkColormapClass *klass);static void gdk_colormap_finalize (GObject *object);static gpointer parent_class = NULL;GTypegdk_colormap_get_type (void){ static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (GdkColormapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gdk_colormap_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GdkColormap), 0, /* n_preallocs */ (GInstanceInitFunc) gdk_colormap_init, }; object_type = g_type_register_static (G_TYPE_OBJECT, "GdkColormap", &object_info, 0); } return object_type;}static voidgdk_colormap_init (GdkColormap *colormap){ GdkColormapPrivateX11 *private; private = g_new (GdkColormapPrivateX11, 1); colormap->windowing_data = private; private->screen = NULL; private->hash = NULL; private->last_sync_time = 0; private->info = NULL; colormap->size = 0; colormap->colors = NULL;}static voidgdk_colormap_class_init (GdkColormapClass *klass){ GObjectClass *object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->finalize = gdk_colormap_finalize;}static voidgdk_colormap_finalize (GObject *object){ GdkColormap *colormap = GDK_COLORMAP (object); GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap); gdk_colormap_remove (colormap); if (!private->screen->closed) XFreeColormap (GDK_SCREEN_XDISPLAY (private->screen), private->xcolormap); if (private->hash) g_hash_table_destroy (private->hash); g_free (private->info); g_free (colormap->colors); g_free (private); G_OBJECT_CLASS (parent_class)->finalize (object);}/** * gdk_colormap_new: * @visual: a #GdkVisual. * @allocate: if %TRUE, the newly created colormap will be * a private colormap, and all colors in it will be * allocated for the applications use. * * Creates a new colormap for the given visual. * * Return value: the new #GdkColormap. **/GdkColormap*gdk_colormap_new (GdkVisual *visual, gboolean allocate){ GdkColormap *colormap; GdkColormapPrivateX11 *private; Visual *xvisual; Display *xdisplay; Window xrootwin; int size; int i; /* FIXME when object properties settle down, there needs to be some * kind of default construction (and construct-only arguments) */ g_return_val_if_fail (GDK_IS_VISUAL (visual), NULL); colormap = g_object_new (GDK_TYPE_COLORMAP, NULL); private = GDK_COLORMAP_PRIVATE_DATA (colormap); colormap->visual = visual; private->screen = gdk_visual_get_screen (visual); xvisual = ((GdkVisualPrivate*) visual)->xvisual; xdisplay = GDK_SCREEN_XDISPLAY (private->screen); xrootwin = GDK_SCREEN_XROOTWIN (private->screen); colormap->size = visual->colormap_size; switch (visual->type) { case GDK_VISUAL_GRAYSCALE: case GDK_VISUAL_PSEUDO_COLOR: private->info = g_new0 (GdkColorInfo, colormap->size); colormap->colors = g_new (GdkColor, colormap->size); private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash, (GEqualFunc) gdk_color_equal); private->private_val = allocate; private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, (allocate) ? (AllocAll) : (AllocNone)); if (allocate) { GdkVisual *system_visual; XColor *default_colors; gint n_default_colors; system_visual = gdk_screen_get_system_visual (private->screen); n_default_colors = MIN (system_visual->colormap_size, colormap->size); default_colors = g_new (XColor, colormap->size); for (i = 0; i < n_default_colors; i++) default_colors[i].pixel = i; XQueryColors (xdisplay, DefaultColormapOfScreen (GDK_SCREEN_X11 (private->screen)->xscreen), default_colors, n_default_colors); for (i = 0; i < n_default_colors; 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, n_default_colors); g_free (default_colors); } break; case GDK_VISUAL_DIRECT_COLOR: private->private_val = TRUE; private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, AllocAll); colormap->colors = g_new (GdkColor, colormap->size); 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, colormap->size); break; case GDK_VISUAL_STATIC_GRAY: case GDK_VISUAL_STATIC_COLOR: private->private_val = FALSE; private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, AllocNone); colormap->colors = g_new (GdkColor, colormap->size); gdk_colormap_sync (colormap, TRUE); break; case GDK_VISUAL_TRUE_COLOR: private->private_val = FALSE; private->xcolormap = XCreateColormap (xdisplay, xrootwin, xvisual, AllocNone); break; } gdk_colormap_add (colormap); return colormap;}static voidgdk_colormap_sync_palette (GdkColormap *colormap){ GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap); XColor *xpalette; gint nlookup; gint i; nlookup = 0; xpalette = g_new (XColor, colormap->size); for (i = 0; i < colormap->size; i++) { if (!private->info || private->info[i].ref_count == 0) { xpalette[nlookup].pixel = i; xpalette[nlookup].red = 0; xpalette[nlookup].green = 0; xpalette[nlookup].blue = 0; nlookup++; } } XQueryColors (GDK_SCREEN_XDISPLAY (private->screen), private->xcolormap, xpalette, nlookup); for (i = 0; i < nlookup; i++) { gulong pixel = xpalette[i].pixel; colormap->colors[pixel].pixel = pixel; colormap->colors[pixel].red = xpalette[i].red; colormap->colors[pixel].green = xpalette[i].green; colormap->colors[pixel].blue = xpalette[i].blue; } g_free (xpalette);}static voidgdk_colormap_sync_direct_color (GdkColormap *colormap){ GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap); GdkVisual *visual = colormap->visual; XColor *xpalette; gint i; xpalette = g_new (XColor, colormap->size); for (i = 0; i < colormap->size; i++) { xpalette[i].pixel = (((i << visual->red_shift) & visual->red_mask) | ((i << visual->green_shift) & visual->green_mask) | ((i << visual->blue_shift) & visual->blue_mask)); } XQueryColors (GDK_SCREEN_XDISPLAY (private->screen), private->xcolormap, xpalette, colormap->size); for (i = 0; i < colormap->size; 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; } g_free (xpalette);}#define MIN_SYNC_TIME 2static voidgdk_colormap_sync (GdkColormap *colormap, gboolean force){ time_t current_time; GdkColormapPrivateX11 *private = GDK_COLORMAP_PRIVATE_DATA (colormap); g_return_if_fail (GDK_IS_COLORMAP (colormap)); if (private->screen->closed) return; current_time = time (NULL); if (!force && ((current_time - private->last_sync_time) < MIN_SYNC_TIME)) return; private->last_sync_time = current_time; if (colormap->visual->type == GDK_VISUAL_DIRECT_COLOR) gdk_colormap_sync_direct_color (colormap); else gdk_colormap_sync_palette (colormap);} /** * gdk_screen_get_system_colormap: * @screen: a #GdkScreen * * Gets the system's default colormap for @screen * * Returns: the default colormap for @screen. * * Since: 2.2 */GdkColormap *gdk_screen_get_system_colormap (GdkScreen *screen){ GdkColormap *colormap = NULL; GdkColormapPrivateX11 *private; GdkScreenX11 *screen_x11; g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); screen_x11 = GDK_SCREEN_X11 (screen); if (screen_x11->system_colormap) return screen_x11->system_colormap; colormap = g_object_new (GDK_TYPE_COLORMAP, NULL); private = GDK_COLORMAP_PRIVATE_DATA (colormap); private->screen = screen; colormap->visual = gdk_screen_get_system_visual (screen); private->xcolormap = DefaultColormapOfScreen (screen_x11->xscreen); private->private_val = FALSE; private->hash = NULL; private->last_sync_time = 0; private->info = NULL; colormap->colors = NULL; colormap->size = colormap->visual->colormap_size; switch (colormap->visual->type) { case GDK_VISUAL_GRAYSCALE: case GDK_VISUAL_PSEUDO_COLOR: private->info = g_new0 (GdkColorInfo, colormap->size); private->hash = g_hash_table_new ((GHashFunc) gdk_color_hash, (GEqualFunc) gdk_color_equal); /* Fall through */ case GDK_VISUAL_STATIC_GRAY: case GDK_VISUAL_STATIC_COLOR: case GDK_VISUAL_DIRECT_COLOR: colormap->colors = g_new (GdkColor, colormap->size); gdk_colormap_sync (colormap, TRUE); case GDK_VISUAL_TRUE_COLOR: break; } gdk_colormap_add (colormap); screen_x11->system_colormap = colormap; return colormap;}/** * gdk_colormap_get_system_size: * * Returns the size of the system's default colormap. * (See the description of struct #GdkColormap for an * explanation of the size of a colormap.) * * Return value: the size of the system's default colormap. **/gintgdk_colormap_get_system_size (void){ return DisplayCells (GDK_SCREEN_XDISPLAY (gdk_screen_get_default()), GDK_SCREEN_X11 (gdk_screen_get_default())->screen_num);}/** * gdk_colormap_change: * @colormap: a #GdkColormap. * @ncolors: the number of colors to change. * * Changes the value of the first @ncolors in a private colormap * to match the values in the <structfield>colors</structfield> * array in the colormap. This function is obsolete and * should not be used. See gdk_color_change(). **/voidgdk_colormap_change (GdkColormap *colormap, gint ncolors){ GdkColormapPrivateX11 *private; GdkVisual *visual; XColor *palette; Display *xdisplay; gint shift; int max_colors; int size; int i; g_return_if_fail (GDK_IS_COLORMAP (colormap)); private = GDK_COLORMAP_PRIVATE_DATA (colormap); if (private->screen->closed) return; xdisplay = GDK_SCREEN_XDISPLAY (private->screen); palette = g_new (XColor, ncolors); switch (colormap->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 (xdisplay, private->xcolormap, palette, ncolors); break; case GDK_VISUAL_DIRECT_COLOR: visual = colormap->visual; shift = visual->red_shift; max_colors = 1 << visual->red_prec; size = (ncolors < max_colors) ? (ncolors) : (max_colors);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -