📄 tclmacresource.c
字号:
SetResLoad(false); fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision); SetResLoad(true); if (fileRef == -1) { err = ResError(); if (((err == fnfErr) || (err == eofErr)) && (macPermision == fsRdWrShPerm)) { /* * No resource fork existed for this file. Since we are * opening it for writing we will create the resource fork * now. */ HCreateResFile(fileSpec.vRefNum, fileSpec.parID, fileSpec.name); fileRef = (long) FSpOpenResFileCompat(&fileSpec, macPermision); if (fileRef == -1) { goto openError; } } else if (err == fnfErr) { Tcl_AppendStringsToObj(resultPtr, "file does not exist", (char *) NULL); return TCL_ERROR; } else if (err == eofErr) { Tcl_AppendStringsToObj(resultPtr, "file does not contain resource fork", (char *) NULL); return TCL_ERROR; } else { openError: Tcl_AppendStringsToObj(resultPtr, "error opening resource file", (char *) NULL); return TCL_ERROR; } } /* * The FspOpenResFile function does not set the ResFileAttrs. * Even if you open the file read only, the mapReadOnly * attribute is not set. This means we can't detect writes to a * read only resource fork until the write fails, which is bogus. * So set it here... */ if (macPermision == fsRdPerm) { SetResFileAttrs(fileRef, mapReadOnly); } Tcl_SetStringObj(resultPtr, "", 0); if (TclMacRegisterResourceFork(fileRef, resultPtr, TCL_RESOURCE_CHECK_IF_OPEN) != TCL_OK) { CloseResFile(fileRef); return TCL_ERROR; } return TCL_OK; case RESOURCE_READ: if (!((objc == 4) || (objc == 5))) { Tcl_WrongNumArgs(interp, 2, objv, "resourceType resourceId ?resourceRef?"); return TCL_ERROR; } if (Tcl_GetOSTypeFromObj(interp, objv[2], &rezType) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetLongFromObj((Tcl_Interp *) NULL, objv[3], &rsrcId) != TCL_OK) { resourceId = Tcl_GetStringFromObj(objv[3], &length); } if (objc == 5) { stringPtr = Tcl_GetStringFromObj(objv[4], &length); } else { stringPtr = NULL; } resource = Tcl_MacFindResource(interp, rezType, resourceId, rsrcId, stringPtr, &releaseIt); if (resource != NULL) { size = GetResourceSizeOnDisk(resource); Tcl_SetStringObj(resultPtr, *resource, size); /* * Don't release the resource unless WE loaded it... */ if (releaseIt) { ReleaseResource(resource); } return TCL_OK; } else { Tcl_AppendStringsToObj(resultPtr, "could not load resource", (char *) NULL); return TCL_ERROR; } case RESOURCE_TYPES: if (!((objc == 2) || (objc == 3))) { Tcl_WrongNumArgs(interp, 2, objv, "?resourceRef?"); return TCL_ERROR; } if (objc == 3) { resourceRef = GetRsrcRefFromObj(objv[2], 1, "get types of", resultPtr); if (resourceRef == NULL) { return TCL_ERROR; } saveRef = CurResFile(); UseResFile((short) resourceRef->fileRef); limitSearch = true; } if (limitSearch) { count = Count1Types(); } else { count = CountTypes(); } for (i = 1; i <= count; i++) { if (limitSearch) { Get1IndType((ResType *) &rezType, i); } else { GetIndType((ResType *) &rezType, i); } objPtr = Tcl_NewOSTypeObj(rezType); result = Tcl_ListObjAppendElement(interp, resultPtr, objPtr); if (result != TCL_OK) { Tcl_DecrRefCount(objPtr); break; } } if (limitSearch) { UseResFile(saveRef); } return result; case RESOURCE_WRITE: if ((objc < 4) || (objc > 11)) { Tcl_WrongNumArgs(interp, 2, objv, "?-id resourceId? ?-name resourceName? ?-file resourceRef?\ ?-force? resourceType data"); return TCL_ERROR; } i = 2; gotInt = false; resourceId = NULL; limitSearch = false; force = 0; while (i < (objc - 2)) { if (Tcl_GetIndexFromObj(interp, objv[i], writeSwitches, "switch", 0, &index) != TCL_OK) { return TCL_ERROR; } switch (index) { case RESOURCE_WRITE_ID: if (Tcl_GetLongFromObj(interp, objv[i+1], &rsrcId) != TCL_OK) { return TCL_ERROR; } gotInt = true; i += 2; break; case RESOURCE_WRITE_NAME: resourceId = Tcl_GetStringFromObj(objv[i+1], &length); strcpy((char *) theName, resourceId); resourceId = (char *) theName; c2pstr(resourceId); i += 2; break; case RESOURCE_WRITE_FILE: resourceRef = GetRsrcRefFromObj(objv[i+1], 0, "write to", resultPtr); if (resourceRef == NULL) { return TCL_ERROR; } limitSearch = true; i += 2; break; case RESOURCE_FORCE: force = 1; i += 1; break; } } if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) { return TCL_ERROR; } stringPtr = Tcl_GetStringFromObj(objv[i+1], &length); if (gotInt == false) { rsrcId = UniqueID(rezType); } if (resourceId == NULL) { resourceId = (char *) "\p"; } if (limitSearch) { saveRef = CurResFile(); UseResFile((short) resourceRef->fileRef); } /* * If we are adding the resource by number, then we must make sure * there is not already a resource of that number. We are not going * load it here, since we want to detect whether we loaded it or * not. Remember that releasing some resources in particular menu * related ones, can be fatal. */ if (gotInt == true) { SetResLoad(false); resource = Get1Resource(rezType,rsrcId); SetResLoad(true); } if (resource == NULL) { /* * We get into this branch either if there was not already a * resource of this type & id, or the id was not specified. */ resource = NewHandle(length); if (resource == NULL) { resource = NewHandleSys(length); if (resource == NULL) { panic("could not allocate memory to write resource"); } } HLock(resource); memcpy(*resource, stringPtr, length); HUnlock(resource); AddResource(resource, rezType, (short) rsrcId, (StringPtr) resourceId); releaseIt = 1; } else { /* * We got here because there was a resource of this type * & ID in the file. */ if (*resource == NULL) { releaseIt = 1; } else { releaseIt = 0; } if (!force) { /* *We only overwrite extant resources * when the -force flag has been set. */ sprintf(errbuf,"%d", rsrcId); Tcl_AppendStringsToObj(resultPtr, "the resource ", errbuf, " already exists, use \"-force\"", " to overwrite it.", (char *) NULL); result = TCL_ERROR; goto writeDone; } else if (GetResAttrs(resource) & resProtected) { /* * * Next, check to see if it is protected... */ sprintf(errbuf,"%d", rsrcId); Tcl_AppendStringsToObj(resultPtr, "could not write resource id ", errbuf, " of type ", Tcl_GetStringFromObj(objv[i],&length), ", it was protected.",(char *) NULL); result = TCL_ERROR; goto writeDone; } else { /* * Be careful, the resource might already be in memory * if something else loaded it. */ if (*resource == 0) { LoadResource(resource); err = ResError(); if (err != noErr) { sprintf(errbuf,"%d", rsrcId); Tcl_AppendStringsToObj(resultPtr, "error loading resource ", errbuf, " of type ", Tcl_GetStringFromObj(objv[i],&length), " to overwrite it", (char *) NULL); goto writeDone; } } SetHandleSize(resource, length); if ( MemError() != noErr ) { panic("could not allocate memory to write resource"); } HLock(resource); memcpy(*resource, stringPtr, length); HUnlock(resource); ChangedResource(resource); /* * We also may have changed the name... */ SetResInfo(resource, rsrcId, (StringPtr) resourceId); } } err = ResError(); if (err != noErr) { Tcl_AppendStringsToObj(resultPtr, "error adding resource to resource map", (char *) NULL); result = TCL_ERROR; goto writeDone; } WriteResource(resource); err = ResError(); if (err != noErr) { Tcl_AppendStringsToObj(resultPtr, "error writing resource to disk", (char *) NULL); result = TCL_ERROR; } writeDone: if (releaseIt) { ReleaseResource(resource); err = ResError(); if (err != noErr) { Tcl_AppendStringsToObj(resultPtr, "error releasing resource", (char *) NULL); result = TCL_ERROR; } } if (limitSearch) { UseResFile(saveRef); } return result; default: panic("Tcl_GetIndexFromObject returned unrecognized option"); return TCL_ERROR; /* Should never be reached. */ }}/* *---------------------------------------------------------------------- * * Tcl_MacSourceObjCmd -- * * This procedure is invoked to process the "source" Tcl command. * See the user documentation for details on what it does. In * addition, it supports sourceing from the resource fork of * type 'TEXT'. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intTcl_MacSourceObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *CONST objv[]) /* Argument objects. */{ char *errNum = "wrong # args: "; char *errBad = "bad argument: "; char *errStr; char *fileName = NULL, *rsrcName = NULL; long rsrcID = -1; char *string; int length; if (objc < 2 || objc > 4) { errStr = errNum; goto sourceFmtErr; } if (objc == 2) { string = TclGetStringFromObj(objv[1], &length); return Tcl_EvalFile(interp, string); } /* * The following code supports a few older forms of this command * for backward compatability. */ string = TclGetStringFromObj(objv[1], &length); if (!strcmp(string, "-rsrc") || !strcmp(string, "-rsrcname")) { rsrcName = TclGetStringFromObj(objv[2], &length); } else if (!strcmp(string, "-rsrcid")) { if (Tcl_GetLongFromObj(interp, objv[2], &rsrcID) != TCL_OK) { return TCL_ERROR; } } else { errStr = errBad; goto sourceFmtErr; } if (objc == 4) { fileName = TclGetStringFromObj(objv[3], &length); } return Tcl_MacEvalResource(interp, rsrcName, rsrcID, fileName); sourceFmtErr: Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), errStr, "should be \"", Tcl_GetStringFromObj(objv[0], (int *) NULL), " fileName\" or \"", Tcl_GetStringFromObj(objv[0], (int *) NULL), " -rsrc name ?fileName?\" or \"", Tcl_GetStringFromObj(objv[0], (int *) NULL), " -rsrcid id ?fileName?\"", (char *) NULL); return TCL_ERROR;}/* *---------------------------------------------------------------------- * * Tcl_BeepObjCmd -- * * This procedure makes the beep sound. * * Results: * A standard Tcl result. * * Side effects: * Makes a beep. * *---------------------------------------------------------------------- */intTcl_BeepObjCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *CONST objv[]) /* Argument values. */{ Tcl_Obj *resultPtr, *objPtr; Handle sound; Str255 sndName; int volume = -1, length; char * sndArg = NULL; resultPtr = Tcl_GetObjResult(interp); if (objc == 1) { SysBeep(1); return TCL_OK; } else if (objc == 2) { if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-list")) { int count, i; short id; Str255 theName; ResType rezType; count = CountResources('snd '); for (i = 1; i <= count; i++) { sound = GetIndResource('snd ', i); if (sound != NULL) { GetResInfo(sound, &id, &rezType, theName); if (theName[0] == 0) { continue; } objPtr = Tcl_NewStringObj((char *) theName + 1, theName[0]); Tcl_ListObjAppendElement(interp, resultPtr, objPtr); } } return TCL_OK; } else { sndArg = Tcl_GetStringFromObj(objv[1], &length); } } else if (objc == 3) { if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-volume")) { Tcl_GetIntFromObj(interp, objv[2], &volume); } else { goto beepUsage; } } else if (objc == 4) { if (!strcmp(Tcl_GetStringFromObj(objv[1], &length), "-volume")) { Tcl_GetIntFromObj(interp, objv[2], &volume); sndArg = Tcl_GetStringFromObj(objv[3], &length); } else { goto beepUsage; } } else { goto beepUsage; } /* * Play the sound */ if (sndArg == NULL) { /* * Set Volume for SysBeep */ if (volume >= 0) { SetSoundVolume(volume, SYS_BEEP_VOLUME); } SysBeep(1); /* * Reset Volume */ if (volume >= 0) { SetSoundVolume(0, RESET_VOLUME); } } else { strcpy((char *) sndName + 1, sndArg); sndName[0] = length; sound = GetNamedResource('snd ', sndName); if (sound != NULL) { /* * Set Volume for Default Output device */ if (volume >= 0) { SetSoundVolume(volume, DEFAULT_SND_VOLUME); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -