int ColorModel::command(int argc, const char*const* argv) { Tcl& tcl = Tcl::instance(); if (argc == 2) { if (strcmp(argv[1], "alloc-colors") == 0) { tcl.result(allocate() < 0 ? "0" : "1"); return (TCL_OK); } if (strcmp(argv[1], "free-colors") == 0) { free_colors(); return (TCL_OK); } } else if (argc == 3) { if (strcmp(argv[1], "visual") == 0) { Tk_Window tk = Tk_NameToWindow(tcl.interp(), (char*)argv[2], tcl.tkmain()); setvisual(Tk_Visual(tk), Tk_Colormap(tk), Tk_Depth(tk)); return (TCL_OK); } if (strcmp(argv[1], "gamma") == 0) { double v = atof(argv[2]); if (v < 0) tcl.result("0"); gamma_ = v; tcl.result("1"); return (TCL_OK); } } return (TclObject::command(argc, argv)); }
XColor * Tk_GetColorByValue( Tk_Window tkwin, /* Window where color will be used. */ XColor *colorPtr) /* Red, green, and blue fields indicate * desired color. */ { ValueKey valueKey; Tcl_HashEntry *valueHashPtr; int isNew; TkColor *tkColPtr; Display *display = Tk_Display(tkwin); TkDisplay *dispPtr = TkGetDisplay(display); if (!dispPtr->colorInit) { ColorInit(dispPtr); } /* * First, check to see if there's already a mapping for this color name. * Must clear the structure first; it's not tightly packed on 64-bit * systems. [Bug 2911570] */ memset(&valueKey, 0, sizeof(ValueKey)); valueKey.red = colorPtr->red; valueKey.green = colorPtr->green; valueKey.blue = colorPtr->blue; valueKey.colormap = Tk_Colormap(tkwin); valueKey.display = display; valueHashPtr = Tcl_CreateHashEntry(&dispPtr->colorValueTable, (char *) &valueKey, &isNew); if (!isNew) { tkColPtr = Tcl_GetHashValue(valueHashPtr); tkColPtr->resourceRefCount++; return &tkColPtr->color; } /* * The name isn't currently known. Find a pixel value for this color and * add a new structure to colorValueTable (in TkDisplay). */ tkColPtr = TkpGetColorByValue(tkwin, colorPtr); tkColPtr->magic = COLOR_MAGIC; tkColPtr->gc = None; tkColPtr->screen = Tk_Screen(tkwin); tkColPtr->colormap = valueKey.colormap; tkColPtr->visual = Tk_Visual(tkwin); tkColPtr->resourceRefCount = 1; tkColPtr->objRefCount = 0; tkColPtr->type = TK_COLOR_BY_VALUE; tkColPtr->hashPtr = valueHashPtr; tkColPtr->nextPtr = NULL; Tcl_SetHashValue(valueHashPtr, tkColPtr); return &tkColPtr->color; }
int JvDecoder::setcolors(int ncolors) { int mono = 0; if (JvsColormap(server_, ":0", Tk_Colormap(Tcl::instance().tkmain()), &ncolors, mono) < 0) { fprintf(stderr, "vic: JvsColormap failed\n"); /*XXX*/ exit(1); } return (ncolors); }
XColor * Tk_AllocColorFromObj( Tcl_Interp *interp, /* Used only for error reporting. If NULL, * then no messages are provided. */ Tk_Window tkwin, /* Window in which the color will be used.*/ Tcl_Obj *objPtr) /* Object that describes the color; string * value is a color name such as "red" or * "#ff0000".*/ { TkColor *tkColPtr; if (objPtr->typePtr != &tkColorObjType) { InitColorObj(objPtr); } tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; /* * If the object currently points to a TkColor, see if it's the one we * want. If so, increment its reference count and return. */ if (tkColPtr != NULL) { if (tkColPtr->resourceRefCount == 0) { /* * This is a stale reference: it refers to a TkColor that's no * longer in use. Clear the reference. */ FreeColorObjProc(objPtr); tkColPtr = NULL; } else if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { tkColPtr->resourceRefCount++; return (XColor *) tkColPtr; } } /* * The object didn't point to the TkColor that we wanted. Search the list * of TkColors with the same name to see if one of the other TkColors is * the right one. */ if (tkColPtr != NULL) { TkColor *firstColorPtr = Tcl_GetHashValue(tkColPtr->hashPtr); FreeColorObjProc(objPtr); for (tkColPtr = firstColorPtr; tkColPtr != NULL; tkColPtr = tkColPtr->nextPtr) { if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { tkColPtr->resourceRefCount++; tkColPtr->objRefCount++; objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; return (XColor *) tkColPtr; } } } /* * Still no luck. Call Tk_GetColor to allocate a new TkColor object. */ tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr)); objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; if (tkColPtr != NULL) { tkColPtr->objRefCount++; } return (XColor *) tkColPtr; }
XColor * Tk_GetColorFromObj( Tk_Window tkwin, /* The window in which the color will be * used. */ Tcl_Obj *objPtr) /* String value contains the name of the * desired color. */ { TkColor *tkColPtr; Tcl_HashEntry *hashPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; if (objPtr->typePtr != &tkColorObjType) { InitColorObj(objPtr); } /* * First check to see if the internal representation of the object is * defined and is a color that is valid for the current screen and color * map. If it is, we are done. */ tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; if ((tkColPtr != NULL) && (tkColPtr->resourceRefCount > 0) && (Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { /* * The object already points to the right TkColor structure. Just * return it. */ return (XColor *) tkColPtr; } /* * If we reach this point, it means that the TkColor structure that we * have cached in the internal representation is not valid for the current * screen and colormap. But there is a list of other TkColor structures * attached to the TkDisplay. Walk this list looking for the right TkColor * structure. */ hashPtr = Tcl_FindHashEntry(&dispPtr->colorNameTable, Tcl_GetString(objPtr)); if (hashPtr == NULL) { goto error; } for (tkColPtr = Tcl_GetHashValue(hashPtr); (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) { if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { FreeColorObjProc(objPtr); objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; tkColPtr->objRefCount++; return (XColor *) tkColPtr; } } error: Tcl_Panic("Tk_GetColorFromObj called with non-existent color!"); /* * The following code isn't reached; it's just there to please compilers. */ return NULL; }
XColor * Tk_GetColor( Tcl_Interp *interp, /* Place to leave error message if color can't * be found. */ Tk_Window tkwin, /* Window in which color will be used. */ Tk_Uid name) /* Name of color to be allocated (in form * suitable for passing to XParseColor). */ { Tcl_HashEntry *nameHashPtr; int isNew; TkColor *tkColPtr; TkColor *existingColPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; if (!dispPtr->colorInit) { ColorInit(dispPtr); } /* * First, check to see if there's already a mapping for this color name. */ nameHashPtr = Tcl_CreateHashEntry(&dispPtr->colorNameTable, name, &isNew); if (!isNew) { existingColPtr = Tcl_GetHashValue(nameHashPtr); for (tkColPtr = existingColPtr; tkColPtr != NULL; tkColPtr = tkColPtr->nextPtr) { if ((tkColPtr->screen == Tk_Screen(tkwin)) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { tkColPtr->resourceRefCount++; return &tkColPtr->color; } } } else { existingColPtr = NULL; } /* * The name isn't currently known. Map from the name to a pixel value. */ tkColPtr = TkpGetColor(tkwin, name); if (tkColPtr == NULL) { if (interp != NULL) { if (*name == '#') { Tcl_AppendResult(interp, "invalid color name \"", name, "\"", NULL); } else { Tcl_AppendResult(interp, "unknown color name \"", name, "\"", NULL); } } if (isNew) { Tcl_DeleteHashEntry(nameHashPtr); } return NULL; } /* * Now create a new TkColor structure and add it to colorNameTable (in * TkDisplay). */ tkColPtr->magic = COLOR_MAGIC; tkColPtr->gc = None; tkColPtr->screen = Tk_Screen(tkwin); tkColPtr->colormap = Tk_Colormap(tkwin); tkColPtr->visual = Tk_Visual(tkwin); tkColPtr->resourceRefCount = 1; tkColPtr->objRefCount = 0; tkColPtr->type = TK_COLOR_BY_NAME; tkColPtr->hashPtr = nameHashPtr; tkColPtr->nextPtr = existingColPtr; Tcl_SetHashValue(nameHashPtr, tkColPtr); return &tkColPtr->color; }
Tk_3DBorder Tk_Alloc3DBorderFromObj( Tcl_Interp *interp, /* Interp for error results. */ Tk_Window tkwin, /* Need the screen the border is used on.*/ Tcl_Obj *objPtr) /* Object giving name of color for window * background. */ { TkBorder *borderPtr; if (objPtr->typePtr != &tkBorderObjType) { InitBorderObj(objPtr); } borderPtr = (TkBorder *) objPtr->internalRep.twoPtrValue.ptr1; /* * If the object currently points to a TkBorder, see if it's the one we * want. If so, increment its reference count and return. */ if (borderPtr != NULL) { if (borderPtr->resourceRefCount == 0) { /* * This is a stale reference: it refers to a border that's no * longer in use. Clear the reference. */ FreeBorderObjProc(objPtr); borderPtr = NULL; } else if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { borderPtr->resourceRefCount++; return (Tk_3DBorder) borderPtr; } } /* * The object didn't point to the border that we wanted. Search the list * of borders with the same name to see if one of the others is the right * one. */ /* * If the cached value is NULL, either the object type was not a color * going in, or the object is a color type but had previously been freed. * * If the value is not NULL, the internal rep is the value of the color * the last time this object was accessed. Check the screen and colormap * of the last access, and if they match, we are done. */ if (borderPtr != NULL) { TkBorder *firstBorderPtr = (TkBorder *) Tcl_GetHashValue(borderPtr->hashPtr); FreeBorderObjProc(objPtr); for (borderPtr = firstBorderPtr ; borderPtr != NULL; borderPtr = borderPtr->nextPtr) { if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { borderPtr->resourceRefCount++; borderPtr->objRefCount++; objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; return (Tk_3DBorder) borderPtr; } } } /* * Still no luck. Call Tk_Get3DBorder to allocate a new border. */ borderPtr = (TkBorder *) Tk_Get3DBorder(interp, tkwin, Tcl_GetString(objPtr)); objPtr->internalRep.twoPtrValue.ptr1 = (void *) borderPtr; if (borderPtr != NULL) { borderPtr->objRefCount++; } return (Tk_3DBorder) borderPtr; }
Tk_3DBorder Tk_Get3DBorder( Tcl_Interp *interp, /* Place to store an error message. */ Tk_Window tkwin, /* Token for window in which border will be * drawn. */ Tk_Uid colorName) /* String giving name of color for window * background. */ { Tcl_HashEntry *hashPtr; TkBorder *borderPtr, *existingBorderPtr; int isNew; XGCValues gcValues; XColor *bgColorPtr; TkDisplay *dispPtr; dispPtr = ((TkWindow *) tkwin)->dispPtr; if (!dispPtr->borderInit) { BorderInit(dispPtr); } hashPtr = Tcl_CreateHashEntry(&dispPtr->borderTable, colorName, &isNew); if (!isNew) { existingBorderPtr = (TkBorder *) Tcl_GetHashValue(hashPtr); for (borderPtr = existingBorderPtr; borderPtr != NULL; borderPtr = borderPtr->nextPtr) { if ((Tk_Screen(tkwin) == borderPtr->screen) && (Tk_Colormap(tkwin) == borderPtr->colormap)) { borderPtr->resourceRefCount++; return (Tk_3DBorder) borderPtr; } } } else { existingBorderPtr = NULL; } /* * No satisfactory border exists yet. Initialize a new one. */ bgColorPtr = Tk_GetColor(interp, tkwin, colorName); if (bgColorPtr == NULL) { if (isNew) { Tcl_DeleteHashEntry(hashPtr); } return NULL; } borderPtr = TkpGetBorder(); borderPtr->screen = Tk_Screen(tkwin); borderPtr->visual = Tk_Visual(tkwin); borderPtr->depth = Tk_Depth(tkwin); borderPtr->colormap = Tk_Colormap(tkwin); borderPtr->resourceRefCount = 1; borderPtr->objRefCount = 0; borderPtr->bgColorPtr = bgColorPtr; borderPtr->darkColorPtr = NULL; borderPtr->lightColorPtr = NULL; borderPtr->shadow = None; borderPtr->bgGC = None; borderPtr->darkGC = None; borderPtr->lightGC = None; borderPtr->hashPtr = hashPtr; borderPtr->nextPtr = existingBorderPtr; Tcl_SetHashValue(hashPtr, borderPtr); /* * Create the information for displaying the background color, but delay * the allocation of shadows until they are actually needed for drawing. */ gcValues.foreground = borderPtr->bgColorPtr->pixel; borderPtr->bgGC = Tk_GetGC(tkwin, GCForeground, &gcValues); return (Tk_3DBorder) borderPtr; }
static PyObject * tkwin_colormap(TkWinObject * self, PyObject * args) { return PaxCMap_FromColormap(Tk_Colormap(self->tkwin), Tk_Display(self->tkwin), 0); }
Tk_Cursor Tk_GetCursorFromData( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which cursor will be used. */ CONST char *source, /* Bitmap data for cursor shape. */ CONST char *mask, /* Bitmap data for cursor mask. */ int width, int height, /* Dimensions of cursor. */ int xHot, int yHot, /* Location of hot-spot in cursor. */ Tk_Uid fg, /* Foreground color for cursor. */ Tk_Uid bg) /* Background color for cursor. */ { DataKey dataKey; Tcl_HashEntry *dataHashPtr; register TkCursor *cursorPtr; int isNew; XColor fgColor, bgColor; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; if (!dispPtr->cursorInit) { CursorInit(dispPtr); } dataKey.source = source; dataKey.mask = mask; dataKey.width = width; dataKey.height = height; dataKey.xHot = xHot; dataKey.yHot = yHot; dataKey.fg = fg; dataKey.bg = bg; dataKey.display = Tk_Display(tkwin); dataHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorDataTable, (char *) &dataKey, &isNew); if (!isNew) { cursorPtr = (TkCursor *) Tcl_GetHashValue(dataHashPtr); cursorPtr->resourceRefCount++; return cursorPtr->cursor; } /* * No suitable cursor exists yet. Make one using the data available and * add it to the database. */ if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) { Tcl_AppendResult(interp, "invalid color name \"", fg, "\"", NULL); goto error; } if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) { Tcl_AppendResult(interp, "invalid color name \"", bg, "\"", NULL); goto error; } cursorPtr = TkCreateCursorFromData(tkwin, source, mask, width, height, xHot, yHot, fgColor, bgColor); if (cursorPtr == NULL) { goto error; } cursorPtr->resourceRefCount = 1; cursorPtr->otherTable = &dispPtr->cursorDataTable; cursorPtr->hashPtr = dataHashPtr; cursorPtr->objRefCount = 0; cursorPtr->idHashPtr = Tcl_CreateHashEntry(&dispPtr->cursorIdTable, (char *) cursorPtr->cursor, &isNew); cursorPtr->nextPtr = NULL; if (!isNew) { Tcl_Panic("cursor already registered in Tk_GetCursorFromData"); } Tcl_SetHashValue(dataHashPtr, cursorPtr); Tcl_SetHashValue(cursorPtr->idHashPtr, cursorPtr); return cursorPtr->cursor; error: Tcl_DeleteHashEntry(dataHashPtr); return None; }
static int ImgBmapPostscript( ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psinfo, int x, int y, int width, int height, int prepass) { BitmapMaster *masterPtr = clientData; char buffer[200]; if (prepass) { return TCL_OK; } /* * There is nothing to do for bitmaps with zero width or height. */ if (width<=0 || height<=0 || masterPtr->width<=0 || masterPtr->height<= 0){ return TCL_OK; } /* * Translate the origin of the coordinate system to be the lower-left * corner of the bitmap and adjust the scale of the coordinate system so * that entire bitmap covers one square unit of the page. The calling * function put a "gsave" into the postscript and will add a "grestore" at * after this routine returns, so it is safe to make whatever changes are * necessary here. */ if (x!=0 || y!=0) { sprintf(buffer, "%d %d moveto\n", x, y); Tcl_AppendResult(interp, buffer, NULL); } if (width!=1 || height!=1) { sprintf(buffer, "%d %d scale\n", width, height); Tcl_AppendResult(interp, buffer, NULL); } /* * Color the background, if there is one. This step is skipped if the * background is transparent. If the background is not transparent and * there is no background mask, then color the complete rectangle that * encloses the bitmap. If there is a background mask, then only apply * color to the bits specified by the mask. */ if ((masterPtr->bgUid != NULL) && (masterPtr->bgUid[0] != '\000')) { XColor color; XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid, &color); if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) { return TCL_ERROR; } if (masterPtr->maskData == NULL) { Tcl_AppendResult(interp, "0 0 moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto ", "closepath fill\n", NULL); } else if (ImgBmapPsImagemask(interp, masterPtr->width, masterPtr->height, masterPtr->maskData) != TCL_OK) { return TCL_ERROR; } } /* * Draw the bitmap foreground, assuming there is one. */ if ((masterPtr->fgUid != NULL) && (masterPtr->data != NULL)) { XColor color; XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid, &color); if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) { return TCL_ERROR; } if (ImgBmapPsImagemask(interp, masterPtr->width, masterPtr->height, masterPtr->data) != TCL_OK) { return TCL_ERROR; } } return TCL_OK; }
static Cursor CreateCursorFromTableOrFile( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which cursor will be used. */ int argc, const char **argv, /* Cursor spec parsed into elements. */ const struct TkCursorName *tkCursorPtr) /* Non-NULL when cursor is defined in Tk * table. */ { Cursor cursor = None; int width, height, maskWidth, maskHeight; int xHot = -1, yHot = -1; int dummy1, dummy2; XColor fg, bg; const char *fgColor; const char *bgColor; int inTkTable = (tkCursorPtr != NULL); Display *display = Tk_Display(tkwin); Drawable drawable = RootWindowOfScreen(Tk_Screen(tkwin)); Pixmap source = None; Pixmap mask = None; /* * A cursor defined in a file accepts either 2 or 4 arguments. * * {srcfile fg} * {srcfile maskfile fg bg} * * A cursor defined in the Tk table accepts 1, 2, or 3 arguments. * * {tkcursorname} * {tkcursorname fg} * {tkcursorname fg bg} */ if (inTkTable) { /* * This logic is like TkReadBitmapFile(). */ char *data; data = TkGetBitmapData(NULL, tkCursorPtr->data, NULL, &width, &height, &xHot, &yHot); if (data == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading bitmap data for \"%s\"", argv[0])); Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_DATA", NULL); goto cleanup; } source = XCreateBitmapFromData(display, drawable, data, width,height); ckfree(data); } else { if (TkReadBitmapFile(display, drawable, &argv[0][1], (unsigned *) &width, (unsigned *) &height, &source, &xHot, &yHot) != BitmapSuccess) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cleanup reading bitmap file \"%s\"", &argv[0][1])); Tcl_SetErrorCode(interp, "TK", "CURSOR", "BITMAP_FILE", NULL); goto cleanup; } } if ((xHot < 0) || (yHot < 0) || (xHot >= width) || (yHot >= height)) { if (inTkTable) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad hot spot in bitmap data for \"%s\"", argv[0])); } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad hot spot in bitmap file \"%s\"", &argv[0][1])); } Tcl_SetErrorCode(interp, "TK", "CURSOR", "HOTSPOT", NULL); goto cleanup; } /* * Parse color names from optional fg and bg arguments */ if (argc == 1) { fg.red = fg.green = fg.blue = 0; bg.red = bg.green = bg.blue = 65535; } else if (argc == 2) { fgColor = argv[1]; if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid color name \"%s\"", fgColor)); Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL); goto cleanup; } if (inTkTable) { bg.red = bg.green = bg.blue = 0; } else { bg = fg; } } else { /* 3 or 4 arguments */ if (inTkTable) { fgColor = argv[1]; bgColor = argv[2]; } else { fgColor = argv[2]; bgColor = argv[3]; } if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid color name \"%s\"", fgColor)); Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL); goto cleanup; } if (TkParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid color name \"%s\"", bgColor)); Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL); goto cleanup; } } /* * If there is no mask data, then create the cursor now. */ if ((!inTkTable && (argc == 2)) || (inTkTable && tkCursorPtr->mask == NULL)) { cursor = XCreatePixmapCursor(display, source, source, &fg, &fg, (unsigned) xHot, (unsigned) yHot); goto cleanup; } /* * Parse bitmap mask data and create cursor with fg and bg colors. */ if (inTkTable) { /* * This logic is like TkReadBitmapFile(). */ char *data; data = TkGetBitmapData(NULL, tkCursorPtr->mask, NULL, &maskWidth, &maskHeight, &dummy1, &dummy2); if (data == NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading bitmap mask data for \"%s\"", argv[0])); Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_DATA", NULL); goto cleanup; } mask = XCreateBitmapFromData(display, drawable, data, maskWidth, maskHeight); ckfree(data); } else { if (TkReadBitmapFile(display, drawable, argv[1], (unsigned int *) &maskWidth, (unsigned int *) &maskHeight, &mask, &dummy1, &dummy2) != BitmapSuccess) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "cleanup reading bitmap file \"%s\"", argv[1])); Tcl_SetErrorCode(interp, "TK", "CURSOR", "MASK_FILE", NULL); goto cleanup; } } if ((maskWidth != width) || (maskHeight != height)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "source and mask bitmaps have different sizes", -1)); Tcl_SetErrorCode(interp, "TK", "CURSOR", "SIZE_MATCH", NULL); goto cleanup; } cursor = XCreatePixmapCursor(display, source, mask, &fg, &bg, (unsigned) xHot, (unsigned) yHot); cleanup: if (source != None) { Tk_FreePixmap(display, source); } if (mask != None) { Tk_FreePixmap(display, mask); } return cursor; }
TkCursor * TkGetCursorByName( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which cursor will be used. */ Tk_Uid string) /* Description of cursor. See manual entry for * details on legal syntax. */ { TkUnixCursor *cursorPtr = NULL; Cursor cursor = None; int argc; const char **argv = NULL; Display *display = Tk_Display(tkwin); int inTkTable = 0; const struct TkCursorName *tkCursorPtr = NULL; if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { return NULL; } if (argc == 0) { goto badString; } /* * Check Tk specific table of cursor names. The cursor names don't overlap * with cursors defined in the X table so search order does not matter. */ if (argv[0][0] != '@') { for (tkCursorPtr = tkCursorNames; ; tkCursorPtr++) { if (tkCursorPtr->name == NULL) { tkCursorPtr = NULL; break; } if ((tkCursorPtr->name[0] == argv[0][0]) && (strcmp(tkCursorPtr->name, argv[0]) == 0)) { inTkTable = 1; break; } } } if ((argv[0][0] != '@') && !inTkTable) { XColor fg, bg; unsigned int maskIndex; register const struct CursorName *namePtr; TkDisplay *dispPtr; /* * The cursor is to come from the standard cursor font. If one arg, it * is cursor name (use black and white for fg and bg). If two args, * they are name and fg color (ignore mask). If three args, they are * name, fg, bg. Some of the code below is stolen from the * XCreateFontCursor Xlib function. */ if (argc > 3) { goto badString; } for (namePtr = cursorNames; ; namePtr++) { if (namePtr->name == NULL) { goto badString; } if ((namePtr->name[0] == argv[0][0]) && (strcmp(namePtr->name, argv[0]) == 0)) { break; } } maskIndex = namePtr->shape + 1; if (argc == 1) { fg.red = fg.green = fg.blue = 0; bg.red = bg.green = bg.blue = 65535; } else { if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid color name \"%s\"", argv[1])); Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL); goto cleanup; } if (argc == 2) { bg.red = bg.green = bg.blue = 0; maskIndex = namePtr->shape; } else if (TkParseColor(display, Tk_Colormap(tkwin), argv[2], &bg) == 0) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "invalid color name \"%s\"", argv[2])); Tcl_SetErrorCode(interp, "TK", "CURSOR", "COLOR", NULL); goto cleanup; } } dispPtr = ((TkWindow *) tkwin)->dispPtr; if (dispPtr->cursorFont == None) { dispPtr->cursorFont = XLoadFont(display, CURSORFONT); if (dispPtr->cursorFont == None) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't load cursor font", -1)); Tcl_SetErrorCode(interp, "TK", "CURSOR", "FONT", NULL); goto cleanup; } } cursor = XCreateGlyphCursor(display, dispPtr->cursorFont, dispPtr->cursorFont, namePtr->shape, maskIndex, &fg, &bg); } else { /* * Prevent file system access in safe interpreters. */ if (!inTkTable && Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "can't get cursor from a file in a safe interpreter", -1)); Tcl_SetErrorCode(interp, "TK", "SAFE", "CURSOR_FILE", NULL); cursorPtr = NULL; goto cleanup; } /* * If the cursor is to be created from bitmap files, then there should * be either two elements in the list (source, color) or four (source * mask fg bg). A cursor defined in the Tk table accepts the same * arguments as an X cursor. */ if (inTkTable && (argc != 1) && (argc != 2) && (argc != 3)) { goto badString; } if (!inTkTable && (argc != 2) && (argc != 4)) { goto badString; } cursor = CreateCursorFromTableOrFile(interp, tkwin, argc, argv, tkCursorPtr); } if (cursor != None) { cursorPtr = ckalloc(sizeof(TkUnixCursor)); cursorPtr->info.cursor = (Tk_Cursor) cursor; cursorPtr->display = display; } cleanup: if (argv != NULL) { ckfree(argv); } return (TkCursor *) cursorPtr; badString: if (argv) { ckfree(argv); } Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad cursor spec \"%s\"", string)); Tcl_SetErrorCode(interp, "TK", "VALUE", "CURSOR", NULL); return NULL; }