| /*********************************************************** |
| Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, |
| The Netherlands. |
| |
| All Rights Reserved |
| |
| Permission to use, copy, modify, and distribute this software and its |
| documentation for any purpose and without fee is hereby granted, |
| provided that the above copyright notice appear in all copies and that |
| both that copyright notice and this permission notice appear in |
| supporting documentation, and that the names of Stichting Mathematisch |
| Centrum or CWI not be used in advertising or publicity pertaining to |
| distribution of the software without specific, written prior permission. |
| |
| STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO |
| THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND |
| FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE |
| FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
| OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| |
| ******************************************************************/ |
| |
| #include "allobjects.h" |
| #include "modsupport.h" /* For getargs() etc. */ |
| #include "macglue.h" |
| |
| #include <Memory.h> |
| #include <Files.h> |
| #include <Folders.h> |
| #include <StandardFile.h> |
| #include <Aliases.h> |
| #include <LowMem.h> |
| |
| #include "getapplbycreator.h" |
| |
| #ifdef THINK_C |
| #define FileFilterUPP FileFilterProcPtr |
| #endif |
| |
| static object *ErrorObject; |
| |
| /* ----------------------------------------------------- */ |
| /* Declarations for objects of type Alias */ |
| |
| typedef struct { |
| OB_HEAD |
| AliasHandle alias; |
| } mfsaobject; |
| |
| staticforward typeobject Mfsatype; |
| |
| #define is_mfsaobject(v) ((v)->ob_type == &Mfsatype) |
| |
| /* ---------------------------------------------------------------- */ |
| /* Declarations for objects of type FSSpec */ |
| |
| typedef struct { |
| OB_HEAD |
| FSSpec fsspec; |
| } mfssobject; |
| |
| staticforward typeobject Mfsstype; |
| |
| #define is_mfssobject(v) ((v)->ob_type == &Mfsstype) |
| |
| |
| /* ---------------------------------------------------------------- */ |
| /* Declarations for objects of type FInfo */ |
| |
| typedef struct { |
| OB_HEAD |
| FInfo finfo; |
| } mfsiobject; |
| |
| staticforward typeobject Mfsitype; |
| |
| #define is_mfsiobject(v) ((v)->ob_type == &Mfsitype) |
| |
| |
| mfssobject *newmfssobject(FSSpec *fss); /* Forward */ |
| |
| /* ---------------------------------------------------------------- */ |
| |
| static object * |
| mfsa_Resolve(self, args) |
| mfsaobject *self; |
| object *args; |
| { |
| FSSpec from, *fromp, result; |
| Boolean changed; |
| OSErr err; |
| |
| from.name[0] = 0; |
| if (!newgetargs(args, "|O&", PyMac_GetFSSpec, &from)) |
| return NULL; |
| if (from.name[0] ) |
| fromp = &from; |
| else |
| fromp = NULL; |
| err = ResolveAlias(fromp, self->alias, &result, &changed); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return mkvalue("(Oi)", newmfssobject(&result), (int)changed); |
| } |
| |
| static object * |
| mfsa_GetInfo(self, args) |
| mfsaobject *self; |
| object *args; |
| { |
| Str63 value; |
| int i; |
| OSErr err; |
| |
| if (!newgetargs(args, "i", &i)) |
| return NULL; |
| err = GetAliasInfo(self->alias, (AliasInfoType)i, value); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return 0; |
| } |
| return newsizedstringobject((char *)&value[1], value[0]); |
| } |
| |
| static object * |
| mfsa_Update(self, args) |
| mfsaobject *self; |
| object *args; |
| { |
| FSSpec target, fromfile, *fromfilep; |
| OSErr err; |
| Boolean changed; |
| |
| fromfile.name[0] = 0; |
| if (!newgetargs(args, "O&|O&", PyMac_GetFSSpec, &target, |
| PyMac_GetFSSpec, &fromfile)) |
| return NULL; |
| if ( fromfile.name[0] ) |
| fromfilep = &fromfile; |
| else |
| fromfilep = NULL; |
| err = UpdateAlias(fromfilep, &target, self->alias, &changed); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return 0; |
| } |
| return mkvalue("i", (int)changed); |
| } |
| |
| static struct methodlist mfsa_methods[] = { |
| {"Resolve", (method)mfsa_Resolve, 1}, |
| {"GetInfo", (method)mfsa_GetInfo, 1}, |
| {"Update", (method)mfsa_Update, 1}, |
| |
| {NULL, NULL} /* sentinel */ |
| }; |
| |
| /* ---------- */ |
| |
| static object * |
| mfsa_getattr(self, name) |
| mfsaobject *self; |
| char *name; |
| { |
| if ( strcmp(name, "data") == 0 ) { |
| int size; |
| PyObject *rv; |
| |
| size = GetHandleSize((Handle)self->alias); |
| HLock((Handle)self->alias); |
| rv = PyString_FromStringAndSize(*(Handle)self->alias, size); |
| HUnlock((Handle)self->alias); |
| return rv; |
| } |
| return findmethod(mfsa_methods, (object *)self, name); |
| } |
| |
| mfsaobject * |
| newmfsaobject(alias) |
| AliasHandle alias; |
| { |
| mfsaobject *self; |
| |
| self = NEWOBJ(mfsaobject, &Mfsatype); |
| if (self == NULL) |
| return NULL; |
| self->alias = alias; |
| return self; |
| } |
| |
| |
| static void |
| mfsa_dealloc(self) |
| mfsaobject *self; |
| { |
| #if 0 |
| if ( self->alias ) { |
| should we do something here? |
| } |
| #endif |
| |
| DEL(self); |
| } |
| |
| statichere typeobject Mfsatype = { |
| OB_HEAD_INIT(&Typetype) |
| 0, /*ob_size*/ |
| "Alias", /*tp_name*/ |
| sizeof(mfsaobject), /*tp_basicsize*/ |
| 0, /*tp_itemsize*/ |
| /* methods */ |
| (destructor)mfsa_dealloc, /*tp_dealloc*/ |
| (printfunc)0, /*tp_print*/ |
| (getattrfunc)mfsa_getattr, /*tp_getattr*/ |
| (setattrfunc)0, /*tp_setattr*/ |
| (cmpfunc)0, /*tp_compare*/ |
| (reprfunc)0, /*tp_repr*/ |
| 0, /*tp_as_number*/ |
| 0, /*tp_as_sequence*/ |
| 0, /*tp_as_mapping*/ |
| (hashfunc)0, /*tp_hash*/ |
| }; |
| |
| /* End of code for Alias objects */ |
| /* -------------------------------------------------------- */ |
| |
| /* ---------------------------------------------------------------- */ |
| |
| static struct methodlist mfsi_methods[] = { |
| |
| {NULL, NULL} /* sentinel */ |
| }; |
| |
| /* ---------- */ |
| |
| static mfsiobject * |
| newmfsiobject() |
| { |
| mfsiobject *self; |
| |
| self = NEWOBJ(mfsiobject, &Mfsitype); |
| if (self == NULL) |
| return NULL; |
| memset((char *)&self->finfo, '\0', sizeof(self->finfo)); |
| return self; |
| } |
| |
| static void |
| mfsi_dealloc(self) |
| mfsiobject *self; |
| { |
| DEL(self); |
| } |
| |
| static object * |
| mfsi_getattr(self, name) |
| mfsiobject *self; |
| char *name; |
| { |
| if ( strcmp(name, "Type") == 0 ) |
| return PyMac_BuildOSType(self->finfo.fdType); |
| else if ( strcmp(name, "Creator") == 0 ) |
| return PyMac_BuildOSType(self->finfo.fdCreator); |
| else if ( strcmp(name, "Flags") == 0 ) |
| return Py_BuildValue("i", (int)self->finfo.fdFlags); |
| else if ( strcmp(name, "Location") == 0 ) |
| return PyMac_BuildPoint(self->finfo.fdLocation); |
| else if ( strcmp(name, "Fldr") == 0 ) |
| return Py_BuildValue("i", (int)self->finfo.fdFldr); |
| else |
| return findmethod(mfsi_methods, (object *)self, name); |
| } |
| |
| |
| static int |
| mfsi_setattr(self, name, v) |
| mfsiobject *self; |
| char *name; |
| object *v; |
| { |
| int rv; |
| int i; |
| |
| if ( v == NULL ) { |
| err_setstr(AttributeError, "Cannot delete attribute"); |
| return -1; |
| } |
| if ( strcmp(name, "Type") == 0 ) |
| rv = PyMac_GetOSType(v, &self->finfo.fdType); |
| else if ( strcmp(name, "Creator") == 0 ) |
| rv = PyMac_GetOSType(v, &self->finfo.fdCreator); |
| else if ( strcmp(name, "Flags") == 0 ) { |
| rv = PyArg_Parse(v, "i", &i); |
| self->finfo.fdFlags = (short)i; |
| } else if ( strcmp(name, "Location") == 0 ) |
| rv = PyMac_GetPoint(v, &self->finfo.fdLocation); |
| else if ( strcmp(name, "Fldr") == 0 ) { |
| rv = PyArg_Parse(v, "i", &i); |
| self->finfo.fdFldr = (short)i; |
| } else { |
| err_setstr(AttributeError, "No such attribute"); |
| return -1; |
| } |
| if (rv) |
| return 0; |
| return -1; |
| } |
| |
| |
| static typeobject Mfsitype = { |
| OB_HEAD_INIT(&Typetype) |
| 0, /*ob_size*/ |
| "FInfo object", /*tp_name*/ |
| sizeof(mfsiobject), /*tp_basicsize*/ |
| 0, /*tp_itemsize*/ |
| /* methods */ |
| (destructor)mfsi_dealloc, /*tp_dealloc*/ |
| (printfunc)0, /*tp_print*/ |
| (getattrfunc)mfsi_getattr, /*tp_getattr*/ |
| (setattrfunc)mfsi_setattr, /*tp_setattr*/ |
| (cmpfunc)0, /*tp_compare*/ |
| (reprfunc)0, /*tp_repr*/ |
| 0, /*tp_as_number*/ |
| 0, /*tp_as_sequence*/ |
| 0, /*tp_as_mapping*/ |
| (hashfunc)0, /*tp_hash*/ |
| }; |
| |
| /* End of code for FInfo object objects */ |
| /* -------------------------------------------------------- */ |
| |
| |
| /* |
| ** Helper routine for other modules: return an FSSpec * if the |
| ** object is a python fsspec object, else NULL |
| */ |
| FSSpec * |
| mfs_GetFSSpecFSSpec(self) |
| object *self; |
| { |
| if ( is_mfssobject(self) ) |
| return &((mfssobject *)self)->fsspec; |
| return NULL; |
| } |
| |
| /* |
| ** Two generally useful routines |
| */ |
| static OSErr |
| PyMac_GetFileDates(fss, crdat, mddat, bkdat) |
| FSSpec *fss; |
| unsigned long *crdat, *mddat, *bkdat; |
| { |
| CInfoPBRec pb; |
| OSErr error; |
| |
| pb.dirInfo.ioNamePtr = fss->name; |
| pb.dirInfo.ioFDirIndex = 0; |
| pb.dirInfo.ioVRefNum = fss->vRefNum; |
| pb.dirInfo.ioDrDirID = fss->parID; |
| error = PBGetCatInfoSync(&pb); |
| if ( error ) return error; |
| *crdat = pb.hFileInfo.ioFlCrDat; |
| *mddat = pb.hFileInfo.ioFlMdDat; |
| *bkdat = pb.hFileInfo.ioFlBkDat; |
| return 0; |
| } |
| |
| static OSErr |
| PyMac_SetFileDates(fss, crdat, mddat, bkdat) |
| FSSpec *fss; |
| unsigned long crdat, mddat, bkdat; |
| { |
| CInfoPBRec pb; |
| OSErr error; |
| |
| pb.dirInfo.ioNamePtr = fss->name; |
| pb.dirInfo.ioFDirIndex = 0; |
| pb.dirInfo.ioVRefNum = fss->vRefNum; |
| pb.dirInfo.ioDrDirID = fss->parID; |
| error = PBGetCatInfoSync(&pb); |
| if ( error ) return error; |
| pb.dirInfo.ioNamePtr = fss->name; |
| pb.dirInfo.ioFDirIndex = 0; |
| pb.dirInfo.ioVRefNum = fss->vRefNum; |
| pb.dirInfo.ioDrDirID = fss->parID; |
| pb.hFileInfo.ioFlCrDat = crdat; |
| pb.hFileInfo.ioFlMdDat = mddat; |
| pb.hFileInfo.ioFlBkDat = bkdat; |
| error = PBSetCatInfoSync(&pb); |
| return error; |
| } |
| |
| static object * |
| mfss_as_pathname(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| char strbuf[257]; |
| OSErr err; |
| |
| if (!newgetargs(args, "")) |
| return NULL; |
| err = PyMac_GetFullPath(&self->fsspec, strbuf); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return newstringobject(strbuf); |
| } |
| |
| static object * |
| mfss_as_tuple(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| if (!newgetargs(args, "")) |
| return NULL; |
| return Py_BuildValue("(iis#)", self->fsspec.vRefNum, self->fsspec.parID, |
| &self->fsspec.name[1], self->fsspec.name[0]); |
| } |
| |
| static object * |
| mfss_NewAlias(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| FSSpec src, *srcp; |
| OSErr err; |
| AliasHandle alias; |
| |
| src.name[0] = 0; |
| if (!newgetargs(args, "|O&", PyMac_GetFSSpec, &src)) |
| return NULL; |
| if ( src.name[0] ) |
| srcp = &src; |
| else |
| srcp = NULL; |
| err = NewAlias(srcp, &self->fsspec, &alias); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| |
| return (object *)newmfsaobject(alias); |
| } |
| |
| static object * |
| mfss_NewAliasMinimal(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| OSErr err; |
| AliasHandle alias; |
| |
| if (!newgetargs(args, "")) |
| return NULL; |
| err = NewAliasMinimal(&self->fsspec, &alias); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return (object *)newmfsaobject(alias); |
| } |
| |
| /* XXXX These routines should be replaced by a wrapper to the *FInfo routines */ |
| static object * |
| mfss_GetCreatorType(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| OSErr err; |
| FInfo info; |
| |
| if (!newgetargs(args, "")) |
| return NULL; |
| err = FSpGetFInfo(&self->fsspec, &info); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return Py_BuildValue("(O&O&)", |
| PyMac_BuildOSType, info.fdCreator, PyMac_BuildOSType, info.fdType); |
| } |
| |
| static object * |
| mfss_SetCreatorType(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| OSErr err; |
| OSType creator, type; |
| FInfo info; |
| |
| if (!newgetargs(args, "O&O&", PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) |
| return NULL; |
| err = FSpGetFInfo(&self->fsspec, &info); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| info.fdType = type; |
| info.fdCreator = creator; |
| err = FSpSetFInfo(&self->fsspec, &info); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| INCREF(None); |
| return None; |
| } |
| |
| static object * |
| mfss_GetFInfo(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| OSErr err; |
| mfsiobject *fip; |
| |
| |
| if (!newgetargs(args, "")) |
| return NULL; |
| if ( (fip=newmfsiobject()) == NULL ) |
| return NULL; |
| err = FSpGetFInfo(&self->fsspec, &fip->finfo); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| DECREF(fip); |
| return NULL; |
| } |
| return (object *)fip; |
| } |
| |
| static object * |
| mfss_SetFInfo(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| OSErr err; |
| mfsiobject *fip; |
| |
| if (!newgetargs(args, "O!", &Mfsitype, &fip)) |
| return NULL; |
| err = FSpSetFInfo(&self->fsspec, &fip->finfo); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| INCREF(None); |
| return None; |
| } |
| |
| static object * |
| mfss_GetDates(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| OSErr err; |
| unsigned long crdat, mddat, bkdat; |
| |
| if (!newgetargs(args, "")) |
| return NULL; |
| err = PyMac_GetFileDates(&self->fsspec, &crdat, &mddat, &bkdat); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return mkvalue("ddd", (double)crdat, (double)mddat, (double)bkdat); |
| } |
| |
| static object * |
| mfss_SetDates(self, args) |
| mfssobject *self; |
| object *args; |
| { |
| OSErr err; |
| double crdat, mddat, bkdat; |
| |
| if (!newgetargs(args, "ddd", &crdat, &mddat, &bkdat)) |
| return NULL; |
| err = PyMac_SetFileDates(&self->fsspec, (unsigned long)crdat, |
| (unsigned long)mddat, (unsigned long)bkdat); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| INCREF(None); |
| return None; |
| } |
| |
| static struct methodlist mfss_methods[] = { |
| {"as_pathname", (method)mfss_as_pathname, 1}, |
| {"as_tuple", (method)mfss_as_tuple, 1}, |
| {"NewAlias", (method)mfss_NewAlias, 1}, |
| {"NewAliasMinimal", (method)mfss_NewAliasMinimal, 1}, |
| {"GetCreatorType", (method)mfss_GetCreatorType, 1}, |
| {"SetCreatorType", (method)mfss_SetCreatorType, 1}, |
| {"GetFInfo", (method)mfss_GetFInfo, 1}, |
| {"SetFInfo", (method)mfss_SetFInfo, 1}, |
| {"GetDates", (method)mfss_GetDates, 1}, |
| {"SetDates", (method)mfss_SetDates, 1}, |
| |
| {NULL, NULL} /* sentinel */ |
| }; |
| |
| /* ---------- */ |
| |
| static object * |
| mfss_getattr(self, name) |
| mfssobject *self; |
| char *name; |
| { |
| if ( strcmp(name, "data") == 0) |
| return PyString_FromStringAndSize((char *)&self->fsspec, sizeof(FSSpec)); |
| return findmethod(mfss_methods, (object *)self, name); |
| } |
| |
| mfssobject * |
| newmfssobject(fss) |
| FSSpec *fss; |
| { |
| mfssobject *self; |
| |
| self = NEWOBJ(mfssobject, &Mfsstype); |
| if (self == NULL) |
| return NULL; |
| self->fsspec = *fss; |
| return self; |
| } |
| |
| static void |
| mfss_dealloc(self) |
| mfssobject *self; |
| { |
| DEL(self); |
| } |
| |
| static object * |
| mfss_repr(self) |
| mfssobject *self; |
| { |
| char buf[512]; |
| |
| sprintf(buf, "FSSpec((%d, %d, '%.*s'))", |
| self->fsspec.vRefNum, |
| self->fsspec.parID, |
| self->fsspec.name[0], self->fsspec.name+1); |
| return newstringobject(buf); |
| } |
| |
| static int |
| mfss_compare(v, w) |
| mfssobject *v, *w; |
| { |
| int minlen; |
| int res; |
| |
| if ( v->fsspec.vRefNum < w->fsspec.vRefNum ) return -1; |
| if ( v->fsspec.vRefNum > w->fsspec.vRefNum ) return 1; |
| if ( v->fsspec.parID < w->fsspec.parID ) return -1; |
| if ( v->fsspec.parID > w->fsspec.parID ) return 1; |
| minlen = v->fsspec.name[0]; |
| if ( w->fsspec.name[0] < minlen ) minlen = w->fsspec.name[0]; |
| res = strncmp((char *)v->fsspec.name+1, (char *)w->fsspec.name+1, minlen); |
| if ( res ) return res; |
| if ( v->fsspec.name[0] < w->fsspec.name[0] ) return -1; |
| if ( v->fsspec.name[0] > w->fsspec.name[0] ) return 1; |
| return res; |
| } |
| |
| statichere typeobject Mfsstype = { |
| OB_HEAD_INIT(&Typetype) |
| 0, /*ob_size*/ |
| "FSSpec", /*tp_name*/ |
| sizeof(mfssobject), /*tp_basicsize*/ |
| 0, /*tp_itemsize*/ |
| /* methods */ |
| (destructor)mfss_dealloc, /*tp_dealloc*/ |
| (printfunc)0, /*tp_print*/ |
| (getattrfunc)mfss_getattr, /*tp_getattr*/ |
| (setattrfunc)0, /*tp_setattr*/ |
| (cmpfunc)mfss_compare, /*tp_compare*/ |
| (reprfunc)mfss_repr, /*tp_repr*/ |
| 0, /*tp_as_number*/ |
| 0, /*tp_as_sequence*/ |
| 0, /*tp_as_mapping*/ |
| (hashfunc)0, /*tp_hash*/ |
| }; |
| |
| /* End of code for FSSpec objects */ |
| /* -------------------------------------------------------- */ |
| |
| static object * |
| mfs_ResolveAliasFile(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| FSSpec fss; |
| Boolean chain = 1, isfolder, wasaliased; |
| OSErr err; |
| |
| if (!newgetargs(args, "O&|i", PyMac_GetFSSpec, &fss, &chain)) |
| return NULL; |
| err = ResolveAliasFile(&fss, chain, &isfolder, &wasaliased); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return mkvalue("Oii", newmfssobject(&fss), (int)isfolder, (int)wasaliased); |
| } |
| |
| static object * |
| mfs_StandardGetFile(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| SFTypeList list; |
| short numtypes; |
| StandardFileReply reply; |
| |
| list[0] = list[1] = list[2] = list[3] = 0; |
| numtypes = 0; |
| if (!newgetargs(args, "|O&O&O&O&", PyMac_GetOSType, &list[0], |
| PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2], |
| PyMac_GetOSType, &list[3]) ) |
| return NULL; |
| while ( numtypes < 4 && list[numtypes] ) { |
| numtypes++; |
| } |
| if ( numtypes == 0 ) |
| numtypes = -1; |
| StandardGetFile((FileFilterUPP)0, numtypes, list, &reply); |
| return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood); |
| } |
| |
| static object * |
| mfs_PromptGetFile(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| SFTypeList list; |
| short numtypes; |
| StandardFileReply reply; |
| char *prompt = NULL; |
| |
| list[0] = list[1] = list[2] = list[3] = 0; |
| numtypes = 0; |
| if (!newgetargs(args, "s|O&O&O&O&", &prompt, PyMac_GetOSType, &list[0], |
| PyMac_GetOSType, &list[1], PyMac_GetOSType, &list[2], |
| PyMac_GetOSType, &list[3]) ) |
| return NULL; |
| while ( numtypes < 4 && list[numtypes] ) { |
| numtypes++; |
| } |
| if ( numtypes == 0 ) |
| numtypes = -1; |
| PyMac_PromptGetFile(numtypes, list, &reply, prompt); |
| return mkvalue("(Oi)", newmfssobject(&reply.sfFile), reply.sfGood); |
| } |
| |
| static object * |
| mfs_StandardPutFile(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| Str255 prompt, dft; |
| StandardFileReply reply; |
| |
| dft[0] = 0; |
| if (!newgetargs(args, "O&|O&", PyMac_GetStr255, &prompt, PyMac_GetStr255, &dft) ) |
| return NULL; |
| StandardPutFile(prompt, dft, &reply); |
| return mkvalue("(Oi)",newmfssobject(&reply.sfFile), reply.sfGood); |
| } |
| |
| /* |
| ** Set initial directory for file dialogs */ |
| static object * |
| mfs_SetFolder(self, args) |
| object *self; |
| object *args; |
| { |
| FSSpec spec; |
| FSSpec ospec; |
| short orefnum; |
| long oparid; |
| |
| /* Get old values */ |
| orefnum = -LMGetSFSaveDisk(); |
| oparid = LMGetCurDirStore(); |
| (void)FSMakeFSSpec(orefnum, oparid, "\pplaceholder", &ospec); |
| |
| /* Go to working directory by default */ |
| (void)FSMakeFSSpec(0, 0, "\p:placeholder", &spec); |
| if (!newgetargs(args, "|O&", PyMac_GetFSSpec, &spec)) |
| return NULL; |
| /* Set standard-file working directory */ |
| LMSetSFSaveDisk(-spec.vRefNum); |
| LMSetCurDirStore(spec.parID); |
| return (object *)newmfssobject(&ospec); |
| } |
| |
| static object * |
| mfs_FSSpec(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| FSSpec fss; |
| |
| if (!newgetargs(args, "O&", PyMac_GetFSSpec, &fss)) |
| return NULL; |
| return (object *)newmfssobject(&fss); |
| } |
| |
| static object * |
| mfs_RawFSSpec(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| FSSpec *fssp; |
| int size; |
| |
| if (!newgetargs(args, "s#", &fssp, &size)) |
| return NULL; |
| if ( size != sizeof(FSSpec) ) { |
| PyErr_SetString(PyExc_TypeError, "Incorrect size for FSSpec record"); |
| return NULL; |
| } |
| return (object *)newmfssobject(fssp); |
| } |
| |
| static object * |
| mfs_RawAlias(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| char *dataptr; |
| Handle h; |
| int size; |
| |
| if (!newgetargs(args, "s#", &dataptr, &size)) |
| return NULL; |
| h = NewHandle(size); |
| if ( h == NULL ) { |
| PyErr_NoMemory(); |
| return NULL; |
| } |
| HLock(h); |
| memcpy((char *)*h, dataptr, size); |
| HUnlock(h); |
| return (object *)newmfsaobject((AliasHandle)h); |
| } |
| |
| static object * |
| mfs_GetDirectory(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| FSSpec fsdir; |
| int ok; |
| char *prompt = NULL; |
| |
| if (!newgetargs(args, "|s", &prompt) ) |
| return NULL; |
| |
| ok = PyMac_GetDirectory(&fsdir, prompt); |
| return mkvalue("(Oi)", newmfssobject(&fsdir), ok); |
| } |
| |
| static object * |
| mfs_FindFolder(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| OSErr err; |
| short where; |
| OSType which; |
| int create; |
| short refnum; |
| long dirid; |
| |
| if (!newgetargs(args, "hO&i", &where, PyMac_GetOSType, &which, &create) ) |
| return NULL; |
| err = FindFolder(where, which, (Boolean)create, &refnum, &dirid); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return mkvalue("(ii)", refnum, dirid); |
| } |
| |
| static object * |
| mfs_FindApplication(self, args) |
| object *self; /* Not used */ |
| object *args; |
| { |
| OSErr err; |
| OSType which; |
| FSSpec fss; |
| |
| if (!newgetargs(args, "O&", PyMac_GetOSType, &which) ) |
| return NULL; |
| err = FindApplicationFromCreator(which, &fss); |
| if ( err ) { |
| PyErr_Mac(ErrorObject, err); |
| return NULL; |
| } |
| return (object *)newmfssobject(&fss); |
| } |
| |
| static object * |
| mfs_FInfo(self, args) |
| object *self; |
| object *args; |
| { |
| return (object *)newmfsiobject(); |
| } |
| |
| /* List of methods defined in the module */ |
| |
| static struct methodlist mfs_methods[] = { |
| {"ResolveAliasFile", mfs_ResolveAliasFile, 1}, |
| {"StandardGetFile", mfs_StandardGetFile, 1}, |
| {"PromptGetFile", mfs_PromptGetFile, 1}, |
| {"StandardPutFile", mfs_StandardPutFile, 1}, |
| {"GetDirectory", mfs_GetDirectory, 1}, |
| {"SetFolder", mfs_SetFolder, 1}, |
| {"FSSpec", mfs_FSSpec, 1}, |
| {"RawFSSpec", mfs_RawFSSpec, 1}, |
| {"RawAlias", mfs_RawAlias, 1}, |
| {"FindFolder", mfs_FindFolder, 1}, |
| {"FindApplication", mfs_FindApplication, 1}, |
| {"FInfo", mfs_FInfo, 1}, |
| |
| {NULL, NULL} /* sentinel */ |
| }; |
| |
| |
| /* Initialization function for the module (*must* be called initmacfs) */ |
| |
| void |
| initmacfs() |
| { |
| object *m, *d; |
| |
| /* Create the module and add the functions */ |
| m = initmodule("macfs", mfs_methods); |
| |
| /* Add some symbolic constants to the module */ |
| d = getmoduledict(m); |
| ErrorObject = newstringobject("macfs.error"); |
| dictinsert(d, "error", ErrorObject); |
| |
| /* XXXX Add constants here */ |
| |
| /* Check for errors */ |
| if (err_occurred()) |
| fatal("can't initialize module macfs"); |
| } |