Changeset 16 for trunk/Cocoa/F-Script Anywhere/Source/FSAAppList.m
- Timestamp:
- 10/20/02 04:46:29 (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cocoa/F-Script Anywhere/Source/FSAAppList.m
r7 r16 25 25 */ 26 26 27 #import "FSAnywhere.h" 27 28 #import "FSAAppList.h" 28 29 #import "FSAApp.h" … … 32 33 #import "NSTableView-NJRExtensions.h" 33 34 35 // for appIsPEF: 36 #import <Carbon/Carbon.h> 37 #import <fcntl.h> 38 #import <unistd.h> 39 34 40 NSString * const FSATableColumnIdentifier_appNameAndIcon = @"appNameAndIcon"; 35 41 NSString * const FSATableColumnIdentifier_checkMark = @"checkMark"; 36 42 37 43 NSString *FSACheckMarkCharacter; 44 NSImage *FSACheckMarkImage; 38 45 39 46 static const char *FSACocoaFrameworks[] = { … … 46 53 @implementation FSAAppList 47 54 48 + (void) load;55 + (void)initialize; 49 56 { 50 57 FSACheckMarkCharacter = [[NSString alloc] initWithCharacters: (const unichar *)"\x27\x13" length: 1]; 58 FSACheckMarkImage = [NSImage imageNamed: @"NSMenuCheckmark"]; 59 if (FSACheckMarkImage == nil) { 60 FSACheckMarkImage = [[NSImage alloc] initByReferencingFile: [[NSBundle mainBundle] pathForResource: @"Fallback checkmark" ofType: @"tiff"]]; 61 if (FSACheckMarkImage != nil && ![FSACheckMarkImage isValid]) { 62 [FSACheckMarkImage release]; 63 FSACheckMarkImage = nil; 64 } 65 FSALog(@"Falling back to checkmark image from bundle: %@", FSACheckMarkImage); 66 } 51 67 } 52 68 … … 60 76 [[tableView tableColumnWithIdentifier: FSATableColumnIdentifier_appNameAndIcon] 61 77 setDataCell: [NJRLabeledImageCell cell]]; 78 if (FSACheckMarkImage != nil) 79 [[tableView tableColumnWithIdentifier: FSATableColumnIdentifier_checkMark] 80 setDataCell: [[[NSImageCell alloc] init] autorelease]]; 62 81 [[tableView window] setResizeIncrements: NSMakeSize(1, [tableView cellHeight])]; 63 82 … … 90 109 } 91 110 111 - (BOOL)appIsPEF:(DeVercruesseProcess *)app; 112 { 113 NSString *bundleExecutableLoc = [app executableLoc]; 114 const char *bundleExecutablePath; 115 int fd; 116 PEFContainerHeader pefHeader; 117 118 if (bundleExecutableLoc == NULL) 119 return NO; 120 121 if ( (bundleExecutablePath = [bundleExecutableLoc fileSystemRepresentation]) == NULL) 122 return NO; 123 124 if ( (fd = open(bundleExecutablePath, O_RDONLY, 0)) == -1) 125 return NO; 126 127 if (read(fd, &pefHeader, sizeof(pefHeader)) != sizeof(pefHeader)) 128 return NO; 129 130 if (pefHeader.tag1 != kPEFTag1 || pefHeader.tag2 != kPEFTag2) 131 return NO; 132 133 return YES; 134 } 135 92 136 - (BOOL)appIsCocoa:(DeVercruesseProcess *)app; 93 137 { … … 100 144 - (void)addApp:(DeVercruesseProcess *)app; 101 145 { 102 if ( ([app isCarbon] || [app isCocoa]) // XXX OS X 10.1.2 (and earlier?) bug, Cocoa reported as Carbon 103 && ![app isBackgroundOnly] 104 && [self appIsCocoa: app]) { 146 /* Try to determine if the application is a foreground Cocoa application. 147 In Jaguar, itÕs possible to mix Cocoa in a primarily Carbon application, 148 but we don't support such hybrids because the menu items we add depend 149 on Cocoa dispatch mechanisms. 150 151 The CPS 'flavor' mechanism (isCarbon, isCocoa) is broken in Mac OS X 152 10.1.2 through 10.1.5 and possibly earlier, reporting that all Cocoa apps 153 are Carbon apps. So we use some code extracted from otool to check 154 whether the application links to the Foundation, AppKit or Cocoa 155 frameworks. This problem is fixed in Jaguar, except that certain CFM 156 Carbon apps are reported to be Cocoa apps (Drop Drawers is one example). 157 Conversely, the appIsCocoa: code works on _most_ applications, but 158 Jaguar always correctly identifies Cocoa apps as isCocoa. 159 160 So, our checks go like this: 161 Is the application background-only? 162 Is the application Cocoa or Carbon according to the CPS flavor? 163 If it's Cocoa, is it a CFM app? If so, CPS is lying to us. 164 If it's "Carbon", does it link to AppKit, Foundation or Cocoa? 165 If so, it's really a Cocoa app. If not, it's a Carbon app. 166 167 Be careful not to call appIsCocoa: on a Classic application, you will 168 crash. 169 */ 170 171 /* 172 if ([app isCocoa] || [app isCarbon]) { 173 NSLog(@"%@ |%@%@%@%@%@", [app name], 174 [app isBackgroundOnly] ? @" bgOnly" : @"", 175 [app isCocoa] ? @" isCocoa" : @"", 176 [app isCarbon] ? @" isCarbon" : @"", 177 [self appIsPEF: app] ? @" appIsPEF" : @"", 178 [self appIsCocoa: app] ? @" appIsCocoa" : @""); 179 } 180 */ 181 182 if ( ![app isBackgroundOnly] && 183 ( ( [app isCocoa] && ![self appIsPEF: app]) || 184 ( [app isCarbon] && [self appIsCocoa: app]))) { 105 185 [cocoaApps addObject: app]; 106 186 } … … 203 283 return [(DeVercruesseProcess *)[cocoaApps objectAtIndex: rowIndex] name]; 204 284 } else if ([columnIdentifier isEqualToString: FSATableColumnIdentifier_checkMark]) { 205 return [patchedApps containsObject: [cocoaApps objectAtIndex: rowIndex]] ? FSACheckMarkCharacter : @""; 285 BOOL isPatched = [patchedApps containsObject: [cocoaApps objectAtIndex: rowIndex]]; 286 if (FSACheckMarkImage == nil) 287 return isPatched ? FSACheckMarkCharacter : @""; 288 else 289 return isPatched ? FSACheckMarkImage : nil; 206 290 } 207 291 return nil;
Note:
See TracChangeset
for help on using the changeset viewer.