Ignore:
Timestamp:
02/13/04 21:01:06 (20 years ago)
Author:
Nicholas Riley
Message:

Integrates SCPatch and mach_inject; unfinished, buggy.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cocoa/F-Script Anywhere/Source/FSAAppList.m

    r19 r153  
    2525*/
    2626
     27#import "FSAAppList.h"
    2728#import "FSAnywhere.h"
    28 #import "FSAAppList.h"
    29 #import "FSAApp.h"
    3029#import "libMatch.h"
    3130#import "DeVercruesseProcessManager.h"
     
    4342NSString *FSACheckMarkCharacter;
    4443NSImage *FSACheckMarkImage;
     44
     45NSString *FSAEllipsisCharacter;
     46NSImage *FSAEllipsisImage;
    4547
    4648static const char *FSACocoaFrameworks[] = {
     
    6567        FSALog(@"Falling back to checkmark image from bundle: %@", FSACheckMarkImage);
    6668    }
     69    FSAEllipsisCharacter = [[NSString alloc] initWithCharacters: (const unichar *)"\x20\x26" length: 1];
     70    FSAEllipsisImage = [[NSImage alloc] initByReferencingFile: [[NSBundle mainBundle] pathForResource: @"Ellipsis" ofType: @"tiff"]];
     71    if (FSAEllipsisImage != nil && ![FSAEllipsisImage isValid]) {
     72        [FSAEllipsisImage release];
     73        FSAEllipsisImage = nil;
     74    }
    6775}
    6876
     
    7482    cocoaApps = [[NSMutableArray alloc] init];
    7583    patchedApps = [[NSMutableSet alloc] init];
     84    patchingApps = [[NSMutableSet alloc] init];
    7685    appsByPID = [[NSMutableDictionary alloc] init];
    7786
     
    8594    [self update];
    8695    [window makeFirstResponder: tableView];
    87     [window makeKeyAndOrderFront: self];
    8896}
    8997
     
    105113}
    106114
     115- (void)_processStatusChanged;
     116{
     117    [tableView reloadData];
     118    [self tableView: tableView shouldSelectRow: [tableView selectedRow]];
     119}
     120
     121- (DeVercruesseProcess *)_applicationForPID:(pid_t)pid;
     122{
     123    return [appsByPID objectForKey: [NSNumber numberWithInt: pid]];
     124}
     125
    107126- (void)didPatchProcessID:(pid_t)pid;
    108127{
    109     [patchedApps addObject: [appsByPID objectForKey: [NSNumber numberWithInt: pid]]];
    110     [tableView reloadData];
    111     [installButton setEnabled: NO];
     128    DeVercruesseProcess *app = [self _applicationForPID: pid];
     129    [patchingApps removeObject: app];
     130    [patchedApps addObject: app];
     131    [self _processStatusChanged];
     132}
     133
     134- (void)isPatchingProcessID:(pid_t)pid;
     135{
     136    [patchingApps addObject: [self _applicationForPID: pid]];
     137    [self _processStatusChanged];
    112138}
    113139
     
    201227    [cocoaApps removeAllObjects];
    202228    [appsByPID removeAllObjects];
    203     // [processManager update]; // [processManager processes] sends update
     229    // [processManager update] unneeded: [processManager processes] sends update
    204230
    205231    allApps = [processManager processes];
     
    211237
    212238    [tableView noteNumberOfRowsChanged];
    213     [tableView reloadData];
    214     // XXX this is broken, it doesn't update properly
    215     [self tableView: tableView shouldSelectRow: [tableView selectedRow]];
     239    [self _processStatusChanged];
     240}
     241
     242- (NSArray *)cocoaAppProcessIDs;
     243{
     244    NSEnumerator *e = [cocoaApps objectEnumerator];
     245    NSMutableArray *pids = [NSMutableArray arrayWithCapacity: [cocoaApps count]];
     246    DeVercruesseProcess *app;
     247    while ( (app = [e nextObject]) != nil) {
     248        [pids addObject: [NSNumber numberWithInt: [app pid]]];
     249    }
     250    return pids;
    216251}
    217252
    218253- (void)applicationLaunchedWithProcessID:(pid_t)pid;
    219254{
    220     NSNumber *pidNum = [NSNumber numberWithInt: pid];
    221     DeVercruesseProcess *app = [appsByPID objectForKey: pidNum];
    222 
    223     if (app == nil) {
     255    if ([self _applicationForPID: pid] == nil) {
    224256        [self update];
    225257    }
     
    228260- (void)applicationQuitWithProcessID:(pid_t)pid;
    229261{
    230     NSNumber *pidNum = [NSNumber numberWithInt: pid];
    231     DeVercruesseProcess *app = [appsByPID objectForKey: pidNum];
     262    DeVercruesseProcess *app = [self _applicationForPID: pid];
    232263
    233264    if (app != nil) {
    234265        [cocoaApps removeObject: app];
    235         [appsByPID removeObjectForKey: pidNum];
     266        [appsByPID removeObjectForKey: [NSNumber numberWithLong: pid]];
    236267        [patchedApps removeObject: app];
    237268    }
    238269
    239     [tableView reloadData];
     270    [tableView noteNumberOfRowsChanged];
     271    [self _processStatusChanged];
    240272}
    241273
     
    260292
    261293    if (row != -1) {
    262         canInstall = ![patchedApps containsObject: [cocoaApps objectAtIndex: row]];
     294        DeVercruesseProcess *app = [cocoaApps objectAtIndex: row];
     295        canInstall = !([patchedApps containsObject: app] ||
     296                       [patchingApps containsObject: app]);
    263297    }
    264298
     
    286320        return [(DeVercruesseProcess *)[cocoaApps objectAtIndex: rowIndex] name];
    287321    } else if ([columnIdentifier isEqualToString: FSATableColumnIdentifier_checkMark]) {
    288         BOOL isPatched = [patchedApps containsObject: [cocoaApps objectAtIndex: rowIndex]];
    289         if (FSACheckMarkImage == nil)
    290             return isPatched ? FSACheckMarkCharacter : @"";
    291         else
    292             return isPatched ? FSACheckMarkImage : nil;
     322        DeVercruesseProcess *app = [cocoaApps objectAtIndex: rowIndex];
     323        if ([patchedApps containsObject: app]) {
     324            if (FSACheckMarkImage == nil)
     325                return FSACheckMarkCharacter;
     326            else
     327                return FSACheckMarkImage;
     328        }
     329        if ([patchingApps containsObject: app]) {
     330            if (FSAEllipsisImage == nil)
     331                return FSAEllipsisCharacter;
     332            else
     333                return FSAEllipsisImage;
     334        }
    293335    }
    294336    return nil;
     
    327369}
    328370
    329 - (BOOL)windowShouldClose:(id)sender;
    330 {
    331     if ([patchedApps count] != 0) {
    332         NSMutableString *message =  [@"F-Script Anywhere is installed in the following applications:\n\n" mutableCopy];
    333         NSEnumerator *e = [patchedApps objectEnumerator];
    334         DeVercruesseProcess *app;
    335         int retval;
    336 
    337         while ( (app = [e nextObject]) != nil) {
    338             [message appendFormat: @"    ¥ %@\n", [app name]];
    339         }
    340 
    341         [message appendString: @"\nIf F-Script Anywhere quits now, these applications will be forced to quit, and any changes you have made in them will be lost.\n\nPlease quit these applications before quitting F-Script Anywhere, or click Force Quit to continue."];
    342 
    343         retval = NSRunAlertPanel(@"Force applications to quit?", message, @"DonÕt Quit", @"Force Quit", nil);
    344         if (retval != NSAlertAlternateReturn) {
    345             return NO;
    346         }
    347 
    348         [(FSAApp *)NSApp unloadBundles: self];
    349     }
    350 
    351     return YES;
    352 }
    353 
    354371@end
    355372
     
    359376{
    360377    static NSMenu *dockMenu = nil;
    361     NSMenuItem *menuItem;
     378    id<NSMenuItem> menuItem;
    362379    DeVercruesseProcess *frontApp = [processManager frontProcess];
    363380    NSString *appName = [frontApp name];
     
    375392    }
    376393
    377     NSAssert(frontApp != nil && appName != nil, @"CanÕt obtain information on the frontmost application");
     394    NSAssert(frontApp != nil && appName != nil, @"Can't obtain information on the frontmost application");
    378395
    379396    if ([patchedApps containsObject: frontApp]) {
    380         status = [NSString stringWithFormat: @"Installed in Ò%@Ó", appName];
     397        status = [NSString stringWithFormat: NSLocalizedString(@"Installed in '%@'", "Dock menu disabled item displayed when FSA already installed, app name parameter"), appName];
    381398    } else if (![cocoaApps containsObject: frontApp]) {
    382         status = [NSString stringWithFormat: @"CanÕt install because Ò%@Ó is not a Cocoa application", appName];
     399        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];
    383400    }
    384401
    385402    if (status == nil) {
    386         menuItem = [dockMenu addItemWithTitle: [NSString stringWithFormat: @"Install in Ò%@Ó", appName]
     403        menuItem = [dockMenu addItemWithTitle: [NSString stringWithFormat: NSLocalizedString(@"Install in '%@'", "Dock menu item to install FSA in frontmost app"), appName]
    387404                                       action: @selector(invoke)
    388405                                keyEquivalent: @""];
     
    406423}
    407424
    408 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
    409 {
    410     return ([self windowShouldClose: self] ? NSTerminateNow : NSTerminateCancel);
    411 }
    412 
    413425@end
Note: See TracChangeset for help on using the changeset viewer.