]> granicus.if.org Git - python/commitdiff
Added macfs.FindApplication() to find application FSSpec given signature.
authorJack Jansen <jack.jansen@cwi.nl>
Fri, 20 Sep 1996 15:25:16 +0000 (15:25 +0000)
committerJack Jansen <jack.jansen@cwi.nl>
Fri, 20 Sep 1996 15:25:16 +0000 (15:25 +0000)
Mac/Include/getapplbycreator.h [new file with mode: 0644]
Mac/Modules/macfsmodule.c
Mac/Python/getapplbycreator.c [new file with mode: 0644]

diff --git a/Mac/Include/getapplbycreator.h b/Mac/Include/getapplbycreator.h
new file mode 100644 (file)
index 0000000..4ff60fa
--- /dev/null
@@ -0,0 +1,4 @@
+#include <Types.h>
+#include <Files.h>
+
+extern OSErr FindApplicationFromCreator(OSType, FSSpecPtr);
index 831fd650eae71f8e395c966ccbf37197a67c6119..91e63ebcd711c76f42481b74d9d6907c1bcfad23 100644 (file)
@@ -34,6 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <LowMem.h>
 
 #include "nfullpath.h"
+#include "getapplbycreator.h"
 
 #ifdef THINK_C
 #define FileFilterUPP FileFilterProcPtr
@@ -894,6 +895,25 @@ mfs_FindFolder(self, args)
        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;
@@ -915,6 +935,7 @@ static struct methodlist mfs_methods[] = {
        {"RawFSSpec",                   mfs_RawFSSpec,                  1},
        {"RawAlias",                    mfs_RawAlias,                   1},
        {"FindFolder",                  mfs_FindFolder,                 1},
+       {"FindApplication",             mfs_FindApplication,    1},
        {"FInfo",                               mfs_FInfo,                              1},
  
        {NULL,          NULL}           /* sentinel */
diff --git a/Mac/Python/getapplbycreator.c b/Mac/Python/getapplbycreator.c
new file mode 100644 (file)
index 0000000..3370f31
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+** FindApplicationFromCreator uses the Desktop Database to
+** locate the creator application for the given document
+**
+** this routine will check the desktop database of all local
+** disks, then the desktop databases of all server volumes
+** (so up to two passes will be made)
+**
+** This code was created from FindApplicationFromDocument
+** routine, origin unknown.
+*/
+
+#include <Types.h>
+#include <Files.h>
+#include <Errors.h>
+#include "getapplbycreator.h"
+
+
+OSErr FindApplicationFromCreator(OSType creator,
+        FSSpecPtr applicationFSSpecPtr)
+{
+        enum { localPass, remotePass, donePass } volumePass;
+        DTPBRec desktopParams;
+        HParamBlockRec hfsParams;
+        short volumeIndex;
+        Boolean foundFlag;
+        GetVolParmsInfoBuffer volumeInfoBuffer;
+        OSErr retCode;
+
+/* dkj 12/94 initialize flag to false (thanks to Peter Baral for pointing out this bug) */
+        foundFlag = false;
+
+        volumePass = localPass;
+        volumeIndex = 0;
+
+        do {
+                               /*
+                ** first, find the vRefNum of the volume whose Desktop Database
+                ** we're checking this time
+                               */
+
+                               volumeIndex++;
+
+                               /*      convert the volumeIndex into a vRefNum */
+
+                               hfsParams.volumeParam.ioNamePtr = nil;
+                               hfsParams.volumeParam.ioVRefNum = 0;
+                               hfsParams.volumeParam.ioVolIndex = volumeIndex;
+                               retCode = PBHGetVInfoSync(&hfsParams);
+
+                               /* a nsvErr indicates that the current pass is over */
+                               if (retCode == nsvErr) goto SkipThisVolume;
+                               if (retCode != noErr) goto Bail;
+
+                               /*
+                               ** call GetVolParms to determine if this volume is a server
+                               ** (a remote volume)
+                               */
+                               
+                               hfsParams.ioParam.ioBuffer = (Ptr) &volumeInfoBuffer;
+                               hfsParams.ioParam.ioReqCount = sizeof(GetVolParmsInfoBuffer);
+                               retCode = PBHGetVolParmsSync(&hfsParams);
+                               if (retCode != noErr) goto Bail;
+                               
+                               /*
+                               ** if the vMServerAdr field of the volume information buffer
+                               ** is zero, this is a local volume; skip this volume
+                               ** if it's local on a remote pass or remote on a local pass
+                               */
+                               
+                               if ((volumeInfoBuffer.vMServerAdr != 0) !=
+                                               (volumePass == remotePass)) goto SkipThisVolume;
+
+                               /* okay, now we've found the vRefNum for our desktop database call */
+
+                               desktopParams.ioVRefNum = hfsParams.volumeParam.ioVRefNum;
+
+                               /*
+                ** find the path refNum for the desktop database for
+                ** the volume we're interested in
+                */
+
+                desktopParams.ioNamePtr = nil;
+
+                retCode = PBDTGetPath(&desktopParams);
+                if (retCode == noErr && desktopParams.ioDTRefNum != 0) {
+
+                                               /*
+                        ** use the GetAPPL call to find the preferred application
+                        ** for opening any document with this one's creator
+                        */
+
+                        desktopParams.ioIndex = 0;
+                        desktopParams.ioFileCreator = creator;
+                        desktopParams.ioNamePtr = applicationFSSpecPtr->name;
+                        retCode = PBDTGetAPPLSync(&desktopParams);
+
+                        if (retCode == noErr) {
+                                                               /*
+                                ** okay, found it; fill in the application file spec
+                                ** and set the flag indicating we're done
+                                */
+
+                                applicationFSSpecPtr->parID = desktopParams.ioAPPLParID;
+                                applicationFSSpecPtr->vRefNum = desktopParams.ioVRefNum;
+                                foundFlag = true;
+
+                        }
+                }
+
+        SkipThisVolume:
+                               /*
+                ** if retCode indicates a no such volume error or if this
+                ** was the first pass, it's time to move on to the next pass
+                */
+
+                if (retCode == nsvErr) {
+                        volumePass++;
+                        volumeIndex = 0;
+                }
+
+        } while (foundFlag == false && volumePass != donePass);
+
+Bail:
+               if (retCode == nsvErr)
+                       return fnfErr;          /* More logical than "No such volume" */
+        return retCode;
+}