DesktopWindow* GetWindowFromAEDesc(const AEDesc *inDesc) { DescType data_desc; MacSize data_size; DescType get_type; SInt32 get_index; DescType get_form; Boolean toplevel; OSStatus err; DesktopWindow* win = NULL; err = AEGetKeyPtr(inDesc, keyAEDesiredClass, cType, &data_desc, &get_type, sizeof(get_type), &data_size); if (noErr == err && (get_type == cWindow || get_type == cDocument)) { // OK, looks like the request for a window, let's look closer. toplevel = (get_type == cWindow); err = AEGetKeyPtr(inDesc, keyAEKeyForm, cEnumeration, &data_desc, &get_form, sizeof(get_form), &data_size); if (err == noErr) { err = AESizeOfKeyDesc(inDesc, keyAEKeyData, &data_desc, &data_size); if (err == noErr) { if ((get_form == formUniqueID) && (data_desc == cLongInteger) && (data_size == 4)) { err = AEGetKeyPtr(inDesc, keyAEKeyData, cLongInteger, &data_desc, &get_index, sizeof(get_index), &data_size); if (err == noErr) win = GetDesktopWindowForExportID(get_index, toplevel); } else if ((get_form == formAbsolutePosition) && (data_desc == cLongInteger) && (data_size == 4)) { err = AEGetKeyPtr(inDesc, keyAEKeyData, cLongInteger, &data_desc, &get_index, sizeof(get_index), &data_size); if (err == noErr) win = GetNumberedWindow(get_index, toplevel, NULL); } else if ((get_form == formAbsolutePosition) && (data_desc == typeAbsoluteOrdinal) && (data_size == 4)) { err = AEGetKeyPtr(inDesc, keyAEKeyData, typeAbsoluteOrdinal, &data_desc, &get_index, sizeof(get_index), &data_size); if (err == noErr) win = GetOrdinalWindow(get_index, toplevel, NULL); } else if ((get_form == formName) && (data_desc == typeUnicodeText || data_desc == typeChar)) { uni_char* uniName = GetNewStringFromObjectAndKey(inDesc, keyAEKeyData); if (uniName) { win = GetNamedWindow(uniName, toplevel, NULL); delete [] uniName; } } } } } return win; }
uni_char* GetNewStringFromObjectAndKey(const AEDescList* desc, AEKeyword keyword) { uni_char* uniText = NULL; DescType data_desc; MacSize data_size; OSStatus err; err = AESizeOfKeyDesc(desc, keyword, &data_desc, &data_size); if ((err == noErr) && (data_desc == typeUnicodeText || data_desc == typeChar)) { if (data_desc == typeUnicodeText) { uniText = new uni_char[data_size/2 + 1]; err = AEGetKeyPtr(desc, keyword, data_desc, &data_desc, uniText, data_size, &data_size); uniText[data_size/2] = 0; if (err != noErr) { delete [] uniText; uniText = NULL; } } else if (data_desc == typeChar) { char* macText = new char[data_size + 1]; if (macText) { err = AEGetKeyPtr(desc, keyword, data_desc, &data_desc, macText, data_size, &data_size); if (err == noErr) { macText[data_size] = 0; uniText = new uni_char[data_size + 1]; gTextConverter->ConvertStringFromMacC(macText, uniText, data_size+1); if (gTextConverter->GotConversionError()) { delete [] uniText; uniText = NULL; } } delete [] macText; } } } return uniText; }
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; }
/* *---------------------------------------------------------------------- * * GetFinderFont -- * * Gets the "views" font of the Macintosh Finder * * Results: * Standard Tcl result, and sets finderID to the font family * id for the current finder font. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int GetFinderFont(int *finderID) { OSErr err = noErr; OSType finderPrefs, viewFont = 'vfnt'; DescType returnType; Size returnSize; long result, sys8Mask = 0x0800; static AppleEvent outgoingAevt = {typeNull, NULL}; AppleEvent returnAevt; AEAddressDesc fndrAddress; AEDesc nullContainer = {typeNull, NULL}, tempDesc = {typeNull, NULL}, tempDesc2 = {typeNull, NULL}, finalDesc = {typeNull, NULL}; const OSType finderSignature = 'MACS'; if (outgoingAevt.descriptorType == typeNull) { if ((Gestalt(gestaltSystemVersion, &result) != noErr) || (result >= sys8Mask)) { finderPrefs = 'pfrp'; } else { finderPrefs = 'pvwp'; } AECreateDesc(typeApplSignature, &finderSignature, sizeof(finderSignature), &fndrAddress); err = AECreateAppleEvent(kAECoreSuite, kAEGetData, &fndrAddress, kAutoGenerateReturnID, kAnyTransactionID, &outgoingAevt); AEDisposeDesc(&fndrAddress); /* * The structure is: * the property view font ('vfnt') * of the property view preferences ('pvwp') * of the Null Container (i.e. the Finder itself). */ AECreateDesc(typeType, &finderPrefs, sizeof(finderPrefs), &tempDesc); err = CreateObjSpecifier(typeType, &nullContainer, formPropertyID, &tempDesc, true, &tempDesc2); AECreateDesc(typeType, &viewFont, sizeof(viewFont), &tempDesc); err = CreateObjSpecifier(typeType, &tempDesc2, formPropertyID, &tempDesc, true, &finalDesc); AEPutKeyDesc(&outgoingAevt, keyDirectObject, &finalDesc); AEDisposeDesc(&finalDesc); } err = AESend(&outgoingAevt, &returnAevt, kAEWaitReply, kAEHighPriority, kAEDefaultTimeout, NULL, NULL); if (err == noErr) { err = AEGetKeyPtr(&returnAevt, keyDirectObject, typeInteger, &returnType, (void *) finderID, sizeof(int), &returnSize); if (err == noErr) { return TCL_OK; } } return TCL_ERROR; }
static OSStatus CreateCFArrayFromAEDescList( const AEDescList * descList, CFArrayRef * itemsPtr ) // This routine's input is an AEDescList that contains replies // from the "properties of every login item" event. Each element // of the list is an AERecord with two important properties, // "path" and "hidden". This routine creates a CFArray that // corresponds to this list. Each element of the CFArray // contains two properties, kLIAEURL and // kLIAEHidden, that are derived from the corresponding // AERecord properties. // // On entry, descList must not be NULL // On entry, itemsPtr must not be NULL // On entry, *itemsPtr must be NULL // On success, *itemsPtr will be a valid CFArray // On error, *itemsPtr will be NULL { OSStatus err; CFMutableArrayRef result; long itemCount; long itemIndex; AEKeyword junkKeyword; DescType junkType; Size junkSize; assert( itemsPtr != NULL); assert(*itemsPtr == NULL); result = NULL; // Create a place for the result. err = noErr; result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); if (result == NULL) { err = coreFoundationUnknownErr; } // For each element in the descriptor list... if (err == noErr) { err = AECountItems(descList, &itemCount); } if (err == noErr) { for (itemIndex = 1; itemIndex <= itemCount; itemIndex++) { if (itemIndex == 4) { int notused = 0; notused++; } AERecord thisItem; UInt8 thisPath[1024]; Size thisPathSize; FSRef thisItemRef; CFURLRef thisItemURL; Boolean thisItemHidden; CFDictionaryRef thisItemDict; thisItem = kAENull; thisItemURL = NULL; thisItemDict = NULL; // Get this element's AERecord. err = AEGetNthDesc(descList, itemIndex, typeAERecord, &junkKeyword, &thisItem); if (err != noErr) { err = noErr; continue; } // Extract the path and create a CFURL. if (err == noErr) { err = AEGetKeyPtr( &thisItem, propPath, typeUTF8Text, &junkType, thisPath, sizeof(thisPath) - 1, // to ensure that we can always add null terminator &thisPathSize ); } if (err == noErr) { thisPath[thisPathSize] = 0; err = FSPathMakeRef(thisPath, &thisItemRef, NULL); if (err == noErr) { thisItemURL = CFURLCreateFromFSRef(NULL, &thisItemRef); } else { err = noErr; // swallow error and create an imprecise URL thisItemURL = CFURLCreateFromFileSystemRepresentation( NULL, thisPath, thisPathSize, false ); } if (thisItemURL == NULL) { err = coreFoundationUnknownErr; } } // Extract the hidden flag. if (err == noErr) { err = AEGetKeyPtr( &thisItem, propHidden, typeBoolean, &junkType, &thisItemHidden, sizeof(thisItemHidden), &junkSize ); // Work around <rdar://problem/4052117> by assuming that hidden // is false if we can't get its value. if (err != noErr) { thisItemHidden = false; err = noErr; } } // Create the CFDictionary for this item. if (err == noErr) { CFStringRef keys[2]; CFTypeRef values[2]; keys[0] = kLIAEURL; keys[1] = kLIAEHidden; values[0] = thisItemURL; values[1] = (thisItemHidden ? kCFBooleanTrue : kCFBooleanFalse); thisItemDict = CFDictionaryCreate( NULL, (const void **) keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); if (thisItemDict == NULL) { err = coreFoundationUnknownErr; } } // Add it to the results array. if (err == noErr) { CFArrayAppendValue(result, thisItemDict); } AEDisposeDescQ(&thisItem); CFQRelease(thisItemURL); CFQRelease(thisItemDict); if (err != noErr) { break; } } } // Clean up. if (err != noErr) { CFQRelease(result); result = NULL; } *itemsPtr = result; assert( (err == noErr) == (*itemsPtr != NULL) ); return err; }
// This routine's input is an AEDescList that contains replies // from the "properties of every login item" event. Each element // of the list is an AERecord with two important properties, // "path" and "hidden". This routine creates a CFArray that // corresponds to this list. Each element of the CFArray // contains two properties, kLIAEURL and // kLIAEHidden, that are derived from the corresponding // AERecord properties. // // On entry, descList must not be NULL // On entry, itemsPtr must not be NULL // On entry, *itemsPtr must be NULL // On success, *itemsPtr will be a valid CFArray // On error, *itemsPtr will be NULL static OSStatus CreateCFArrayFromAEDescList(const AEDescList *descList, CFArrayRef *itemsPtr) { if (!descList || !itemsPtr) return paramErr; check(*itemsPtr == NULL); // Create a place for the result. OSStatus err = noErr; CFMutableArrayRef result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); if (result == NULL) err = coreFoundationUnknownErr; // For each element in the descriptor list... long itemCount; if (err == noErr) err = AECountItems(descList, &itemCount); if (err == noErr) { for (long itemIndex = 1; itemIndex <= itemCount; itemIndex++) { UInt8 thisPath[1024]; Size thisPathSize; FSRef thisItemRef; CFURLRef thisItemURL; Boolean thisItemHidden; CFDictionaryRef thisItemDict; AERecord thisItem = WBAEEmptyDesc(); thisItemURL = NULL; thisItemDict = NULL; // Get this element's AERecord. AEKeyword junkKeyword; err = AEGetNthDesc(descList, itemIndex, typeAERecord, &junkKeyword, &thisItem); // Extract the path and create a CFURL. if (err == noErr) { err = AEGetKeyPtr(&thisItem, propPath, typeUTF8Text, NULL, thisPath, sizeof(thisPath) - 1, // to ensure that we can always add null terminator &thisPathSize); } if (err == noErr) { thisPath[thisPathSize] = 0; /* resolve symlink */ err = FSPathMakeRef(thisPath, &thisItemRef, NULL); if (err == noErr) { thisItemURL = CFURLCreateFromFSRef(NULL, &thisItemRef); } else { err = noErr; // swallow error and create an imprecise URL thisItemURL = CFURLCreateFromFileSystemRepresentation(NULL, thisPath, thisPathSize, false); } if (thisItemURL == NULL) { err = coreFoundationUnknownErr; } } // Extract the hidden flag. if (err == noErr) { err = AEGetKeyPtr(&thisItem, propHidden, typeBoolean, NULL, &thisItemHidden, sizeof(thisItemHidden), NULL); // Work around <rdar://problem/4052117> by assuming that hidden // is false if we can't get its value. if (err != noErr) { thisItemHidden = false; err = noErr; } } // Create the CFDictionary for this item. if (err == noErr) { CFStringRef keys[2]; CFTypeRef values[2]; keys[0] = kWBLoginItemURL; keys[1] = kWBLoginItemHidden; values[0] = thisItemURL; values[1] = (thisItemHidden ? kCFBooleanTrue : kCFBooleanFalse); thisItemDict = CFDictionaryCreate(kCFAllocatorDefault, (const void **) keys, values, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); if (thisItemDict == NULL) { err = coreFoundationUnknownErr; } } // Add it to the results array. if (err == noErr) { CFArrayAppendValue(result, thisItemDict); } WBAEDisposeDesc(&thisItem); if (thisItemURL) CFRelease(thisItemURL); if (thisItemDict) CFRelease(thisItemDict); if (err != noErr) { break; } } } // Clean up. if (err != noErr) { if (result) CFRelease(result); result = NULL; } *itemsPtr = result; check( (err == noErr) == (*itemsPtr != NULL) ); return err; }
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); }