diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2017-01-03 21:51:01 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2017-01-03 21:51:01 (GMT) |
commit | a780057cc1b51dd3a557549c3cf2431f09136c0d (patch) | |
tree | 717f78052c55596449b27743171d7e170c4d39a0 /tkimg/pixmap/pixmap.c | |
parent | 7749430b9352c1eaf5dca7d8a89a6d35f565ef24 (diff) | |
download | blt-a780057cc1b51dd3a557549c3cf2431f09136c0d.zip blt-a780057cc1b51dd3a557549c3cf2431f09136c0d.tar.gz blt-a780057cc1b51dd3a557549c3cf2431f09136c0d.tar.bz2 |
upgrade tkimg to 1.4.6
Diffstat (limited to 'tkimg/pixmap/pixmap.c')
-rw-r--r-- | tkimg/pixmap/pixmap.c | 1294 |
1 files changed, 0 insertions, 1294 deletions
diff --git a/tkimg/pixmap/pixmap.c b/tkimg/pixmap/pixmap.c deleted file mode 100644 index 922d185..0000000 --- a/tkimg/pixmap/pixmap.c +++ /dev/null @@ -1,1294 +0,0 @@ -/* - * tkImgPmap.c -- - * - * This file implements images of type "pixmap" for Tk. - * - * Copyright (c) 1996, Expert Interface Technologies - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - */ - -#include <ctype.h> -#include <stdlib.h> -#include <string.h> -#include "pixmapInt.h" -#include "tkimg.h" - -#if defined(__WIN32__) && !defined (__GNUC__) -#define strncasecmp strnicmp -#endif - -#ifndef MAC_TCL -#include <sys/types.h> -#include <sys/stat.h> -#endif - -#define UCHAR(c) ((unsigned char) (c)) - -/* - * Prototypes for procedures used only locally in this file: - */ - -static int TkimgXpmCreate(Tcl_Interp *interp, - const char *name, int argc, Tcl_Obj *objv[], - const Tk_ImageType *typePtr, Tk_ImageMaster master, - ClientData *clientDataPtr); -static ClientData TkimgXpmGet(Tk_Window tkwin, - ClientData clientData); -static void TkimgXpmDisplay(ClientData clientData, - Display *display, Drawable drawable, - int imageX, int imageY, int width, int height, - int drawableX, int drawableY); -static void TkimgXpmFree(ClientData clientData, - Display *display); -static void TkimgXpmDelete(ClientData clientData); -static int TkimgXpmCmd(ClientData clientData, - Tcl_Interp *interp, int argc, CONST84 char **argv); -static void TkimgXpmCmdDeletedProc( - ClientData clientData); -static void TkimgXpmConfigureInstance( - PixmapInstance *instancePtr); -static int TkimgXpmConfigureMaster( - PixmapMaster *masterPtr, int argc, CONST84 char **argv, - int flags); -static int TkimgXpmGetData(Tcl_Interp *interp, - PixmapMaster *masterPtr); -static CONST84 char **TkimgXpmGetDataFromFile(Tcl_Interp *interp, - char *string, int *numLines_return); -static CONST84 char **TkimgXpmGetDataFromString(Tcl_Interp *interp, - char *string, int *numLines_return); -static void TkimgXpmGetPixmapFromData( - Tcl_Interp *interp, - PixmapMaster *masterPtr, - PixmapInstance *instancePtr); -static char *GetType(char *colorDefn, - int *type_ret); -static char *GetColor(char *colorDefn, - char *colorName, int *type_ret); - -/* - * Information used for parsing configuration specs: - */ - -static Tk_ConfigSpec configSpecs[] = { - {TK_CONFIG_STRING, "-data", (char *) NULL, (char *) NULL, - (char *) NULL, Tk_Offset(PixmapMaster, dataString), TK_CONFIG_NULL_OK}, - {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL, - (char *) NULL, Tk_Offset(PixmapMaster, fileString), TK_CONFIG_NULL_OK}, - {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, - (char *) NULL, 0, 0} -}; - -Tk_ImageType imgPixmapImageType = { - "pixmap", /* name */ - (Tk_ImageCreateProc *) TkimgXpmCreate,/* createProc */ - TkimgXpmGet, /* getProc */ - TkimgXpmDisplay, /* displayProc */ - TkimgXpmFree, /* freeProc */ - TkimgXpmDelete, /* deleteProc */ -#ifdef TK_CONFIG_OBJS - (Tk_ImagePostscriptProc *) NULL, /* postscriptProc */ -#endif - (Tk_ImageType *) NULL /* nextPtr */ -}; - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmCreate -- - * - * This procedure is called by the Tk image code to create "pixmap" - * images. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * The data structure for a new image is allocated. - * - *---------------------------------------------------------------------- - */ - -static int -TkimgXpmCreate(interp, name, argc, objv, typePtr, master, clientDataPtr) - Tcl_Interp *interp; /* Interpreter for application containing - * image. */ - const char *name; /* Name to use for image. */ - int argc; /* Number of arguments. */ - Tcl_Obj *objv[]; /* Argument strings for options (doesn't - * include image name or type). */ - const Tk_ImageType *typePtr; /* Pointer to our type record (not used). */ - Tk_ImageMaster master; /* Token for image, to be used by us in - * later callbacks. */ - ClientData *clientDataPtr; /* Store manager's token for image here; - * it will be returned in later callbacks. */ -{ - PixmapMaster *masterPtr; - int i; - char *argvbuf[10]; - CONST84 char **args = (CONST84 char **) argvbuf; - - /* - * Convert the objc/objv arguments into string equivalent. - */ - if (argc > 10) { - args = (CONST84 char **) ckalloc(argc * sizeof(char *)); - } - for (i = 0; i < argc; i++) { - args[i] = tkimg_GetStringFromObj(objv[i], NULL); - } - - masterPtr = (PixmapMaster *) ckalloc(sizeof(PixmapMaster)); - masterPtr->tkMaster = master; - masterPtr->interp = interp; - masterPtr->imageCmd = Tcl_CreateCommand(interp, name, TkimgXpmCmd, - (ClientData) masterPtr, TkimgXpmCmdDeletedProc); - - masterPtr->fileString = NULL; - masterPtr->dataString = NULL; - masterPtr->data = NULL; - masterPtr->isDataAlloced = 0; - masterPtr->instancePtr = NULL; - - if (TkimgXpmConfigureMaster(masterPtr, argc, args, 0) != TCL_OK) { - TkimgXpmDelete((ClientData) masterPtr); - if (args != ((CONST84 char **) argvbuf)) { - ckfree((char *) args); - } - return TCL_ERROR; - } - *clientDataPtr = (ClientData) masterPtr; - if (args != ((CONST84 char **) argvbuf)) { - ckfree((char *) args); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmConfigureMaster -- - * - * This procedure is called when a pixmap image is created or - * reconfigured. It process configuration options and resets - * any instances of the image. - * - * Results: - * A standard Tcl return value. If TCL_ERROR is returned then - * an error message is left in masterPtr->interp->result. - * - * Side effects: - * Existing instances of the image will be redisplayed to match - * the new configuration options. - * - * If any error occurs, the state of *masterPtr is restored to - * previous state. - * - *---------------------------------------------------------------------- - */ - -static int -TkimgXpmConfigureMaster(masterPtr, argc, argv, flags) - PixmapMaster *masterPtr; /* Pointer to data structure describing - * overall pixmap image to (reconfigure). */ - int argc; /* Number of entries in argv. */ - CONST84 char **argv; /* Pairs of configuration options for image. */ - int flags; /* Flags to pass to Tk_ConfigureWidget, - * such as TK_CONFIG_ARGV_ONLY. */ -{ - PixmapInstance *instancePtr; - char * oldData, * oldFile; - - oldData = masterPtr->dataString; - oldFile = masterPtr->fileString; - - if (Tk_ConfigureWidget(masterPtr->interp, Tk_MainWindow(masterPtr->interp), - configSpecs, argc, argv, (char *) masterPtr, flags) - != TCL_OK) { - return TCL_ERROR; - } - - if (masterPtr->dataString != NULL || - masterPtr->fileString != NULL) { - if (TkimgXpmGetData(masterPtr->interp, masterPtr) != TCL_OK) { - goto error; - } - } else { - Tcl_AppendResult(masterPtr->interp, - "must specify one of -data or -file", NULL); - goto error; - } - - /* - * Cycle through all of the instances of this image, regenerating - * the information for each instance. Then force the image to be - * redisplayed everywhere that it is used. - */ - for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; - instancePtr = instancePtr->nextPtr) { - TkimgXpmConfigureInstance(instancePtr); - } - - if (masterPtr->data) { - Tk_ImageChanged(masterPtr->tkMaster, 0, 0, - masterPtr->size[0], masterPtr->size[1], - masterPtr->size[0], masterPtr->size[1]); - } else { - Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, 0, 0); - } - - return TCL_OK; - - error: - /* Restore it to the original (possible valid) mode */ - if (masterPtr->dataString && masterPtr->dataString != oldData) { - ckfree(masterPtr->dataString); - } - if (masterPtr->fileString && masterPtr->fileString != oldFile) { - ckfree(masterPtr->fileString); - } - masterPtr->dataString = oldData; - masterPtr->fileString = oldFile; - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmGetData -- - * - * Given a file name or ASCII string, this procedure parses the - * file or string contents to produce binary data for a pixmap. - * - * Results: - * If the pixmap description was parsed successfully then the data - * is read into an array of strings. This array will later be used - * to create X Pixmaps for each instance. - * - * Side effects: - * The masterPtr->data array is allocated when successful. Contents of - * *masterPtr is changed only when successful. - *---------------------------------------------------------------------- - */ - -static int -TkimgXpmGetData(interp, masterPtr) - Tcl_Interp *interp; /* For reporting errors. */ - PixmapMaster *masterPtr; -{ - CONST84 char ** data = NULL; - int isAllocated = 0; /* do we need to free "data"? */ - int listArgc; - CONST84 char ** listArgv = NULL; - int numLines; - int size[2]; - int cpp; - int ncolors; - int code = TCL_OK; - - if (masterPtr->fileString != NULL) { - if (Tcl_IsSafe(interp)) { - Tcl_AppendResult(interp, "can't get image from a file in a", - " safe interpreter", (char *) NULL); - return TCL_ERROR; - } - data = TkimgXpmGetDataFromFile(interp, masterPtr->fileString, &numLines); - isAllocated = 1; - } - else if (masterPtr->dataString != NULL) { - data = TkimgXpmGetDataFromString(interp,masterPtr->dataString,&numLines); - isAllocated = 1; - } - else { - /* Should have been enforced by TkimgXpmConfigureMaster() */ - Tcl_Panic("TkimgXpmGetData(): -data and -file are all NULL"); - } - - if (data == NULL) { - /* nothing has been allocated yet. Don't need to goto done */ - return TCL_ERROR; - } - - /* Parse the first line of the data and get info about this pixmap */ - if (Tcl_SplitList(interp, data[0], &listArgc, &listArgv) != TCL_OK) { - code = TCL_ERROR; goto done; - } - - if (listArgc < 4) { /* file format error */ - code = TCL_ERROR; goto done; - } - - if (Tcl_GetInt(interp, listArgv[0], &size[0]) != TCL_OK) { - code = TCL_ERROR; goto done; - } - if (Tcl_GetInt(interp, listArgv[1], &size[1]) != TCL_OK) { - code = TCL_ERROR; goto done; - } - if (Tcl_GetInt(interp, listArgv[2], &ncolors) != TCL_OK) { - code = TCL_ERROR; goto done; - } - if (Tcl_GetInt(interp, listArgv[3], &cpp) != TCL_OK) { - code = TCL_ERROR; goto done; - } - - if (isAllocated) { - if (numLines != size[1] + ncolors + 1) { - /* the number of lines read from the file/data - * is not the same as specified in the data - */ - code = TCL_ERROR; goto done; - } - } - - done: - if (code == TCL_OK) { - if (masterPtr->isDataAlloced && masterPtr->data) { - ckfree((char*)masterPtr->data); - } - masterPtr->isDataAlloced = isAllocated; - masterPtr->data = (char **) data; - masterPtr->size[0] = size[0]; - masterPtr->size[1] = size[1]; - masterPtr->cpp = cpp; - masterPtr->ncolors = ncolors; - } else { - if (isAllocated && data) { - ckfree((char*)data); - } - - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "File format error", NULL); - } - - if (listArgv) { - ckfree((char*)listArgv); - } - - return code; -} - -static CONST84 char ** -TkimgXpmGetDataFromString(interp, string, numLines_return) - Tcl_Interp * interp; - char * string; - int * numLines_return; -{ - int quoted; - char * p, * list; - int numLines; - CONST84 char ** data; - - /* skip the leading blanks (leading blanks are not defined in the - * the XPM definition, but skipping them shouldn't hurt. Also, the ability - * to skip the leading blanks is good for using in-line XPM data in TCL - * scripts - */ - while (isspace(UCHAR(*string))) { - ++ string; - } - - /* parse the header */ - if (strncmp("/* XPM", string, 6) != 0) { - goto error; - } - - /* strip the comments */ - for (quoted = 0, p=string; *p;) { - if (!quoted) { - if (*p == '"') { - quoted = 1; - ++ p; - continue; - } - - if (*p == '/' && *(p+1) == '*') { - *p++ = ' '; - *p++ = ' '; - while (1) { - if (*p == 0) { - break; - } - if (*p == '*' && *(p+1) == '/') { - *p++ = ' '; - *p++ = ' '; - break; - } - *p++ = ' '; - } - continue; - } - ++ p; - } else { - if (*p == '"') { - quoted = 0; - } - ++ p; - } - } - - /* Search for the opening brace */ - for (p=string; *p;) { - if (*p != '{') { - ++ p; - } else { - ++p; - break; - } - } - - /* Change the buffer in to a proper TCL list */ - quoted = 0; - list = p; - - while (*p) { - if (!quoted) { - if (*p == '"') { - quoted = 1; - ++ p; - continue; - } - - if (isspace(UCHAR(*p))) { - *p = ' '; - } - else if (*p == ',') { - *p = ' '; - } - else if (*p == '}') { - *p = 0; - break; - } - ++p; - } - else { - if (*p == '"') { - quoted = 0; - } - ++ p; - } - } - - /* The following code depends on the fact that Tcl_SplitList - * strips away double quoates inside a list: ie: - * if string == "\"1\" \"2\"" then - * list[0] = "1" - * list[1] = "2" - * and NOT - * - * list[0] = "\"1\"" - * list[1] = "\"2\"" - */ - if (Tcl_SplitList(interp, list, &numLines, &data) != TCL_OK) { - goto error; - } else { - if (numLines == 0) { - /* error: empty data? */ - if (data != NULL) { - ckfree((char*)data); - goto error; - } - } - * numLines_return = numLines; - return data; - } - - error: - Tcl_AppendResult(interp, "File format error", NULL); - return (CONST84 char**) NULL; -} - -static CONST84 char ** -TkimgXpmGetDataFromFile(interp, fileName, numLines_return) - Tcl_Interp * interp; - char * fileName; - int * numLines_return; -{ - Tcl_Channel chan; - int size; - CONST84 char ** data = (CONST84 char **) NULL; - char *cmdBuffer = NULL; - - chan = tkimg_OpenFileChannel(interp, fileName, 0); - if (!chan) { - return (CONST84 char **) NULL; - } - - size = Tcl_Seek(chan, 0, SEEK_END); - if (size > 0) { - Tcl_Seek(chan, 0, SEEK_SET); - cmdBuffer = (char *) ckalloc(size+1); - size = Tcl_Read(chan, cmdBuffer, size); - } - if (Tcl_Close(interp, chan) != TCL_OK) { - goto error; - } - if (size < 0) { - Tcl_AppendResult(interp, fileName, ": ", - Tcl_PosixError(interp), (char *)NULL); - goto error; - } - cmdBuffer[size] = 0; - - data = TkimgXpmGetDataFromString(interp, cmdBuffer, numLines_return); - error: - if (cmdBuffer) { - ckfree(cmdBuffer); - } - return data; -} - - -static char * -GetType(colorDefn, type_ret) - char * colorDefn; - int * type_ret; -{ - char * p = colorDefn; - - /* skip white spaces */ - while (*p && isspace(UCHAR(*p))) { - p ++; - } - - /* parse the type */ - if (p[0] != '\0' && p[0] == 'm' && - p[1] != '\0' && isspace(UCHAR(p[1]))) { - *type_ret = XPM_MONO; - p += 2; - } - else if (p[0] != '\0' && p[0] == 'g' && - p[1] != '\0' && p[1] == '4' && - p[2] != '\0' && isspace(UCHAR(p[2]))) { - *type_ret = XPM_GRAY_4; - p += 3; - } - else if (p[0] != '\0' && p[0] == 'g' && - p[1] != '\0' && isspace(UCHAR(p[1]))) { - *type_ret = XPM_GRAY; - p += 2; - } - else if (p[0] != '\0' && p[0] == 'c' && - p[1] != '\0' && isspace(UCHAR(p[1]))) { - *type_ret = XPM_COLOR; - p += 2; - } - else if (p[0] != '\0' && p[0] == 's' && - p[1] != '\0' && isspace(UCHAR(p[1]))) { - *type_ret = XPM_SYMBOLIC; - p += 2; - } - else { - *type_ret = XPM_UNKNOWN; - return NULL; - } - - return p; -} - -/* - * colorName is guaranteed to be big enough - */ - -static char * -GetColor(colorDefn, colorName, type_ret) - char * colorDefn; - char * colorName; /* if found, name is copied to this array */ - int * type_ret; -{ - int type; - char * p; - - if (!colorDefn) { - return NULL; - } - - if ((colorDefn = GetType(colorDefn, &type)) == NULL) { - /* unknown type */ - return NULL; - } - else { - *type_ret = type; - } - - /* skip white spaces */ - while (*colorDefn && isspace(UCHAR(*colorDefn))) { - colorDefn ++; - } - - p = colorName; - - while (1) { - int dummy; - - while (*colorDefn && !isspace(UCHAR(*colorDefn))) { - *p++ = *colorDefn++; - } - - if (!*colorDefn) { - break; - } - - if (GetType(colorDefn, &dummy) == NULL) { - /* the next string should also be considered as a part of a color - * name */ - - while (*colorDefn && isspace(UCHAR(*colorDefn))) { - *p++ = *colorDefn++; - } - } else { - break; - } - if (!*colorDefn) { - break; - } - } - - /* Mark the end of the colorName */ - *p = '\0'; - - return colorDefn; -} - -/*---------------------------------------------------------------------- - * TkimgXpmGetPixmapFromData -- - * - * Creates a pixmap for an image instance. - *---------------------------------------------------------------------- - */ - -static void -TkimgXpmGetPixmapFromData(interp, masterPtr, instancePtr) - Tcl_Interp * interp; - PixmapMaster *masterPtr; - PixmapInstance *instancePtr; -{ - XImage * image = NULL, * mask = NULL; - int depth, i, j, k, lOffset, isTransp = 0, isMono; - ColorStruct * colors; - - depth = Tk_Depth(instancePtr->tkwin); - - switch ((Tk_Visual(instancePtr->tkwin))->class) { - case StaticGray: - case GrayScale: - isMono = 1; - break; - default: - isMono = 0; - } - - TkimgXpmAllocTmpBuffer(masterPtr, instancePtr, &image, &mask); - - /* - * Parse the colors - */ - lOffset = 1; - colors = (ColorStruct*)ckalloc(sizeof(ColorStruct)*masterPtr->ncolors); - - /* - * Initialize the color structures - */ - for (i=0; i<masterPtr->ncolors; i++) { - colors[i].colorPtr = NULL; - if (masterPtr->cpp == 1) { - colors[i].c = 0; - } else { - colors[i].cstring = (char*)ckalloc(masterPtr->cpp); - colors[i].cstring[0] = 0; - } - } - - for (i=0; i<masterPtr->ncolors; i++) { - char * colorDefn; /* the color definition line */ - char * colorName; /* temp place to hold the color name - * defined for one type of visual */ - char * useName; /* the color name used for this - * color. If there are many names - * defined, choose the name that is - * "best" for the target visual - */ - int found; - - colorDefn = masterPtr->data[i+lOffset]+masterPtr->cpp; - colorName = (char*)ckalloc(strlen(colorDefn)); - useName = (char*)ckalloc(strlen(colorDefn)); - found = 0; - - while (colorDefn && *colorDefn) { - int type; - - if ((colorDefn=GetColor(colorDefn, colorName, &type)) == NULL) { - break; - } - if (colorName[0] == '\0') { - continue; - } - - switch (type) { - case XPM_MONO: - if (isMono && depth == 1) { - strcpy(useName, colorName); - found = 1; goto gotcolor; - } - break; - case XPM_GRAY_4: - if (isMono && depth == 4) { - strcpy(useName, colorName); - found = 1; goto gotcolor; - } - break; - case XPM_GRAY: - if (isMono && depth > 4) { - strcpy(useName, colorName); - found = 1; goto gotcolor; - } - break; - case XPM_COLOR: - if (!isMono) { - strcpy(useName, colorName); - found = 1; goto gotcolor; - } - break; - } - if (type != XPM_SYMBOLIC && type != XPM_UNKNOWN) { - if (!found) { /* use this color as default */ - strcpy(useName, colorName); - found = 1; - } - } - } - - gotcolor: - if (masterPtr->cpp == 1) { - colors[i].c = masterPtr->data[i+lOffset][0]; - } else { - strncpy(colors[i].cstring, masterPtr->data[i+lOffset], - (size_t)masterPtr->cpp); - } - - if (found) { - if (strncasecmp(useName, "none", 5) != 0) { - colors[i].colorPtr = Tk_GetColor(interp, - instancePtr->tkwin, Tk_GetUid(useName)); - if (colors[i].colorPtr == NULL) { - colors[i].colorPtr = Tk_GetColor(interp, - instancePtr->tkwin, Tk_GetUid("black")); - } - } - } else { - colors[i].colorPtr = Tk_GetColor(interp, - instancePtr->tkwin, Tk_GetUid("black")); - } - - ckfree(colorName); - ckfree(useName); - } - - lOffset += masterPtr->ncolors; - - /* - * Parse the main body of the image - */ - for (i=0; i<masterPtr->size[1]; i++) { - char * p = masterPtr->data[i+lOffset]; - - for (j=0; j<masterPtr->size[0]; j++) { - if (masterPtr->cpp == 1) { - for (k=0; k<masterPtr->ncolors; k++) { - if (*p == colors[k].c) { - TkimgXpmSetPixel(instancePtr, image, mask, j, i, - colors[k].colorPtr, &isTransp); - break; - } - } - if (*p) { - p++; - } - } else { - for (k=0; k<masterPtr->ncolors; k++) { - if (strncmp(p, colors[k].cstring, - (size_t)masterPtr->cpp) == 0) { - TkimgXpmSetPixel(instancePtr, image, mask, j, i, - colors[k].colorPtr, &isTransp); - break; - } - } - for (k=0; *p && k<masterPtr->cpp; k++) { - p++; - } - } - } - } - - instancePtr->colors = colors; - - TkimgXpmRealizePixmap(masterPtr, instancePtr, image, mask, isTransp); - TkimgXpmFreeTmpBuffer(masterPtr, instancePtr, image, mask); -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmConfigureInstance -- - * - * This procedure is called to create displaying information for - * a pixmap image instance based on the configuration information - * in the master. It is invoked both when new instances are - * created and when the master is reconfigured. - * - * Results: - * None. - * - * Side effects: - * Generates errors via Tk_BackgroundError if there are problems - * in setting up the instance. - * - *---------------------------------------------------------------------- - */ - -static void -TkimgXpmConfigureInstance(instancePtr) - PixmapInstance *instancePtr; /* Instance to reconfigure. */ -{ - PixmapMaster *masterPtr = instancePtr->masterPtr; - - if (instancePtr->pixmap != None) { - Tk_FreePixmap(Tk_Display(instancePtr->tkwin), instancePtr->pixmap); - } - TkimgXpmFreeInstanceData(instancePtr, 0); - - if (instancePtr->colors != NULL) { - int i; - for (i=0; i<masterPtr->ncolors; i++) { - if (instancePtr->colors[i].colorPtr != NULL) { - Tk_FreeColor(instancePtr->colors[i].colorPtr); - } - if (masterPtr->cpp != 1) { - ckfree(instancePtr->colors[i].cstring); - } - } - ckfree((char*)instancePtr->colors); - } - - if (Tk_WindowId(instancePtr->tkwin) == None) { - Tk_MakeWindowExist(instancePtr->tkwin); - } - - /* - * Assumption: masterPtr->data is always non NULL (enfored by - * TkimgXpmConfigureMaster()). Also, the data must be in a valid - * format (partially enforced by TkimgXpmConfigureMaster(), see comments - * inside that function). - */ - TkimgXpmGetPixmapFromData(masterPtr->interp, masterPtr, instancePtr); -} - -/* - *-------------------------------------------------------------- - * - * TkimgXpmCmd -- - * - * This procedure is invoked to process the Tcl command - * that corresponds to an image managed by this module. - * See the user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *-------------------------------------------------------------- - */ - -static int -TkimgXpmCmd(clientData, interp, argc, argv) - ClientData clientData; /* Information about button widget. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - CONST84 char **argv; /* Argument strings. */ -{ - PixmapMaster *masterPtr = (PixmapMaster *) clientData; - int c, code; - size_t length; - - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " option ?arg arg ...?\"", - (char *) NULL); - return TCL_ERROR; - } - c = argv[1][0]; - length = strlen(argv[1]); - - if ((c == 'c') && (strncmp(argv[1], "cget", length) == 0) - && (length >= 2)) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " cget option\"", - (char *) NULL); - return TCL_ERROR; - } - return Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs, - (char *) masterPtr, argv[2], 0); - } else if ((c == 'c') && (strncmp(argv[1], "configure", length) == 0) - && (length >= 2)) { - if (argc == 2) { - code = Tk_ConfigureInfo(interp, Tk_MainWindow(interp), - configSpecs, (char *) masterPtr, (char *) NULL, 0); - } else if (argc == 3) { - code = Tk_ConfigureInfo(interp, Tk_MainWindow(interp), - configSpecs, (char *) masterPtr, argv[2], 0); - } else { - code = TkimgXpmConfigureMaster(masterPtr, argc-2, argv+2, - TK_CONFIG_ARGV_ONLY); - } - return code; - } else if ((c == 'r') && (strncmp(argv[1], "refcount", length) == 0)) { - /* - * The "refcount" command is for debugging only - */ - PixmapInstance *instancePtr; - int count = 0; - char buff[30]; - - if (argc != 1) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], "\"", (char *) NULL); - return TCL_ERROR; - } - for (instancePtr=masterPtr->instancePtr; instancePtr; - instancePtr = instancePtr->nextPtr) { - count += instancePtr->refCount; - } - sprintf(buff, "%d", count); - Tcl_AppendResult(interp, buff, (char *) NULL); - return TCL_OK; - } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be cget, configure or refcount", (char *) NULL); - return TCL_ERROR; - } -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmGet -- - * - * This procedure is called for each use of a pixmap image in a - * widget. - * - * Results: - * The return value is a token for the instance, which is passed - * back to us in calls to TkimgXpmDisplay and TkimgXpmFre. - * - * Side effects: - * A data structure is set up for the instance (or, an existing - * instance is re-used for the new one). - * - *---------------------------------------------------------------------- - */ - -static ClientData -TkimgXpmGet(tkwin, masterData) - Tk_Window tkwin; /* Window in which the instance will be - * used. */ - ClientData masterData; /* Pointer to our master structure for the - * image. */ -{ - PixmapMaster *masterPtr = (PixmapMaster *) masterData; - PixmapInstance *instancePtr; - - /* - * See if there is already an instance for this window. If so - * then just re-use it. - */ - - for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; - instancePtr = instancePtr->nextPtr) { - if (instancePtr->tkwin == tkwin) { - instancePtr->refCount++; - return (ClientData) instancePtr; - } - } - - /* - * The image isn't already in use in this window. Make a new - * instance of the image. - */ - instancePtr = (PixmapInstance *) ckalloc(sizeof(PixmapInstance)); - instancePtr->refCount = 1; - instancePtr->masterPtr = masterPtr; - instancePtr->tkwin = tkwin; - instancePtr->pixmap = None; - instancePtr->nextPtr = masterPtr->instancePtr; - instancePtr->colors = NULL; - masterPtr->instancePtr = instancePtr; - - TkimgInitPixmapInstance(masterPtr, instancePtr); - TkimgXpmConfigureInstance(instancePtr); - - /* - * If this is the first instance, must set the size of the image. - */ - if (instancePtr->nextPtr == NULL) { - if (masterPtr->data) { - Tk_ImageChanged(masterPtr->tkMaster, 0, 0, - masterPtr->size[0], masterPtr->size[1], - masterPtr->size[0], masterPtr->size[1]); - } else { - Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, 0, 0); - } - } - - return (ClientData) instancePtr; -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmDisplay -- - * - * This procedure is invoked to draw a pixmap image. - * - * Results: - * None. - * - * Side effects: - * A portion of the image gets rendered in a pixmap or window. - * - *---------------------------------------------------------------------- - */ - -static void -TkimgXpmDisplay(clientData, display, drawable, imageX, imageY, width, - height, drawableX, drawableY) - ClientData clientData; /* Pointer to PixmapInstance structure for - * for instance to be displayed. */ - Display *display; /* Display on which to draw image. */ - Drawable drawable; /* Pixmap or window in which to draw image. */ - int imageX, imageY; /* Upper-left corner of region within image - * to draw. */ - int width, height; /* Dimensions of region within image to draw.*/ - int drawableX, drawableY; /* Coordinates within drawable that - * correspond to imageX and imageY. */ -{ - TkimgpXpmDisplay(clientData, display, drawable, imageX, imageY, width, - height, drawableX, drawableY); -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmFree -- - * - * This procedure is called when a widget ceases to use a - * particular instance of an image. - * - * Results: - * None. - * - * Side effects: - * Internal data structures get cleaned up. - * - *---------------------------------------------------------------------- - */ - -static void -TkimgXpmFree(clientData, display) - ClientData clientData; /* Pointer to PixmapInstance structure for - * for instance to be displayed. */ - Display *display; /* Display containing window that used image.*/ -{ - PixmapInstance *instancePtr = (PixmapInstance *) clientData; - PixmapInstance *prevPtr; - - instancePtr->refCount--; - if (instancePtr->refCount > 0) { - return; - } - - /* - * There are no more uses of the image within this widget. Free - * the instance structure. - */ - if (instancePtr->pixmap != None) { - Tk_FreePixmap(display, instancePtr->pixmap); - } - TkimgXpmFreeInstanceData(instancePtr, 1); - - if (instancePtr->colors != NULL) { - int i; - for (i=0; i<instancePtr->masterPtr->ncolors; i++) { - if (instancePtr->colors[i].colorPtr != NULL) { - Tk_FreeColor(instancePtr->colors[i].colorPtr); - } - if (instancePtr->masterPtr->cpp != 1) { - ckfree(instancePtr->colors[i].cstring); - } - } - ckfree((char*)instancePtr->colors); - } - - if (instancePtr->masterPtr->instancePtr == instancePtr) { - instancePtr->masterPtr->instancePtr = instancePtr->nextPtr; - } else { - for (prevPtr = instancePtr->masterPtr->instancePtr; - prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) { - /* Empty loop body */ - } - prevPtr->nextPtr = instancePtr->nextPtr; - } - ckfree((char *) instancePtr); -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmDelete -- - * - * This procedure is called by the image code to delete the - * master structure for an image. - * - * Results: - * None. - * - * Side effects: - * Resources associated with the image get freed. - * - *---------------------------------------------------------------------- - */ - -static void -TkimgXpmDelete(masterData) - ClientData masterData; /* Pointer to PixmapMaster structure for - * image. Must not have any more instances. */ -{ - PixmapMaster *masterPtr = (PixmapMaster *) masterData; - - if (masterPtr->instancePtr != NULL) { - Tcl_Panic("tried to delete pixmap image when instances still exist"); - } - masterPtr->tkMaster = NULL; - if (masterPtr->imageCmd != NULL) { - Tcl_DeleteCommand(masterPtr->interp, - Tcl_GetCommandName(masterPtr->interp, masterPtr->imageCmd)); - } - if (masterPtr->isDataAlloced && masterPtr->data != NULL) { - ckfree((char*)masterPtr->data); - masterPtr->data = NULL; - } - - Tk_FreeOptions(configSpecs, (char *) masterPtr, (Display *) NULL, 0); - ckfree((char *) masterPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TkimgXpmCmdDeletedProc -- - * - * This procedure is invoked when the image command for an image - * is deleted. It deletes the image. - * - * Results: - * None. - * - * Side effects: - * The image is deleted. - * - *---------------------------------------------------------------------- - */ - -static void -TkimgXpmCmdDeletedProc(clientData) - ClientData clientData; /* Pointer to PixmapMaster structure for - * image. */ -{ - PixmapMaster *masterPtr = (PixmapMaster *) clientData; - - masterPtr->imageCmd = NULL; - if (masterPtr->tkMaster != NULL) { - Tk_DeleteImage(masterPtr->interp, Tk_NameOfImage(masterPtr->tkMaster)); - } -} - -/* - * Package management. Initialization of stub information. - */ - -/* - *---------------------------------------------------------------------------- - * - * Tkimgpixmap_Init -- - * - * Initialisation routine for loadable module - * - * Results: - * None. - * - * Side effects: - * Creates commands in the interpreter, loads package. - * - *---------------------------------------------------------------------------- - */ - -int -Tkimgpixmap_Init (interp) - Tcl_Interp *interp; /* Interpreter to initialise. */ -{ - static int initialized = 0; - - if (Tcl_InitStubs(interp, "8.3", 0) == NULL) { - return TCL_ERROR; - } - if (Tk_InitStubs(interp, "8.3", 0) == NULL) { - return TCL_ERROR; - } - if (Tkimg_InitStubs(interp, TKIMG_VERSION, 0) == NULL) { - return TCL_ERROR; - } - -#ifndef TCL_MAC - if (!initialized) { - Tk_CreateImageType(&imgPixmapImageType); - initialized = 1; - } -#endif - - /* - * At last provide the package ... - */ - - if (Tcl_PkgProvide(interp, PACKAGE_TCLNAME, PACKAGE_VERSION) != TCL_OK) { - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------------- - * - * Tkimgpixmap_SafeInit -- - * - * Initialisation routine for loadable module in a safe interpreter. - * - * Results: - * None. - * - * Side effects: - * Creates commands in the interpreter, - * loads xml package. - * - *---------------------------------------------------------------------------- - */ - -int -Tkimgpixmap_SafeInit (interp) - Tcl_Interp *interp; /* Interpreter to initialise. */ -{ - return Tkimgpixmap_Init (interp); -} |