Changeset 221 for trunk/Cocoa


Ignore:
Timestamp:
05/11/06 22:26:01 (14 years ago)
Author:
rchin
Message:

We now have a preferences dialog box to remove auto-injected apps, incase the crashes on auto-inject (which would make it difficult to untick the proper box).

Location:
trunk/Cocoa/F-Script Anywhere/Source
Files:
1 added
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cocoa/F-Script Anywhere/Source/English.lproj/MainMenu.nib/info.nib

    r219 r221  
    88        <dict>
    99                <key>29</key>
    10                 <string>61 185 232 44 0 0 1440 878 </string>
     10                <string>54 632 232 44 0 0 1440 878 </string>
    1111        </dict>
    1212        <key>IBFramework Version</key>
     
    1414        <key>IBOpenObjects</key>
    1515        <array>
     16                <integer>229</integer>
    1617                <integer>29</integer>
    1718                <integer>195</integer>
  • trunk/Cocoa/F-Script Anywhere/Source/FSAAppList.h

    r219 r221  
    3535    NSMutableSet *patchedApps;
    3636    NSMutableSet *patchingApps;
    37         NSMutableArray *alwaysApps;
     37    NSMutableArray *alwaysApps;
    3838    IBOutlet NSButton *installButton;
    3939    IBOutlet NSTableView *tableView;
    40         BOOL finishedLaunch;
     40    BOOL finishedLaunch;
    4141}
    4242
  • trunk/Cocoa/F-Script Anywhere/Source/FSAAppList.m

    r220 r221  
    88
    99/*
    10 
     10 
    1111 F-Script Anywhere is free software; you can redistribute it and/or modify
    1212 it under the terms of the GNU General Public License as published by
    1313 the Free Software Foundation; either version 2 of the License, or
    1414 (at your option) any later version.
    15 
     15 
    1616 F-Script Anywhere is distributed in the hope that it will be useful,
    1717 but WITHOUT ANY WARRANTY; without even the implied warranty of
    1818 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1919 GNU General Public License for more details.
    20 
     20 
    2121 You should have received a copy of the GNU General Public License
    2222 along with F-Script Anywhere; if not, write to the Free Software
    2323 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    24 
    25 */
     24 
     25 */
    2626
    2727#include <sys/types.h>
     
    5757
    5858static int sysctlbyname_with_pid (const char *name, pid_t pid,
    59                                                                   void *oldp, size_t *oldlenp,
    60                                                                   void *newp, size_t newlen);
     59                                  void *oldp, size_t *oldlenp,
     60                                  void *newp, size_t newlen);
    6161int is_pid_native (pid_t pid);
    6262
     
    9292    patchingApps = [[NSMutableSet alloc] init];
    9393    appsByPID = [[NSMutableDictionary alloc] init];
    94         if(!([[NSUserDefaults standardUserDefaults] objectForKey:@"AlwaysApps"]))
    95                 alwaysApps = [[NSMutableArray array] retain];
    96         else
    97                 alwaysApps = [[NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"AlwaysApps"]] retain];
    98 
     94    alwaysApps = [[NSMutableArray array] retain];
     95   
    9996    [[tableView tableColumnWithIdentifier: FSATableColumnIdentifier_appNameAndIcon]
    10097        setDataCell: [NJRLabeledImageCell cell]];
     
    103100            setDataCell: [[[NSImageCell alloc] init] autorelease]];
    104101    [window setResizeIncrements: NSMakeSize(1, [tableView cellHeight])];
    105         [tableView setTarget:self];
    106         [tableView setAction:@selector(clickInTable:)];
    107 
     102    [tableView setTarget:self];
     103    [tableView setAction:@selector(clickInTable:)];
     104   
    108105    [self update];
    109106    [window makeFirstResponder: tableView];
     107   
     108    [[NSNotificationCenter defaultCenter] addObserver:self
     109                                             selector:@selector(update)
     110                                                 name:NSUserDefaultsDidChangeNotification
     111                                               object:nil];
    110112}
    111113
     
    123125    int row = [tableView selectedRow];
    124126    if (row == -1) return -1;
    125 
     127   
    126128    return [[cocoaApps objectAtIndex: row] pid];
    127129}
     
    158160    int fd;
    159161    PEFContainerHeader pefHeader;
    160 
     162   
    161163    if (bundleExecutableLoc == NULL)
    162164        return NO;
     
    164166    if ( (bundleExecutablePath = [bundleExecutableLoc fileSystemRepresentation]) == NULL)
    165167        return NO;
    166 
     168   
    167169    if ( (fd = open(bundleExecutablePath, O_RDONLY, 0)) == -1)
    168170        return NO;
    169 
     171   
    170172    if (read(fd, &pefHeader, sizeof(pefHeader)) != sizeof(pefHeader))
    171173        return NO;
     
    173175    if (pefHeader.tag1 != kPEFTag1 || pefHeader.tag2 != kPEFTag2)
    174176        return NO;
    175 
     177   
    176178    return YES;
    177179}
     
    187189-(BOOL)appIsNative:(DeVercruesseProcess *)app
    188190{
    189         return is_pid_native([app pid]);
     191    return is_pid_native([app pid]);
    190192}
    191193
     
    193195{
    194196    /* Try to determine if the application is a foreground Cocoa application.
    195        In Jaguar, itÕs possible to mix Cocoa in a primarily Carbon application,
    196        but we don't support such hybrids because the menu items we add depend
    197        on Cocoa dispatch mechanisms.
    198    
    199        The CPS 'flavor' mechanism (isCarbon, isCocoa) is broken in Mac OS X
    200        10.1.2 through 10.1.5 and possibly earlier, reporting that all Cocoa apps
    201        are Carbon apps.  So we use some code extracted from otool to check
    202        whether the application links to the Foundation, AppKit or Cocoa
    203        frameworks.  This problem is fixed in Jaguar, except that certain CFM
    204        Carbon apps are reported to be Cocoa apps (Drop Drawers is one example).
    205        Conversely, the appIsCocoa: code works on _most_ applications, but
    206        Jaguar always correctly identifies Cocoa apps as isCocoa.
    207 
    208        So, our checks go like this:
    209          Is the application background-only?
    210          Is the application Cocoa or Carbon according to the CPS flavor?
    211            If it's Cocoa, is it a CFM app?  If so, CPS is lying to us.
    212            If it's "Carbon", does it link to AppKit, Foundation or Cocoa?
    213              If so, it's really a Cocoa app.  If not, it's a Carbon app.
    214    
    215        Be careful not to call appIsCocoa: on a Classic application, you will
    216        crash.
     197    In Jaguar, itÕs possible to mix Cocoa in a primarily Carbon application,
     198    but we don't support such hybrids because the menu items we add depend
     199    on Cocoa dispatch mechanisms.
     200   
     201    The CPS 'flavor' mechanism (isCarbon, isCocoa) is broken in Mac OS X
     202    10.1.2 through 10.1.5 and possibly earlier, reporting that all Cocoa apps
     203    are Carbon apps.  So we use some code extracted from otool to check
     204    whether the application links to the Foundation, AppKit or Cocoa
     205    frameworks.  This problem is fixed in Jaguar, except that certain CFM
     206    Carbon apps are reported to be Cocoa apps (Drop Drawers is one example).
     207    Conversely, the appIsCocoa: code works on _most_ applications, but
     208    Jaguar always correctly identifies Cocoa apps as isCocoa.
     209   
     210    So, our checks go like this:
     211    Is the application background-only?
     212    Is the application Cocoa or Carbon according to the CPS flavor?
     213    If it's Cocoa, is it a CFM app?  If so, CPS is lying to us.
     214    If it's "Carbon", does it link to AppKit, Foundation or Cocoa?
     215    If so, it's really a Cocoa app.  If not, it's a Carbon app.
     216   
     217    Be careful not to call appIsCocoa: on a Classic application, you will
     218    crash.
    217219    */
    218 
     220   
    219221    /*
    220     if ([app isCocoa] || [app isCarbon]) {
    221         NSLog(@"%@ |%@%@%@%@%@", [app name],
    222               [app isBackgroundOnly] ? @" bgOnly" : @"",
    223               [app isCocoa] ? @" isCocoa" : @"",
    224               [app isCarbon] ? @" isCarbon" : @"",
    225               [self appIsPEF: app] ? @" appIsPEF" : @"",
    226               [self appIsCocoa: app] ? @" appIsCocoa" : @"");
    227     }
    228     */
    229          
     222     if ([app isCocoa] || [app isCarbon]) {
     223        NSLog(@"%@ |%@%@%@%@%@", [app name],
     224               [app isBackgroundOnly] ? @" bgOnly" : @"",
     225               [app isCocoa] ? @" isCocoa" : @"",
     226               [app isCarbon] ? @" isCarbon" : @"",
     227               [self appIsPEF: app] ? @" appIsPEF" : @"",
     228               [self appIsCocoa: app] ? @" appIsCocoa" : @"");
     229     }
     230     */
     231   
    230232    if ( ![app isBackgroundOnly] &&
    231233         ( ( [app isCocoa] && ![self appIsPEF: app]) ||
    232234           ( [app isCarbon] && [self appIsCocoa: app]))) {
    233                 if([self appIsNative:app]){
    234                         [cocoaApps addObject: app];
    235                         if(finishedLaunch){
    236                                 if([alwaysApps containsObject:[app name]] && ![patchedApps containsObject:app])
    237                                         [NSApp installBundleInAppWithPID:[app pid]];
    238                         }
    239                 }
     235        if([self appIsNative:app]){
     236            [cocoaApps addObject: app];
     237            if(finishedLaunch){
     238                if([alwaysApps containsObject:[app name]] && ![patchedApps containsObject:app])
     239                    [NSApp installBundleInAppWithPID:[app pid]];
     240            }
     241        }
    240242    }
    241243    [appsByPID setObject: app forKey: [NSNumber numberWithInt: [app pid]]];     
     
    249251    NSArray *allApps;
    250252    DeVercruesseProcess *app;
    251 
     253   
    252254    [cocoaApps removeAllObjects];
    253255    [appsByPID removeAllObjects];
    254256    // [processManager update] unneeded: [processManager processes] sends update
    255 
     257   
    256258    allApps = [processManager processes];
    257259    e = [allApps objectEnumerator];
    258 
     260   
    259261    while ( (app = [e nextObject]) != nil) {
    260262        [self addApp: app];
    261263    }
    262264
     265    if([[NSUserDefaults standardUserDefaults] objectForKey:@"AlwaysApps"]){
     266        [[NSUserDefaults standardUserDefaults] synchronize];
     267        [alwaysApps removeAllObjects];
     268        [alwaysApps addObjectsFromArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"AlwaysApps"]];
     269        [tableView reloadData];
     270    }
    263271    [tableView noteNumberOfRowsChanged];
    264272    [self _processStatusChanged];
     
    286294{
    287295    DeVercruesseProcess *app = [self _applicationForPID: pid];
    288 
     296   
    289297    if (app != nil) {
    290298        [cocoaApps removeObject: app];
     
    292300        [patchedApps removeObject: app];
    293301    }
    294 
     302   
    295303    [tableView noteNumberOfRowsChanged];
    296304    [self _processStatusChanged];
     
    305313    if ([[tableColumn identifier] isEqualToString: FSATableColumnIdentifier_appNameAndIcon]) {
    306314        DeVercruesseProcess *app = [cocoaApps objectAtIndex: row];
    307 
     315       
    308316        NSAssert1([cell isKindOfClass: [NJRLabeledImageCell class]], @"Cell is not what we expected, instead %@", cell);
    309317        [(NJRLabeledImageCell *)cell setImage: [app img]];
     
    315323{
    316324    BOOL canInstall = NO;
    317 
     325   
    318326    if (row != -1) {
    319327        DeVercruesseProcess *app = [cocoaApps objectAtIndex: row];
     
    321329                       [patchingApps containsObject: app]);
    322330    }
    323 
     331   
    324332    [installButton setEnabled: canInstall];
    325333   
     
    338346- (id)tableView:(NSTableView *)aTableView
    339347    objectValueForTableColumn:(NSTableColumn *)aTableColumn
    340     row:(int)rowIndex
     348            row:(int)rowIndex
    341349{
    342350    NSString *columnIdentifier = [aTableColumn identifier];
     
    359367        }
    360368    } else if([columnIdentifier isEqualToString:FSATableColumnIdentifier_always]){
    361                 if([alwaysApps containsObject:[[cocoaApps objectAtIndex: rowIndex] name]])
    362                         return [NSNumber numberWithBool:YES];
    363                 else
    364                         return [NSNumber numberWithBool:NO];
    365         }
     369        if([alwaysApps containsObject:[[cocoaApps objectAtIndex: rowIndex] name]])
     370            return [NSNumber numberWithBool:YES];
     371        else
     372            return [NSNumber numberWithBool:NO];
     373    }
    366374    return nil;
    367375}
     
    379387    float heightChange = [[scrollView documentView] bounds].size.height - displayedHeight;
    380388    float heightExcess;
    381 
     389   
    382390    if (heightChange >= 0 && heightChange <= 1) {
    383391        // either the window is already optimal size, or it's too big
     
    385393        heightChange = (rowHeight * [tableView numberOfRows]) - displayedHeight;
    386394    }
    387 
     395   
    388396    frame.size.height += heightChange;
    389 
     397   
    390398    if ( (heightExcess = [window minSize].height - frame.size.height) > 1 ||
    391399         (heightExcess = [window maxSize].height - frame.size.height) < 1) {
     
    393401        frame.size.height += heightExcess;
    394402    }
    395 
     403   
    396404    frame.origin.y -= heightChange;
    397 
     405   
    398406    return frame;
    399407}
     
    413421    NSMethodSignature *sig = [NSApp methodSignatureForSelector: @selector(installBundleInFrontmostApp:)];
    414422    NSInvocation *inv;
    415 
     423   
    416424    if (dockMenu != nil) {
    417425        // XXX release invocation
     
    421429        dockMenu = [[NSMenu alloc] init];
    422430    }
    423 
     431   
    424432    NSAssert(frontApp != nil && appName != nil, @"Can't obtain information on the frontmost application");
    425 
     433   
    426434    if ([patchedApps containsObject: frontApp]) {
    427435        status = [NSString stringWithFormat: NSLocalizedString(@"Installed in '%@'", "Dock menu disabled item displayed when FSA already installed, app name parameter"), appName];
     
    429437        status = [NSString stringWithFormat: NSLocalizedString(@"Can't install because '%@' is not a Cocoa application", "Dock menu disabled item displayed when frontmost app not Cocoa, app name parameter"), appName];
    430438    }
    431 
     439   
    432440    if (status == nil) {
    433441        menuItem = [dockMenu addItemWithTitle: [NSString stringWithFormat: NSLocalizedString(@"Install in '%@'", "Dock menu item to install FSA in frontmost app"), appName]
     
    444452        [menuItem setEnabled: NO];
    445453    }
    446 
     454   
    447455    return dockMenu;
    448456}
     
    450458- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    451459{
    452         id anApp;
    453         id e = [cocoaApps objectEnumerator];
    454         while(anApp = [e nextObject]){
    455                 if([alwaysApps containsObject:[anApp name]] && ![patchedApps containsObject:anApp]){
    456                         [NSApp installBundleInAppWithPID:[anApp pid]];
    457                 }
     460    id anApp;
     461    id e = [cocoaApps objectEnumerator];
     462    while(anApp = [e nextObject]){
     463        if([alwaysApps containsObject:[anApp name]] && ![patchedApps containsObject:anApp]){
     464            [NSApp installBundleInAppWithPID:[anApp pid]];
    458465        }
    459         finishedLaunch = YES;
     466    }
     467    finishedLaunch = YES;
    460468}
    461469
     
    467475-(void)clickInTable:(id)sender
    468476{
    469         if([sender clickedColumn] == 2){
    470                 if([sender clickedRow] >= 0){
    471                         NSString *appName = [[cocoaApps objectAtIndex:[sender clickedRow]] name];
    472                         if(![alwaysApps containsObject:appName]){
    473                                 [NSApp installBundleInAppWithPID:[[cocoaApps objectAtIndex:[sender clickedRow]] pid]];
    474                                 [alwaysApps addObject:appName];
    475                         } else
    476                                 [alwaysApps removeObject:appName];
    477                         [[NSUserDefaults standardUserDefaults] setObject:alwaysApps forKey:@"AlwaysApps"];
    478                 }
     477    if([sender clickedColumn] == 2){
     478        if([sender clickedRow] >= 0){
     479            NSString *appName = [[cocoaApps objectAtIndex:[sender clickedRow]] name];
     480            if(![alwaysApps containsObject:appName]){
     481                [NSApp installBundleInAppWithPID:[[cocoaApps objectAtIndex:[sender clickedRow]] pid]];
     482                [alwaysApps addObject:appName];
     483            } else
     484                [alwaysApps removeObject:appName];
     485            [[NSUserDefaults standardUserDefaults] setObject:alwaysApps forKey:@"AlwaysApps"];
    479486        }
     487    }
    480488}
    481489
     
    483491
    484492static int sysctlbyname_with_pid (const char *name, pid_t pid,
    485                                                                   void *oldp, size_t *oldlenp,
    486                                                                   void *newp, size_t newlen)
     493                                  void *oldp, size_t *oldlenp,
     494                                  void *newp, size_t newlen)
    487495{
    488496    if (pid == 0) {
    489497        if (sysctlbyname(name, oldp, oldlenp, newp, newlen) == -1)  {
    490498            fprintf(stderr, "sysctlbyname_with_pid(0): sysctlbyname  failed:"
    491                                         "%s\n", strerror(errno));
     499                    "%s\n", strerror(errno));
    492500            return -1;
    493501        }
     
    497505        if (sysctlnametomib(name, mib, &len) == -1) {
    498506            fprintf(stderr, "sysctlbyname_with_pid: sysctlnametomib  failed:"
    499                                         "%s\n", strerror(errno));
     507                    "%s\n", strerror(errno));
    500508            return -1;
    501509        }
     
    515523    int ret = 0;
    516524    size_t sz = sizeof(ret);
    517        
     525   
    518526    if (sysctlbyname_with_pid("sysctl.proc_native", pid,
    519                                                           &ret, &sz, NULL, 0) == -1) {
    520                 if (errno == ENOENT) {
     527                              &ret, &sz, NULL, 0) == -1) {
     528        if (errno == ENOENT) {
    521529            // sysctl doesn't exist, which means that this version of Mac OS
    522530            // pre-dates Rosetta, so the application must be native.
Note: See TracChangeset for help on using the changeset viewer.