⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclmacresource.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * tclMacResource.c -- * *	This file contains several commands that manipulate or use *	Macintosh resources.  Included are extensions to the "source" *	command, the mac specific "beep" and "resource" commands, and *	administration for open resource file references. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclMacResource.c 1.35 97/11/24 15:03:58 */#include <Errors.h>#include <FSpCompat.h>#include <Processes.h>#include <Resources.h>#include <Sound.h>#include <Strings.h>#include <Traps.h>#include <LowMem.h>#include "FullPath.h"#include "tcl.h"#include "tclInt.h"#include "tclMac.h"#include "tclMacInt.h"#include "tclMacPort.h"/* * This flag tells the RegisterResource function to insert the * resource into the tail of the resource fork list.  Needed only * Resource_Init. */ #define TCL_RESOURCE_INSERT_TAIL 1/* * 2 is taken by TCL_RESOURCE_DONT_CLOSE * which is the only public flag to TclMacRegisterResourceFork. */ #define TCL_RESOURCE_CHECK_IF_OPEN 4/* * Pass this in the mode parameter of SetSoundVolume to determine * which volume to set. */enum WhichVolume {    SYS_BEEP_VOLUME,    /* This sets the volume for SysBeep calls */     DEFAULT_SND_VOLUME, /* This one for SndPlay calls */    RESET_VOLUME        /* And this undoes the last call to SetSoundVolume */}; /* * Hash table to track open resource files. */typedef struct OpenResourceFork {    short fileRef;    int   flags;} OpenResourceFork;static Tcl_HashTable nameTable;		/* Id to process number mapping. */static Tcl_HashTable resourceTable;	/* Process number to id mapping. */static Tcl_Obj *resourceForkList;       /* Ordered list of resource forks */static int appResourceIndex;            /* This is the index of the application*					 * in the list of resource forks */static int newId = 0;			/* Id source. */static int initialized = 0;		/* 0 means static structures haven't 					 * been initialized yet. */static int osTypeInit = 0;		/* 0 means Tcl object of osType hasn't 					 * been initialized yet. *//* * Prototypes for procedures defined later in this file: */static void		DupOSTypeInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr,			    Tcl_Obj *copyPtr));static void		ResourceInit _ANSI_ARGS_((void));static void             BuildResourceForkList _ANSI_ARGS_((void));static int		SetOSTypeFromAny _ANSI_ARGS_((Tcl_Interp *interp,			    Tcl_Obj *objPtr));static void		UpdateStringOfOSType _ANSI_ARGS_((Tcl_Obj *objPtr));static OpenResourceFork* GetRsrcRefFromObj _ANSI_ARGS_((Tcl_Obj *objPtr,		                int okayOnReadOnly, const char *operation,	                        Tcl_Obj *resultPtr));static void 		SetSoundVolume(int volume, enum WhichVolume mode);/* * The structures below defines the Tcl object type defined in this file by * means of procedures that can be invoked by generic object code. */static Tcl_ObjType osType = {    "ostype",				/* name */    (Tcl_FreeInternalRepProc *) NULL,   /* freeIntRepProc */    DupOSTypeInternalRep,	        /* dupIntRepProc */    UpdateStringOfOSType,		/* updateStringProc */    SetOSTypeFromAny			/* setFromAnyProc */};/* *---------------------------------------------------------------------- * * Tcl_ResourceObjCmd -- * *	This procedure is invoked to process the "resource" Tcl command. *	See the user documentation for details on what it does. * * Results: *	A standard Tcl result. * * Side effects: *	See the user documentation. * *---------------------------------------------------------------------- */intTcl_ResourceObjCmd(    ClientData clientData,		/* Not used. */    Tcl_Interp *interp,			/* Current interpreter. */    int objc,				/* Number of arguments. */    Tcl_Obj *CONST objv[])		/* Argument values. */{    Tcl_Obj *resultPtr, *objPtr;    int index, result;    long fileRef, rsrcId;    FSSpec fileSpec;    Tcl_DString buffer;    char *nativeName;    char *stringPtr;    char errbuf[16];    OpenResourceFork *resourceRef;    Handle resource = NULL;    OSErr err;    int count, i, limitSearch = false, length;    short id, saveRef, resInfo;    Str255 theName;    OSType rezType;    int gotInt, releaseIt = 0, force;    char *resourceId = NULL;	    long size;    char macPermision;    int mode;    static char *switches[] = {"close", "delete" ,"files", "list",             "open", "read", "types", "write", (char *) NULL    };	            enum {            RESOURCE_CLOSE, RESOURCE_DELETE, RESOURCE_FILES, RESOURCE_LIST,             RESOURCE_OPEN, RESOURCE_READ, RESOURCE_TYPES, RESOURCE_WRITE    };                  static char *writeSwitches[] = {            "-id", "-name", "-file", "-force", (char *) NULL    };                enum {            RESOURCE_WRITE_ID, RESOURCE_WRITE_NAME,             RESOURCE_WRITE_FILE, RESOURCE_FORCE    };                static char *deleteSwitches[] = {"-id", "-name", "-file", (char *) NULL};                 enum {RESOURCE_DELETE_ID, RESOURCE_DELETE_NAME, RESOURCE_DELETE_FILE};    resultPtr = Tcl_GetObjResult(interp);        if (objc < 2) {	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");	return TCL_ERROR;    }    if (Tcl_GetIndexFromObj(interp, objv[1], switches, "option", 0, &index)	    != TCL_OK) {	return TCL_ERROR;    }    if (!initialized) {	ResourceInit();    }    result = TCL_OK;    switch (index) {	case RESOURCE_CLOSE:				    if (objc != 3) {		Tcl_WrongNumArgs(interp, 2, objv, "resourceRef");		return TCL_ERROR;	    }	    stringPtr = Tcl_GetStringFromObj(objv[2], &length);	    fileRef = TclMacUnRegisterResourceFork(stringPtr, resultPtr);	    	    if (fileRef >= 0) {	        CloseResFile((short) fileRef);	        return TCL_OK;	    } else {	        return TCL_ERROR;	    }	case RESOURCE_DELETE:	    if (!((objc >= 3) && (objc <= 9) && ((objc % 2) == 1))) {		Tcl_WrongNumArgs(interp, 2, objv, 		    "?-id resourceId? ?-name resourceName? ?-file \resourceRef? resourceType");		return TCL_ERROR;	    }	    	    i = 2;	    fileRef = -1;	    gotInt = false;	    resourceId = NULL;	    limitSearch = false;	    while (i < (objc - 2)) {		if (Tcl_GetIndexFromObj(interp, objv[i], deleteSwitches,			"option", 0, &index) != TCL_OK) {		    return TCL_ERROR;		}		switch (index) {		    case RESOURCE_DELETE_ID:					if (Tcl_GetLongFromObj(interp, objv[i+1], &rsrcId)				!= TCL_OK) {			    return TCL_ERROR;			}			gotInt = true;			break;		    case RESOURCE_DELETE_NAME:					resourceId = Tcl_GetStringFromObj(objv[i+1], &length);			if (length > 255) {			    Tcl_AppendStringsToObj(resultPtr,"-name argument ",			            "too long, must be < 255 characters",			            (char *) NULL);			    return TCL_ERROR;			}			strcpy((char *) theName, resourceId);			resourceId = (char *) theName;			c2pstr(resourceId);			break;		    case RESOURCE_DELETE_FILE:		        resourceRef = GetRsrcRefFromObj(objv[i+1], 0, 		                "delete from", resultPtr);		        if (resourceRef == NULL) {		            return TCL_ERROR;		        }				limitSearch = true;			break;		}		i += 2;	    }	    	    if ((resourceId == NULL) && !gotInt) {		Tcl_AppendStringsToObj(resultPtr,"you must specify either ",		        "\"-id\" or \"-name\" or both ",		        "to \"resource delete\"",		        (char *) NULL);	        return TCL_ERROR;            }	    if (Tcl_GetOSTypeFromObj(interp, objv[i], &rezType) != TCL_OK) {		return TCL_ERROR;	    }	    if (limitSearch) {		saveRef = CurResFile();		UseResFile((short) resourceRef->fileRef);	    }	    	    SetResLoad(false);	    	    if (gotInt == true) {	        if (limitSearch) {		    resource = Get1Resource(rezType, rsrcId);		} else {		    resource = GetResource(rezType, rsrcId);		}                err = ResError();                            if (err == resNotFound || resource == NULL) {	            Tcl_AppendStringsToObj(resultPtr, "resource not found",	                (char *) NULL);	            result = TCL_ERROR;	            goto deleteDone;                               } else if (err != noErr) {                    char buffer[16];                                    sprintf(buffer, "%12d", err);	            Tcl_AppendStringsToObj(resultPtr, "resource error #",	                    buffer, "occured while trying to find resource",	                    (char *) NULL);	            result = TCL_ERROR;	            goto deleteDone;               	        }	    } 	    	    if (resourceId != NULL) {	        Handle tmpResource;	        if (limitSearch) {	            tmpResource = Get1NamedResource(rezType,			    (StringPtr) resourceId);	        } else {	            tmpResource = GetNamedResource(rezType,			    (StringPtr) resourceId);	        }                err = ResError();                            if (err == resNotFound || tmpResource == NULL) {	            Tcl_AppendStringsToObj(resultPtr, "resource not found",	                (char *) NULL);	            result = TCL_ERROR;	            goto deleteDone;                               } else if (err != noErr) {                    char buffer[16];                                    sprintf(buffer, "%12d", err);	            Tcl_AppendStringsToObj(resultPtr, "resource error #",	                    buffer, "occured while trying to find resource",	                    (char *) NULL);	            result = TCL_ERROR;	            goto deleteDone;               	        }	        	        if (gotInt) { 	            if (resource != tmpResource) {	                Tcl_AppendStringsToObj(resultPtr,				"\"-id\" and \"-name\" ",	                        "values do not point to the same resource",	                        (char *) NULL);	                result = TCL_ERROR;	                goto deleteDone;	            }	        } else {	            resource = tmpResource;	        }	    }	               	    resInfo = GetResAttrs(resource);	    	    if ((resInfo & resProtected) == resProtected) {	        Tcl_AppendStringsToObj(resultPtr, "resource ",	                "cannot be deleted: it is protected.",	                (char *) NULL);	        result = TCL_ERROR;	        goto deleteDone;               	    } else if ((resInfo & resSysHeap) == resSysHeap) {   	        Tcl_AppendStringsToObj(resultPtr, "resource",	                "cannot be deleted: it is in the system heap.",	                (char *) NULL);	        result = TCL_ERROR;	        goto deleteDone;               	    }	    	    /*	     * Find the resource file, if it was not specified,	     * so we can flush the changes now.  Perhaps this is	     * a little paranoid, but better safe than sorry.	     */	     	    RemoveResource(resource);	    	    if (!limitSearch) {	        UpdateResFile(HomeResFile(resource));	    } else {	        UpdateResFile(resourceRef->fileRef);	    }	    	    	    deleteDone:	                SetResLoad(true);	    if (limitSearch) {                 UseResFile(saveRef);                        	    }	    return result;	    	case RESOURCE_FILES:	    if ((objc < 2) || (objc > 3)) {		Tcl_SetStringObj(resultPtr,		        "wrong # args: should be \"resource files \?resourceId?\"", -1);		return TCL_ERROR;	    }	    	    if (objc == 2) {	        stringPtr = Tcl_GetStringFromObj(resourceForkList, &length);	        Tcl_SetStringObj(resultPtr, stringPtr, length);	    } else {                FCBPBRec fileRec;                Handle pathHandle;                short pathLength;                Str255 fileName;	        	        if (strcmp(Tcl_GetStringFromObj(objv[2], NULL), "ROM Map")			    == 0) {	            Tcl_SetStringObj(resultPtr,"no file path for ROM Map", -1);	            return TCL_ERROR;	        }	        	        resourceRef = GetRsrcRefFromObj(objv[2], 1, "files", resultPtr);	        if (resourceRef == NULL) {	            return TCL_ERROR;	        }                fileRec.ioCompletion = NULL;                fileRec.ioFCBIndx = 0;                fileRec.ioNamePtr = fileName;                fileRec.ioVRefNum = 0;                fileRec.ioRefNum = resourceRef->fileRef;                err = PBGetFCBInfo(&fileRec, false);                if (err != noErr) {                    Tcl_SetStringObj(resultPtr,                            "could not get FCB for resource file", -1);                    return TCL_ERROR;                }                                err = GetFullPath(fileRec.ioFCBVRefNum, fileRec.ioFCBParID,                        fileRec.ioNamePtr, &pathLength, &pathHandle);                if ( err != noErr) {                    Tcl_SetStringObj(resultPtr,                            "could not get file path from token", -1);                    return TCL_ERROR;                }                                HLock(pathHandle);                Tcl_SetStringObj(resultPtr,*pathHandle,pathLength);                HUnlock(pathHandle);                DisposeHandle(pathHandle);            }                    	    	    return TCL_OK;	case RESOURCE_LIST:				    if (!((objc == 3) || (objc == 4))) {		Tcl_WrongNumArgs(interp, 2, objv, "resourceType ?resourceRef?");		return TCL_ERROR;	    }	    if (Tcl_GetOSTypeFromObj(interp, objv[2], &rezType) != TCL_OK) {		return TCL_ERROR;	    }	    if (objc == 4) {	        resourceRef = GetRsrcRefFromObj(objv[3], 1, 		                "list", resultPtr);		if (resourceRef == NULL) {		    return TCL_ERROR;		}			saveRef = CurResFile();		UseResFile((short) resourceRef->fileRef);		limitSearch = true;	    }	    Tcl_ResetResult(interp);	    if (limitSearch) {		count = Count1Resources(rezType);	    } else {		count = CountResources(rezType);	    }	    SetResLoad(false);	    for (i = 1; i <= count; i++) {		if (limitSearch) {		    resource = Get1IndResource(rezType, i);		} else {		    resource = GetIndResource(rezType, i);		}		if (resource != NULL) {		    GetResInfo(resource, &id, (ResType *) &rezType, theName);		    if (theName[0] != 0) {			objPtr = Tcl_NewStringObj((char *) theName + 1,				theName[0]);		    } else {			objPtr = Tcl_NewIntObj(id);		    }		    ReleaseResource(resource);		    result = Tcl_ListObjAppendElement(interp, resultPtr,			    objPtr);		    if (result != TCL_OK) {			Tcl_DecrRefCount(objPtr);			break;		    }		}	    }	    SetResLoad(true);		    if (limitSearch) {		UseResFile(saveRef);	    }		    return TCL_OK;	case RESOURCE_OPEN:				    if (!((objc == 3) || (objc == 4))) {		Tcl_WrongNumArgs(interp, 2, objv, "fileName ?permissions?");		return TCL_ERROR;	    }	    stringPtr = Tcl_GetStringFromObj(objv[2], &length);	    nativeName = Tcl_TranslateFileName(interp, stringPtr, &buffer);	    if (nativeName == NULL) {		return TCL_ERROR;	    }	    err = FSpLocationFromPath(strlen(nativeName), nativeName,		    &fileSpec) ;	    Tcl_DStringFree(&buffer);	    if (!((err == noErr) || (err == fnfErr))) {		Tcl_AppendStringsToObj(resultPtr,			"invalid path", (char *) NULL);		return TCL_ERROR;	    }	    /*	     * Get permissions for the file.  We really only understand	     * read-only and shared-read-write.  If no permissions are 	     * given we default to read only.	     */	    	    if (objc == 4) {		stringPtr = Tcl_GetStringFromObj(objv[3], &length);		mode = TclGetOpenMode(interp, stringPtr, &index);		if (mode == -1) {		    /* TODO: TclGetOpenMode doesn't work with Obj commands. */		    return TCL_ERROR;		}		switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {		    case O_RDONLY:			macPermision = fsRdPerm;		    break;		    case O_WRONLY:		    case O_RDWR:			macPermision = fsRdWrShPerm;			break;		    default:			panic("Tcl_ResourceObjCmd: invalid mode value");		    break;		}	    } else {		macPermision = fsRdPerm;	    }	    	    /*	     * Don't load in any of the resources in the file, this could 	     * cause problems if you open a file that has CODE resources...	     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -