diff options
Diffstat (limited to 'generic/tkUtil.c')
-rw-r--r-- | generic/tkUtil.c | 483 |
1 files changed, 482 insertions, 1 deletions
diff --git a/generic/tkUtil.c b/generic/tkUtil.c index 226fd86..0ba1f96 100644 --- a/generic/tkUtil.c +++ b/generic/tkUtil.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUtil.c,v 1.6 1999/08/10 05:10:52 jingham Exp $ + * RCS: @(#) $Id: tkUtil.c,v 1.7 1999/12/14 06:52:34 hobbs Exp $ */ #include "tkInt.h" @@ -32,6 +32,487 @@ static Tcl_ObjType stateKeyType = { /* + *-------------------------------------------------------------- + * + * TkStateParseProc -- + * + * This procedure is invoked during option processing to handle + * the "-state" and "-default" options. + * + * Results: + * A standard Tcl return value. + * + * Side effects: + * The state for a given item gets replaced by the state + * indicated in the value argument. + * + *-------------------------------------------------------------- + */ + +int +TkStateParseProc(clientData, interp, tkwin, value, widgRec, offset) + ClientData clientData; /* some flags.*/ + Tcl_Interp *interp; /* Used for reporting errors. */ + Tk_Window tkwin; /* Window containing canvas widget. */ + CONST char *value; /* Value of option. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ +{ + int c; + int flags = (int)clientData; + size_t length; + + register Tk_State *statePtr = (Tk_State *) (widgRec + offset); + + if(value == NULL || *value == 0) { + *statePtr = TK_STATE_NULL; + return TCL_OK; + } + + c = value[0]; + length = strlen(value); + + if ((c == 'n') && (strncmp(value, "normal", length) == 0)) { + *statePtr = TK_STATE_NORMAL; + return TCL_OK; + } + if ((c == 'd') && (strncmp(value, "disabled", length) == 0)) { + *statePtr = TK_STATE_DISABLED; + return TCL_OK; + } + if ((c == 'a') && (flags&1) && (strncmp(value, "active", length) == 0)) { + *statePtr = TK_STATE_ACTIVE; + return TCL_OK; + } + if ((c == 'h') && (flags&2) && (strncmp(value, "hidden", length) == 0)) { + *statePtr = TK_STATE_HIDDEN; + return TCL_OK; + } + + Tcl_AppendResult(interp, "bad ", (flags&4)?"-default" : "state", + " value \"", value, "\": must be normal", + (char *) NULL); + if (flags&1) { + Tcl_AppendResult(interp, ", active",(char *) NULL); + } + if (flags&2) { + Tcl_AppendResult(interp, ", hidden",(char *) NULL); + } + if (flags&3) { + Tcl_AppendResult(interp, ",",(char *) NULL); + } + Tcl_AppendResult(interp, " or disabled",(char *) NULL); + *statePtr = TK_STATE_NORMAL; + return TCL_ERROR; +} + +/* + *-------------------------------------------------------------- + * + * TkStatePrintProc -- + * + * This procedure is invoked by the Tk configuration code + * to produce a printable string for the "-state" + * configuration option. + * + * Results: + * The return value is a string describing the state for + * the item referred to by "widgRec". In addition, *freeProcPtr + * is filled in with the address of a procedure to call to free + * the result string when it's no longer needed (or NULL to + * indicate that the string doesn't need to be freed). + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +char * +TkStatePrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) + ClientData clientData; /* Ignored. */ + Tk_Window tkwin; /* Window containing canvas widget. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ + Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with + * information about how to reclaim + * storage for return string. */ +{ + register Tk_State *statePtr = (Tk_State *) (widgRec + offset); + + if (*statePtr==TK_STATE_NORMAL) { + return "normal"; + } else if (*statePtr==TK_STATE_DISABLED) { + return "disabled"; + } else if (*statePtr==TK_STATE_HIDDEN) { + return "hidden"; + } else if (*statePtr==TK_STATE_ACTIVE) { + return "active"; + } else { + return ""; + } +} + +/* + *-------------------------------------------------------------- + * + * TkOrientParseProc -- + * + * This procedure is invoked during option processing to handle + * the "-orient" option. + * + * Results: + * A standard Tcl return value. + * + * Side effects: + * The orientation for a given item gets replaced by the orientation + * indicated in the value argument. + * + *-------------------------------------------------------------- + */ + +int +TkOrientParseProc(clientData, interp, tkwin, value, widgRec, offset) + ClientData clientData; /* some flags.*/ + Tcl_Interp *interp; /* Used for reporting errors. */ + Tk_Window tkwin; /* Window containing canvas widget. */ + CONST char *value; /* Value of option. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ +{ + int c; + size_t length; + + register int *orientPtr = (int *) (widgRec + offset); + + if(value == NULL || *value == 0) { + *orientPtr = 0; + return TCL_OK; + } + + c = value[0]; + length = strlen(value); + + if ((c == 'h') && (strncmp(value, "horizontal", length) == 0)) { + *orientPtr = 0; + return TCL_OK; + } + if ((c == 'v') && (strncmp(value, "vertical", length) == 0)) { + *orientPtr = 1; + return TCL_OK; + } + Tcl_AppendResult(interp, "bad orientation \"", value, + "\": must be vertical or horizontal", + (char *) NULL); + *orientPtr = 0; + return TCL_ERROR; +} + +/* + *-------------------------------------------------------------- + * + * TkOrientPrintProc -- + * + * This procedure is invoked by the Tk configuration code + * to produce a printable string for the "-orient" + * configuration option. + * + * Results: + * The return value is a string describing the orientation for + * the item referred to by "widgRec". In addition, *freeProcPtr + * is filled in with the address of a procedure to call to free + * the result string when it's no longer needed (or NULL to + * indicate that the string doesn't need to be freed). + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +char * +TkOrientPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) + ClientData clientData; /* Ignored. */ + Tk_Window tkwin; /* Window containing canvas widget. */ + char *widgRec; /* Pointer to record for item. */ + int offset; /* Offset into item. */ + Tcl_FreeProc **freeProcPtr; /* Pointer to variable to fill in with + * information about how to reclaim + * storage for return string. */ +{ + register int *statePtr = (int *) (widgRec + offset); + + if (*statePtr) { + return "vertical"; + } else { + return "horizontal"; + } +} + +/* + *---------------------------------------------------------------------- + * + * TkOffsetParseProc -- + * + * Converts the offset of a stipple or tile into the Tk_TSOffset structure. + * + *---------------------------------------------------------------------- + */ + +int +TkOffsetParseProc(clientData, interp, tkwin, value, widgRec, offset) + ClientData clientData; /* not used */ + Tcl_Interp *interp; /* Interpreter to send results back to */ + Tk_Window tkwin; /* Window on same display as tile */ + CONST char *value; /* Name of image */ + char *widgRec; /* Widget structure record */ + int offset; /* Offset of tile in record */ +{ + Tk_TSOffset *offsetPtr = (Tk_TSOffset *)(widgRec + offset); + Tk_TSOffset tsoffset; + CONST char *q, *p; + int result; + + if ((value == NULL) || (*value == 0)) { + tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE; + goto goodTSOffset; + } + tsoffset.flags = 0; + p = value; + + switch(value[0]) { + case '#': + if (((int)clientData) & TK_OFFSET_RELATIVE) { + tsoffset.flags = TK_OFFSET_RELATIVE; + p++; break; + } + goto badTSOffset; + case 'e': + switch(value[1]) { + case '\0': + tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_MIDDLE; + goto goodTSOffset; + case 'n': + if (value[2]!='d' || value[3]!='\0') {goto badTSOffset;} + tsoffset.flags = INT_MAX; + goto goodTSOffset; + } + case 'w': + if (value[1] != '\0') {goto badTSOffset;} + tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_MIDDLE; + goto goodTSOffset; + case 'n': + if ((value[1] != '\0') && (value[2] != '\0')) { + goto badTSOffset; + } + switch(value[1]) { + case '\0': tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_TOP; + goto goodTSOffset; + case 'w': tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_TOP; + goto goodTSOffset; + case 'e': tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_TOP; + goto goodTSOffset; + } + goto badTSOffset; + case 's': + if ((value[1] != '\0') && (value[2] != '\0')) { + goto badTSOffset; + } + switch(value[1]) { + case '\0': tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_BOTTOM; + goto goodTSOffset; + case 'w': tsoffset.flags = TK_OFFSET_LEFT|TK_OFFSET_BOTTOM; + goto goodTSOffset; + case 'e': tsoffset.flags = TK_OFFSET_RIGHT|TK_OFFSET_BOTTOM; + goto goodTSOffset; + } + goto badTSOffset; + case 'c': + if (strncmp(value, "center", strlen(value)) != 0) { + goto badTSOffset; + } + tsoffset.flags = TK_OFFSET_CENTER|TK_OFFSET_MIDDLE; + goto goodTSOffset; + } + if ((q = strchr(p,',')) == NULL) { + if (((int)clientData) & TK_OFFSET_INDEX) { + if (Tcl_GetInt(interp, (char *) p, &tsoffset.flags) != TCL_OK) { + Tcl_ResetResult(interp); + goto badTSOffset; + } + tsoffset.flags |= TK_OFFSET_INDEX; + goto goodTSOffset; + } + goto badTSOffset; + } + *((char *) q) = 0; + result = Tk_GetPixels(interp, tkwin, (char *) p, &tsoffset.xoffset); + *((char *) q) = ','; + if (result != TCL_OK) { + return TCL_ERROR; + } + if (Tk_GetPixels(interp, tkwin, (char *) q+1, &tsoffset.yoffset) != TCL_OK) { + return TCL_ERROR; + } + + +goodTSOffset: + /* below is a hack to allow the stipple/tile offset to be stored + * in the internal tile structure. Most of the times, offsetPtr + * is a pointer to an already existing tile structure. However + * if this structure is not already created, we must do it + * with Tk_GetTile()!!!!; + */ + + memcpy(offsetPtr,&tsoffset, sizeof(Tk_TSOffset)); + return TCL_OK; + +badTSOffset: + Tcl_AppendResult(interp, "bad offset \"", value, + "\": expected \"x,y\"", (char *) NULL); + if (((int) clientData) & TK_OFFSET_RELATIVE) { + Tcl_AppendResult(interp, ", \"#x,y\"", (char *) NULL); + } + if (((int) clientData) & TK_OFFSET_INDEX) { + Tcl_AppendResult(interp, ", <index>", (char *) NULL); + } + Tcl_AppendResult(interp, ", n, ne, e, se, s, sw, w, nw, or center", + (char *) NULL); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * TkOffsetPrintProc -- + * + * Returns the offset of the tile. + * + * Results: + * The offset of the tile is returned. + * + *---------------------------------------------------------------------- + */ + +char * +TkOffsetPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) + ClientData clientData; /* not used */ + Tk_Window tkwin; /* not used */ + char *widgRec; /* Widget structure record */ + int offset; /* Offset of tile in record */ + Tcl_FreeProc **freeProcPtr; /* not used */ +{ + Tk_TSOffset *offsetPtr = (Tk_TSOffset *)(widgRec + offset); + char *p, *q; + + if ((offsetPtr->flags) & TK_OFFSET_INDEX) { + if ((offsetPtr->flags) >= INT_MAX) { + return "end"; + } + p = (char *) ckalloc(32); + sprintf(p, "%d",(offsetPtr->flags & (~TK_OFFSET_INDEX))); + *freeProcPtr = TCL_DYNAMIC; + return p; + } + if ((offsetPtr->flags) & TK_OFFSET_TOP) { + if ((offsetPtr->flags) & TK_OFFSET_LEFT) { + return "nw"; + } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) { + return "n"; + } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) { + return "ne"; + } + } else if ((offsetPtr->flags) & TK_OFFSET_MIDDLE) { + if ((offsetPtr->flags) & TK_OFFSET_LEFT) { + return "w"; + } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) { + return "center"; + } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) { + return "e"; + } + } else if ((offsetPtr->flags) & TK_OFFSET_BOTTOM) { + if ((offsetPtr->flags) & TK_OFFSET_LEFT) { + return "sw"; + } else if ((offsetPtr->flags) & TK_OFFSET_CENTER) { + return "s"; + } else if ((offsetPtr->flags) & TK_OFFSET_RIGHT) { + return "se"; + } + } + q = p = (char *) ckalloc(32); + if ((offsetPtr->flags) & TK_OFFSET_RELATIVE) { + *q++ = '#'; + } + sprintf(q, "%d,%d",offsetPtr->xoffset, offsetPtr->yoffset); + *freeProcPtr = TCL_DYNAMIC; + return p; +} + + +/* + *---------------------------------------------------------------------- + * + * TkPixelParseProc -- + * + * Converts the name of an image into a tile. + * + *---------------------------------------------------------------------- + */ + +int +TkPixelParseProc(clientData, interp, tkwin, value, widgRec, offset) + ClientData clientData; /* if non-NULL, negative values are + * allowed as well */ + Tcl_Interp *interp; /* Interpreter to send results back to */ + Tk_Window tkwin; /* Window on same display as tile */ + CONST char *value; /* Name of image */ + char *widgRec; /* Widget structure record */ + int offset; /* Offset of tile in record */ +{ + double *doublePtr = (double *)(widgRec + offset); + int result; + + result = TkGetDoublePixels(interp, tkwin, value, doublePtr); + + if ((result == TCL_OK) && (clientData == NULL) && (*doublePtr < 0.0)) { + Tcl_AppendResult(interp, "bad screen distance \"", value, + "\"", (char *) NULL); + return TCL_ERROR; + } + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TkPixelPrintProc -- + * + * Returns the name of the tile. + * + * Results: + * The name of the tile is returned. + * + *---------------------------------------------------------------------- + */ + +char * +TkPixelPrintProc(clientData, tkwin, widgRec, offset, freeProcPtr) + ClientData clientData; /* not used */ + Tk_Window tkwin; /* not used */ + char *widgRec; /* Widget structure record */ + int offset; /* Offset of tile in record */ + Tcl_FreeProc **freeProcPtr; /* not used */ +{ + double *doublePtr = (double *)(widgRec + offset); + char *p; + + p = (char *) ckalloc(24); + Tcl_PrintDouble((Tcl_Interp *) NULL, *doublePtr, p); + *freeProcPtr = TCL_DYNAMIC; + return p; +} + +/* *---------------------------------------------------------------------- * * TkDrawInsetFocusHighlight -- |