OSErr IACdrivefilelist (tyFScallback handlespecroutine) { /* the opendoc and printdoc required events take a list of filespecs as a parameter. we factor out the common code, and make it a little easier for an application to handle these events. you supply a callback routine that handles a single filespec, you could print it or open it, depending on which of the required events is being invoked. */ AEDesc desc; long ctfiles; DescType actualtype; long actualsize; AEKeyword actualkeyword; FSSpec fs; long i; OSErr ec; ec = AEGetKeyDesc (IACglobals.event, keyDirectObject, typeAEList, &desc); IACglobals.errorcode = ec; if (ec != noErr) return (ec); ec = AECountItems (&desc, &ctfiles); IACglobals.errorcode = ec; if (ec != noErr) return (ec); for (i = 1; i <= ctfiles; i ++) { ec = AEGetNthPtr ( &desc, i, typeFSS, &actualkeyword, &actualtype, (Ptr) &fs, sizeof (fs), &actualsize); IACglobals.errorcode = ec; if (ec != noErr) { AEDisposeDesc (&desc); return (ec); } if (!(*handlespecroutine) (&fs)) return (-1); } /*for*/ return (noErr); } /*IACdrivefilelist*/
/*---------------------------------------------------------------------------- GetEventKeyDataParameter Extract the keyData parameter data from an apple event ---------------------------------------------------------------------------*/ void AECoreClass::GetEventKeyDataParameter(const AppleEvent *appleEvent, DescType requestedType, AEDesc *data) { StAEDesc keyData; OSErr err = AEGetKeyDesc(appleEvent, keyAEData, requestedType, &keyData); ThrowIfOSErr(err); ExtractData(&keyData, data); }
// Counts how many files are in the apple event short CountFiles(AppleEvent *message) { AEDesc fileListDesc; long numFiles; OSErr err; /* extract the list of aliases into fileListDesc */ err = AEGetKeyDesc(message, keyDirectObject, typeAEList, &fileListDesc); if (err!=noErr) return 0; /* count the list elements */ err = AECountItems(&fileListDesc, &numFiles); AEDisposeDesc(&fileListDesc); return err ? 0 : numFiles; }
DesktopWindow* GetWindowFromObjectAndKey(const AEDescList* desc, AEKeyword keyword) { DescType data_desc; MacSize data_size; OSErr err; DesktopWindow* win = NULL; err = AESizeOfKeyDesc(desc, keyword, &data_desc, &data_size); if (err == noErr) { if (data_desc == cLongInteger) { // window ID int winID = 0; err = AEGetKeyPtr(desc, keyword, cLongInteger, &data_desc, &winID, sizeof(winID), &data_size); if (err == noErr) { if (winID == -1) win = g_application->GetActiveDesktopWindow(FALSE); else win = GetDesktopWindowForExportID(winID, true); } } else if (data_desc == typeObjectSpecifier) { // window object AEDesc winObject; err = AEGetKeyDesc(desc, keyword, typeObjectSpecifier, &winObject); if (err == noErr) { win = GetWindowFromAEDesc(&winObject); AEDisposeDesc(&winObject); } } else if (data_desc == typeUnicodeText || data_desc == typeChar) { // window name uni_char* name = GetNewStringFromObjectAndKey(desc, keyword); if (name) { win = GetNamedWindow(name, true, NULL); delete [] name; } } } else { win = g_application->GetActiveDesktopWindow(FALSE); } return win; }
// Extracts all the files from a Finder print or open apple event and call the routine specified // on each of them OSErr ForEachFileDo(const AppleEvent *message,AEFileProc theirProc) { OSErr err = noErr; AEDesc fileListDesc; long numFiles; DescType actualType; long actualSize; AEKeyword actualKeyword; FSSpec oneFile; long index; /* extract the list of aliases into fileListDesc */ err = AEGetKeyDesc(message, keyDirectObject, typeAEList, &fileListDesc); if (err!=noErr) return err; /* count the list elements */ err = AECountItems(&fileListDesc, &numFiles); if (err != noErr) { AEDisposeDesc(&fileListDesc); return err; } /* get each from list and process it */ for (index = 1; index <= numFiles; index ++) { err = AEGetNthPtr(&fileListDesc, index, typeFSS, &actualKeyword, &actualType, (Ptr)&oneFile, sizeof(oneFile), &actualSize); if (err != noErr) { AEDisposeDesc(&fileListDesc); return err; } /* oneFile contains FSSpec of file in question */ err=theirProc(&oneFile); if (err) break; } AEDisposeDesc(&fileListDesc); return err; }
static pascal OSErr HandleOdoc(const AEDescList *aevt, AEDescList *reply,long refCon) { AEDesc FileListDescription; DescType MyFileType; long DataSize; AEKeyword MyKeyword; FSSpec TheFileSpec; Word i; Foo_t *FooPtr; /* First, I see if any files are present */ FileListDescription.descriptorType = typeWildCard; /* Any file */ FileListDescription.dataHandle = 0; /* No handle (Yet) */ if (!AEGetKeyDesc(aevt,keyDirectObject,typeAEList,&FileListDescription)) { /* Now load each and every file */ i = 1; FooPtr = (Foo_t *)refCon; while (!AEGetNthPtr(&FileListDescription,i,typeFSS,&MyKeyword,&MyFileType,(Ptr)&TheFileSpec,sizeof(FSSpec),&DataSize)) { char CurrentName[256]; char *DirName; if (TheFileSpec.name[0]) { /* Must have some name! */ PStr2CStr(CurrentName,(char *)TheFileSpec.name); /* Convert to "C" */ TheFileSpec.name[0] = 0; /* Zap the filename */ DirName = GetFullPathFromMacFSSpec(&TheFileSpec); /* Get the directory */ if (DirName) { SetAPrefix(8,DirName); /* Set my directory */ DeallocAPointer(DirName); FooPtr->Result = FALSE; /* Hit me! */ if (FooPtr->Proc(CurrentName)) { /* Process the file */ break; } } } ++i; /* Next */ } } AEDisposeDesc(&FileListDescription); /* Release the file list */ return noErr; }
Boolean GetFileFromObjectAndKey(const AEDescList* desc, AEKeyword keyword, FSRef* file, Boolean create) { DescType data_desc; MacSize data_size; OSErr err; err = AESizeOfKeyDesc(desc, keyword, &data_desc, &data_size); if (err == noErr) { if (data_desc == typeObjectSpecifier) { // file object... AEDesc fileObject; err = AEGetKeyDesc(desc, keyword, typeObjectSpecifier, &fileObject); if (err == noErr) { Boolean ok = GetFileFromObjectAndKey(&fileObject, keyAEKeyData, file, create); AEDisposeDesc(&fileObject); return ok; } } else if (data_desc == typeChar && data_size <= 255) { // file path... FSRef spec; Str255 path; err = AEGetKeyPtr(desc, keyword, typeChar, &data_desc, &path[1], 255, &data_size); path[0] = data_size; if (err == noErr) { FSRef folderRef; OpString unicode_path; unicode_path.SetL((const char*)path); err = FSFindFolder(kLocalDomain, kVolumeRootFolderType, kDontCreateFolder, &folderRef); // FIXME: ismailp - test rhoroughly err = FSMakeFSRefUnicode(&folderRef, unicode_path.Length(), (const UniChar*)unicode_path.CStr(), kTextEncodingUnknown, &spec); //FSMakeFSSpec(0, 0, path, &spec); if (create && (err == noErr || err == fnfErr)) { if (noErr == err) { FSDeleteObject(&spec); } err = FSCreateFileUnicode(&spec, 0, NULL, kFSCatInfoNone, NULL, file, NULL); } } } else if (data_desc == typeAlias) { // file alias... Handle alias = NewHandle(data_size); FSRef spec; HLock(alias); err = AEGetKeyPtr(desc, keyword, typeAlias, &data_desc, *alias, data_size, &data_size); if (err == noErr) { Boolean changed; err = FSResolveAlias(NULL, (AliasHandle)alias, &spec, &changed); if (create && (err == noErr || err == fnfErr)) { if (noErr == err) { FSDeleteObject(&spec); } err = FSCreateFileUnicode(&spec, 0, NULL, kFSCatInfoNone, NULL, file, NULL); //FSpCreate(&spec, '\?\?\?\?', '\?\?\?\?', NULL); } } DisposeHandle(alias); } else { err = paramErr; } } return (err == noErr); }
static OSErr OpenDocEventHandler(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon) { char** argv = NULL; int no; AEDesc fileListDesc = {'NULL', NULL}; long numFiles; long actualSize; long index; OSErr err; DescType actualType; AEKeyword actualKeyword; FSSpec aFile; FSRef theFile; UInt8 fullPath[MAXPATHLEN]; bool openWithWebStart = true; CFURLRef jnlpLocation = NULL; // Load up our list of file descriptors err = AEGetKeyDesc(theAppleEvent, keyDirectObject, typeAEList, &fileListDesc); if(err) { AEDisposeDesc(&fileListDesc); fprintf(stderr, "Error getting key desc\n"); return err; } // How many files do we have to deal with? err = AECountItems(&fileListDesc, &numFiles); if(err) { AEDisposeDesc(&fileListDesc); fprintf(stderr, "Error counting items\n"); return err; } // Iterate through all of the files, and try to send them through the JNLP java code. for(index = 1; index <= numFiles; index++) { err = AEGetNthPtr(&fileListDesc, index, typeFSS, &actualKeyword, &actualType, (Ptr)&aFile, sizeof(aFile), &actualSize); if(err) { AEDisposeDesc(&fileListDesc); fprintf(stderr, "Error getting file pointer\n"); return err; } // Mac stuff to turn the file representation we get into a workable pathname FSpMakeFSRef(&aFile, &theFile); FSRefMakePath(&theFile, fullPath, sizeof(fullPath)); // See if we have an application for this JNLP file. If so, use that instead. jnlpLocation = FindJnlpURLInFile(fullPath); if (jnlpLocation != NULL) { CFURLRef applicationURL = FindJNLPApplicationPackage(jnlpLocation); if (applicationURL != NULL) { OSStatus result = LSOpenCFURLRef(applicationURL, NULL); if (result == noErr) { openWithWebStart = false; } } CFRelease(jnlpLocation); } if (openWithWebStart) { // Three arguments -- app name, file to open, and null. argv = (char**)malloc(sizeof(char*) * 3); no = 0; argv[no++] = GetWebStartAppName(); argv[no++] = fullPath; argv[no] = NULL; // Call into our main app. main(no, argv); } openWithWebStart = TRUE; } QuitApplicationEventLoop(); return noErr; }