Ejemplo n.º 1
0
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));
}
Ejemplo n.º 2
0
Archivo: tkColor.c Proyecto: arazaq/ns2
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
Archivo: tkColor.c Proyecto: arazaq/ns2
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;
}
Ejemplo n.º 5
0
Archivo: tkColor.c Proyecto: arazaq/ns2
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;
}
Ejemplo n.º 6
0
Archivo: tkColor.c Proyecto: arazaq/ns2
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;
}
Ejemplo n.º 7
0
Archivo: tk3d.c Proyecto: aosm/tcl
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;
}
Ejemplo n.º 8
0
Archivo: tk3d.c Proyecto: aosm/tcl
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;
}
Ejemplo n.º 9
0
static PyObject *
tkwin_colormap(TkWinObject * self, PyObject * args)
{
    return PaxCMap_FromColormap(Tk_Colormap(self->tkwin),
				Tk_Display(self->tkwin), 0);
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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;
}