📄 tkcolor.c
字号:
tkColPtr = (TkColor *) ckalloc(sizeof(TkColor)); tkColPtr->color.red = valueKey.red; tkColPtr->color.green = valueKey.green; tkColPtr->color.blue = valueKey.blue; if (Tk_GetColorModel(tkwin) != TK_COLOR) { useMonoApproximation: if ((((int) tkColPtr->color.red) + ((int) tkColPtr->color.green) + ((int) tkColPtr->color.blue)) > (3*65535)/2) { tkColPtr->color.pixel = WhitePixelOfScreen(Tk_Screen(tkwin)); } else { tkColPtr->color.pixel = BlackPixelOfScreen(Tk_Screen(tkwin)); } } else { if (XAllocColor(Tk_Display(tkwin), colormap, &tkColPtr->color) == 0) { Tk_SetColorModel(tkwin, TK_MONO); Tcl_AppendResult(interp, "no more colors left in colormap; ", "changing screen's color model to monochrome", (char *) NULL); Tcl_AddErrorInfo(interp, "\n (while allocating color in Tk_GetColorByValue)"); Tk_BackgroundError(interp); goto useMonoApproximation; } } tkColPtr->magic = COLOR_MAGIC; tkColPtr->screen = Tk_Screen(tkwin); tkColPtr->colormap = colormap; tkColPtr->visual = Tk_Visual(tkwin); tkColPtr->refCount = 1; tkColPtr->tablePtr = &valueTable; tkColPtr->hashPtr = valueHashPtr; Tcl_SetHashValue(valueHashPtr, tkColPtr); return &tkColPtr->color;}/* *-------------------------------------------------------------- * * Tk_NameOfColor -- * * Given a color, return a textual string identifying * the color. * * Results: * If colorPtr was created by Tk_GetColor, then the return * value is the "string" that was used to create it. * Otherwise the return value is a string that could have * been passed to Tk_GetColor to allocate that color. The * storage for the returned string is only guaranteed to * persist up until the next call to this procedure. * * Side effects: * None. * *-------------------------------------------------------------- */char *Tk_NameOfColor(colorPtr) XColor *colorPtr; /* Color whose name is desired. */{ register TkColor *tkColPtr = (TkColor *) colorPtr; static char string[20]; if ((tkColPtr->magic == COLOR_MAGIC) && (tkColPtr->tablePtr == &nameTable)) { return ((NameKey *) tkColPtr->hashPtr->key.words)->name; } sprintf(string, "#%4x%4x%4x", colorPtr->red, colorPtr->green, colorPtr->blue); return string;}/* *---------------------------------------------------------------------- * * Tk_FreeColor -- * * This procedure is called to release a color allocated by * Tk_GetColor. * * Results: * None. * * Side effects: * The reference count associated with colorPtr is deleted, and * the color is released to X if there are no remaining uses * for it. * *---------------------------------------------------------------------- */voidTk_FreeColor(colorPtr) XColor *colorPtr; /* Color to be released. Must have been * allocated by Tk_GetColor or * Tk_GetColorByValue. */{ register TkColor *tkColPtr = (TkColor *) colorPtr; Visual *visual; Screen *screen = tkColPtr->screen; /* * Do a quick sanity check to make sure this color was really * allocated by Tk_GetColor. */ if (tkColPtr->magic != COLOR_MAGIC) { panic("Tk_FreeColor called with bogus color"); } tkColPtr->refCount--; if (tkColPtr->refCount == 0) { /* * Careful! Don't free black or white, since this will * make some servers very unhappy. Also, there is a bug in * some servers (such Sun's X11/NeWS server) where reference * counting is performed incorrectly, so that if a color is * allocated twice in different places and then freed twice, * the second free generates an error (this bug existed as of * 10/1/92). To get around this problem, ignore errors that * occur during the free operation. */ visual = tkColPtr->visual; if ((visual->class != StaticGray) && (visual->class != StaticColor) && (tkColPtr->color.pixel != BlackPixelOfScreen(screen)) && (tkColPtr->color.pixel != WhitePixelOfScreen(screen))) { Tk_ErrorHandler handler; handler = Tk_CreateErrorHandler(DisplayOfScreen(screen), -1, -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); XFreeColors(DisplayOfScreen(screen), tkColPtr->colormap, &tkColPtr->color.pixel, 1, 0L); Tk_DeleteErrorHandler(handler); } Tcl_DeleteHashEntry(tkColPtr->hashPtr); tkColPtr->magic = 0; ckfree((char *) tkColPtr); }}/* *---------------------------------------------------------------------- * * ColorInit -- * * Initialize the structure used for color management. * * Results: * None. * * Side effects: * Read the code. * *---------------------------------------------------------------------- */static voidColorInit(){ initialized = 1; Tcl_InitHashTable(&nameTable, sizeof(NameKey)/sizeof(int)); Tcl_InitHashTable(&valueTable, sizeof(ValueKey)/sizeof(int));}#include "feather.h"Feather_Color Feather_GetColor( interp, tkwin, colormap, name ) Tcl_Interp *interp; /* Place to leave error message if * color can't be found. */ Tk_Window tkwin; /* Window in which color will be used. */ Colormap colormap; /* Map from which to allocate color. None * means use current colormap for tkwin. */ Tk_Uid name; /* Name of color to allocated (in form * suitable for passing to XParseColor). */{ NameKey nameKey; Tcl_HashEntry *nameHashPtr; int new; TkColor *tkColPtr; XColor color; if (!initialized) { ColorInit(); } /* * First, check to see if there's already a mapping for this color * name. */ nameKey.name = name; if (colormap == None) { colormap = Tk_Colormap(tkwin); } nameKey.colormap = colormap; nameKey.display = Tk_Display(tkwin); nameHashPtr = Tcl_CreateHashEntry(&nameTable, (char *) &nameKey, &new); if (!new) { tkColPtr = (TkColor *) Tcl_GetHashValue(nameHashPtr); tkColPtr->refCount++; return (Feather_Color)tkColPtr; } /* * The name isn't currently known. Map from the name to a pixel * value. There are several tricks here: * * 1. Call XAllocNamedColor rather than XParseColor for non-# names: * this saves a server round-trip for those names. * 2. If the display is supposed to be treated as mono, then look * up the color value and translate to mono. * 3. If a color allocation fails, then reset the display's color model * to mono, generate an error message, and retry with the mono * approach. */ if (*name != '#') { XColor screen; if (Tk_GetColorModel(tkwin) != TK_COLOR) { if (XLookupColor(Tk_Display(tkwin), colormap, name, &color, &screen) == 0) { badColorName: Tcl_AppendResult(interp, "unknown color name \"", name, "\"", (char *) NULL); Tcl_DeleteHashEntry(nameHashPtr); return (Feather_Color)0; } goto useMonoApproximation; } if (XAllocNamedColor(Tk_Display(tkwin), colormap, name, &screen, &color) == 0) { char message[120]; /* * Couldn't allocate the color. Try translating the name to * a color value, to see whether the problem is a bad color * name or a full colormap. If the colormap is full, then * put the display into mono mode and */ if (XLookupColor(Tk_Display(tkwin), colormap, name, &color, &screen) == 0) { goto badColorName; } outOfColors: Tk_SetColorModel(tkwin, TK_MONO); Tcl_AppendResult(interp, "no more colors left in colormap; ", "changing screen's color model to monochrome", (char *) NULL); sprintf(message, "\n (while allocating color \"%.50s\")", name); Tcl_AddErrorInfo(interp, message); Tk_BackgroundError(interp); goto useMonoApproximation; } } else { if (XParseColor(Tk_Display(tkwin), colormap, name, &color) == 0) { Tcl_AppendResult(interp, "invalid color name \"", name, "\"", (char *) NULL); Tcl_DeleteHashEntry(nameHashPtr); return (Feather_Color)0; } if (Tk_GetColorModel(tkwin) != TK_COLOR) { useMonoApproximation: if ((((int) color.red) + ((int) color.green) + ((int) color.blue)) > (3*65535)/2) { color.pixel = WhitePixelOfScreen(Tk_Screen(tkwin)); } else { color.pixel = BlackPixelOfScreen(Tk_Screen(tkwin)); } } else if (XAllocColor(Tk_Display(tkwin), colormap, &color) == 0) { goto outOfColors; } } /* * Now create a new TkColor structure and add it to nameTable. */ tkColPtr = (TkColor *) ckalloc(sizeof(TkColor)); tkColPtr->color = color; tkColPtr->magic = COLOR_MAGIC; tkColPtr->screen = Tk_Screen(tkwin); tkColPtr->colormap = colormap; tkColPtr->visual = Tk_Visual(tkwin); tkColPtr->refCount = 1; tkColPtr->tablePtr = &nameTable; tkColPtr->hashPtr = nameHashPtr; Tcl_SetHashValue(nameHashPtr, tkColPtr); return (Feather_Color)tkColPtr;}XColor *Feather_UseColor( colorVoid )Feather_Color colorVoid;{ TkColor *tkColPtr; tkColPtr = (TkColor*)colorVoid; if (!tkColPtr) return (XColor*)0; tkColPtr->refCount++; return &tkColPtr->color;}void Feather_FreeColor( colorVoid )Feather_Color colorVoid;{ TkColor *tkColPtr; tkColPtr = (TkColor*)colorVoid; if (tkColPtr) Tk_FreeColor( &tkColPtr->color );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -