📄 tclmacresource.c
字号:
SndPlay(NULL, (SndListHandle) sound, false); /* * Reset Volume */ if (volume >= 0) { SetSoundVolume(0, RESET_VOLUME); } } else { Tcl_AppendStringsToObj(resultPtr, " \"", sndArg, "\" is not a valid sound. (Try ", Tcl_GetStringFromObj(objv[0], (int *) NULL), " -list)", NULL); return TCL_ERROR; } } return TCL_OK; beepUsage: Tcl_WrongNumArgs(interp, 1, objv, "[-volume num] [-list | sndName]?"); return TCL_ERROR;}/* *----------------------------------------------------------------------------- * * SetSoundVolume -- * * Set the volume for either the SysBeep or the SndPlay call depending * on the value of mode (SYS_BEEP_VOLUME or DEFAULT_SND_VOLUME * respectively. * * It also stores the last channel set, and the old value of its * VOLUME. If you call SetSoundVolume with a mode of RESET_VOLUME, * it will undo the last setting. The volume parameter is * ignored in this case. * * Side Effects: * Sets the System Volume * * Results: * None * *----------------------------------------------------------------------------- */voidSetSoundVolume( int volume, /* This is the new volume */ enum WhichVolume mode) /* This flag says which volume to * set: SysBeep, SndPlay, or instructs us * to reset the volume */{ static int hasSM3 = -1; static enum WhichVolume oldMode; static long oldVolume = -1; /* * The volume setting calls only work if we have SoundManager * 3.0 or higher. So we check that here. */ if (hasSM3 == -1) { if (GetToolboxTrapAddress(_SoundDispatch) != GetToolboxTrapAddress(_Unimplemented)) { NumVersion SMVers = SndSoundManagerVersion(); if (SMVers.majorRev > 2) { hasSM3 = 1; } else { hasSM3 = 0; } } else { /* * If the SoundDispatch trap is not present, then * we don't have the SoundManager at all. */ hasSM3 = 0; } } /* * If we don't have Sound Manager 3.0, we can't set the sound volume. * We will just ignore the request rather than raising an error. */ if (!hasSM3) { return; } switch (mode) { case SYS_BEEP_VOLUME: GetSysBeepVolume(&oldVolume); SetSysBeepVolume(volume); oldMode = SYS_BEEP_VOLUME; break; case DEFAULT_SND_VOLUME: GetDefaultOutputVolume(&oldVolume); SetDefaultOutputVolume(volume); oldMode = DEFAULT_SND_VOLUME; break; case RESET_VOLUME: /* * If oldVolume is -1 someone has made a programming error * and called reset before setting the volume. This is benign * however, so we will just exit. */ if (oldVolume != -1) { if (oldMode == SYS_BEEP_VOLUME) { SetSysBeepVolume(oldVolume); } else if (oldMode == DEFAULT_SND_VOLUME) { SetDefaultOutputVolume(oldVolume); } } oldVolume = -1; }}/* *----------------------------------------------------------------------------- * * Tcl_MacEvalResource -- * * Used to extend the source command. Sources Tcl code from a Text * resource. Currently only sources the resouce by name file ID may be * supported at a later date. * * Side Effects: * Depends on the Tcl code in the resource. * * Results: * Returns a Tcl result. * *----------------------------------------------------------------------------- */intTcl_MacEvalResource( Tcl_Interp *interp, /* Interpreter in which to process file. */ char *resourceName, /* Name of TEXT resource to source, NULL if number should be used. */ int resourceNumber, /* Resource id of source. */ char *fileName) /* Name of file to process. NULL if application resource. */{ Handle sourceText; Str255 rezName; char msg[200]; int result, iOpenedResFile = false; short saveRef, fileRef = -1; char idStr[64]; FSSpec fileSpec; Tcl_DString buffer; char *nativeName; saveRef = CurResFile(); if (fileName != NULL) { OSErr err; nativeName = Tcl_TranslateFileName(interp, fileName, &buffer); if (nativeName == NULL) { return TCL_ERROR; } err = FSpLocationFromPath(strlen(nativeName), nativeName, &fileSpec); Tcl_DStringFree(&buffer); if (err != noErr) { Tcl_AppendResult(interp, "Error finding the file: \"", fileName, "\".", NULL); return TCL_ERROR; } fileRef = FSpOpenResFileCompat(&fileSpec, fsRdPerm); if (fileRef == -1) { Tcl_AppendResult(interp, "Error reading the file: \"", fileName, "\".", NULL); return TCL_ERROR; } UseResFile(fileRef); iOpenedResFile = true; } else { /* * The default behavior will search through all open resource files. * This may not be the behavior you desire. If you want the behavior * of this call to *only* search the application resource fork, you * must call UseResFile at this point to set it to the application * file. This means you must have already obtained the application's * fileRef when the application started up. */ } /* * Load the resource by name or ID */ if (resourceName != NULL) { strcpy((char *) rezName + 1, resourceName); rezName[0] = strlen(resourceName); sourceText = GetNamedResource('TEXT', rezName); } else { sourceText = GetResource('TEXT', (short) resourceNumber); } if (sourceText == NULL) { result = TCL_ERROR; } else { char *sourceStr = NULL; HLock(sourceText); sourceStr = Tcl_MacConvertTextResource(sourceText); HUnlock(sourceText); ReleaseResource(sourceText); /* * We now evaluate the Tcl source */ result = Tcl_Eval(interp, sourceStr); ckfree(sourceStr); if (result == TCL_RETURN) { result = TCL_OK; } else if (result == TCL_ERROR) { sprintf(msg, "\n (rsrc \"%.150s\" line %d)", resourceName, interp->errorLine); Tcl_AddErrorInfo(interp, msg); } goto rezEvalCleanUp; } rezEvalError: sprintf(idStr, "ID=%d", resourceNumber); Tcl_AppendResult(interp, "The resource \"", (resourceName != NULL ? resourceName : idStr), "\" could not be loaded from ", (fileName != NULL ? fileName : "application"), ".", NULL); rezEvalCleanUp: /* * TRICKY POINT: The code that you are sourcing here could load a * shared library. This will go AHEAD of the resource we stored away * in saveRef on the resource path. * If you restore the saveRef in this case, you will never be able * to get to the resources in the shared library, since you are now * pointing too far down on the resource list. * So, we only reset the current resource file if WE opened a resource * explicitly, and then only if the CurResFile is still the * one we opened... */ if (iOpenedResFile && (CurResFile() == fileRef)) { UseResFile(saveRef); } if (fileRef != -1) { CloseResFile(fileRef); } return result;}/* *----------------------------------------------------------------------------- * * Tcl_MacConvertTextResource -- * * Converts a TEXT resource into a Tcl suitable string. * * Side Effects: * Mallocs the returned memory, converts '\r' to '\n', and appends a NULL. * * Results: * A new malloced string. * *----------------------------------------------------------------------------- */char *Tcl_MacConvertTextResource( Handle resource) /* Handle to TEXT resource. */{ int i, size; char *resultStr; size = GetResourceSizeOnDisk(resource); resultStr = ckalloc(size + 1); for (i=0; i<size; i++) { if ((*resource)[i] == '\r') { resultStr[i] = '\n'; } else { resultStr[i] = (*resource)[i]; } } resultStr[size] = '\0'; return resultStr;}/* *----------------------------------------------------------------------------- * * Tcl_MacFindResource -- * * Higher level interface for loading resources. * * Side Effects: * Attempts to load a resource. * * Results: * A handle on success. * *----------------------------------------------------------------------------- */HandleTcl_MacFindResource( Tcl_Interp *interp, /* Interpreter in which to process file. */ long resourceType, /* Type of resource to load. */ char *resourceName, /* Name of resource to find, * NULL if number should be used. */ int resourceNumber, /* Resource id of source. */ char *resFileRef, /* Registered resource file reference, * NULL if searching all open resource files. */ int *releaseIt) /* Should we release this resource when done. */{ Tcl_HashEntry *nameHashPtr; OpenResourceFork *resourceRef; int limitSearch = false; short saveRef; Handle resource; if (resFileRef != NULL) { nameHashPtr = Tcl_FindHashEntry(&nameTable, resFileRef); if (nameHashPtr == NULL) { Tcl_AppendResult(interp, "invalid resource file reference \"", resFileRef, "\"", (char *) NULL); return NULL; } resourceRef = (OpenResourceFork *) Tcl_GetHashValue(nameHashPtr); saveRef = CurResFile(); UseResFile((short) resourceRef->fileRef); limitSearch = true; } /* * Some system resources (for example system resources) should not * be released. So we set autoload to false, and try to get the resource. * If the Master Pointer of the returned handle is null, then resource was * not in memory, and it is safe to release it. Otherwise, it is not. */ SetResLoad(false); if (resourceName == NULL) { if (limitSearch) { resource = Get1Resource(resourceType, resourceNumber); } else { resource = GetResource(resourceType, resourceNumber); } } else { c2pstr(resourceName); if (limitSearch) { resource = Get1NamedResource(resourceType, (StringPtr) resourceName); } else { resource = GetNamedResource(resourceType, (StringPtr) resourceName); } p2cstr((StringPtr) resourceName); } if (*resource == NULL) { *releaseIt = 1; LoadResource(resource); } else { *releaseIt = 0; } SetResLoad(true); if (limitSearch) { UseResFile(saveRef); } return resource;}/* *---------------------------------------------------------------------- * * ResourceInit -- * * Initialize the structures used for resource management. * * Results: * None. * * Side effects: * Read the code. * *---------------------------------------------------------------------- */static voidResourceInit(){ initialized = 1; Tcl_InitHashTable(&nameTable, TCL_STRING_KEYS); Tcl_InitHashTable(&resourceTable, TCL_ONE_WORD_KEYS); resourceForkList = Tcl_NewObj(); Tcl_IncrRefCount(resourceForkList); BuildResourceForkList(); }/***//*Tcl_RegisterObjType(typePtr) *//* *---------------------------------------------------------------------- * * Tcl_NewOSTypeObj -- * * This procedure is used to create a new resource name type object. * * Results: * The newly created object is returned. This object will have a NULL * string representation. The returned object has ref count 0. * * Side effects: * None. * *---------------------------------------------------------------------- */Tcl_Obj *Tcl_NewOSTypeObj( OSType newOSType) /* Int used to initialize the new object. */{ register Tcl_Obj *objPtr; if (!osTypeInit) { osTypeInit = 1; Tcl_RegisterObjType(&osType); } objPtr = Tcl_NewObj(); objPtr->bytes = NULL; objPtr->internalRep.longValue = newOSType; objPtr->typePtr = &osType; return objPtr;}/* *---------------------------------------------------------------------- * * Tcl_SetOSTypeObj -- * * Modify an object to be a resource type and to have the * specified long value. * * Results: * None. * * Side effects: * The object's old string rep, if any, is freed. Also, any old * internal rep is freed. * *---------------------------------------------------------------------- */voidTcl_SetOSTypeObj( Tcl_Obj *objPtr, /* Object whose internal rep to init. */ OSType newOSType) /* Integer used to set object's value. */{ register Tcl_ObjType *oldTypePtr = objPtr->typePtr; if (!osTypeInit) { osTypeInit = 1; Tcl_RegisterObjType(&osType); } Tcl_InvalidateStringRep(objPtr); if ((oldTypePtr != NULL) && (oldTypePtr->freeIntRepProc != NULL)) { oldTypePtr->freeIntRepProc(objPtr); } objPtr->internalRep.longValue = newOSType; objPtr->typePtr = &osType;}/* *---------------------------------------------------------------------- * * Tcl_GetOSTypeFromObj -- * * Attempt to return an int from the Tcl object "objPtr". If the object * is not already an int, an attempt will be made to convert it to one. * * Results: * The return value is a standard Tcl object result. If an error occurs * during conversion, an error message is left in interp->objResult * unless "interp" is NULL. * * Side effects: * If the object is not already an int, the conversion will free * any old internal representation. * *---------------------------------------------------------------------- */intTcl_GetOSTypeFromObj( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr, /* The object from which to get a int. */ OSType *osTypePtr) /* Place to store resulting int. */{ register int result; if (!osTypeInit) { osTypeInit = 1; Tcl_RegisterObjType(&osType); } if (objPtr->typePtr == &osType) { *osTypePtr = objPtr->internalRep.longValue; return TCL_OK; } result = SetOSTypeFromAny(interp, objPtr); if (result == TCL_OK) { *osTypePtr = objPtr->internalRep.longValue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -