Ignore:
Timestamp:
01/30/03 05:31:29 (21 years ago)
Author:
Nicholas Riley
Message:

ICeCoffEE 1.3b2 plus some changes for 1.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ICeCoffEE/ICeCoffEE/APEMain.m

    r66 r74  
    1717#import <objc/objc-runtime.h>
    1818#import "ICeCoffEE.h"
     19#import "ICeCoffEETextEdit.h"
    1920
    2021//¥¥¥ Our settings
     
    2223//¥¥¥ Function prototypes
    2324static void ICCF_ReloadPrefs();                         // reloads our preferences
     25static void ICCF_MigratePrefs();                        // migrates prefs from 1.0Ð1.2
    2426
    2527//¥¥¥ Enter sandman, the code begins --
     
    2830    struct objc_class *patchclass = objc_getClass(patchclass ## Name); \
    2931    if (patchclass == NULL) { \
    30         apeprintf("can't get %s\n", patchclass ## Name); \
     32        ICapeprintf("can't get %s\n", patchclass ## Name); \
    3133        return NO; \
    3234    }
     
    3537    Method name = class_getInstanceMethod(patchclass, sel); \
    3638    if (name == NULL) { \
    37         apeprintf("can't get %s\n", patchclass ## Name); \
     39        ICapeprintf("can't get %s\n", patchclass ## Name); \
    3840        return NO; \
    3941    }
     
    5456    ICCF_GET_METHOD(patchSuperMethod, patchSuperclass, selector);
    5557
    56     APEPatchCreate(patchSuperMethod->method_imp,
    57                    APEPatchCreate(patcheeMethod->method_imp, patchMethod->method_imp));
     58    if (APEPatchCreate(patchSuperMethod->method_imp,
     59                       APEPatchCreate(patcheeMethod->method_imp, patchMethod->method_imp)) == NULL) {
     60        ICapeprintf("can't patch class %s with [%s %s] super %s", patcheeClassName, patchClassName, selectorString, patchSuperclassName);
     61        return NO;
     62    }
    5863    return YES;
    5964}
     65
     66CFBundleRef ICCF_bundle;
    6067
    6168void APEBundleMain(CFBundleRef inBundle)
    6269{
     70    ICCF_MigratePrefs();
     71
    6372    // first check if this application is in the exclude list;
    6473    // if it is, simply return and do not apply any patches.
    6574    // APETools will help us with that; APE Manager will take care of
    6675    // exclude list management for us.
    67     if (APEToolsIsInExcludeList(CFSTR("net.sabi.ICeCoffEE"), NULL))
     76    if (APEToolsIsInExcludeList(kICBundleIdentifier, NULL))
    6877    {
    69         apeprintf("ICeCoffEE APE: not loading as this application is excluded.\n");
     78        ICapeprintf("ICeCoffEE APE: not loading as this application is excluded.\n");
    7079        return;
    7180    }
    72    
    73     ICCF_ReloadPrefs();                                 // load your preferences
    74     // Add any of your initialization here...
    75 
     81
     82    ICCF_bundle = CFBundleGetBundleWithIdentifier(kICBundleIdentifier);
    7683    CFStringRef bundleID = CFBundleGetIdentifier(CFBundleGetMainBundle());
    77     BOOL shouldLoadAlways = YES;
    78    
     84    BOOL shouldLoadInNSTextView = YES;
     85
     86    // XXX handle patching error return from ICCF_PatchMethod
    7987    if (bundleID != NULL) {
    8088        if (CFStringCompare(bundleID, CFSTR("com.apple.projectbuilder"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
    8189            ICCF_PatchMethod("PBXTextView", "ICeCoffEEMenuOnly", "ICeCoffEEMenuSuper", "menuForEvent:");
    82             apeprintf("ICeCoffEE APE: loading in PB!\n");
    83             shouldLoadAlways = NO;
     90            ICapeprintf("ICeCoffEE APE: loaded in PBXTextView for PB!\n");
     91            shouldLoadInNSTextView = NO;
    8492        } else if (CFStringCompare(bundleID, CFSTR("com.apple.terminal"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
    85             ICCF_PatchMethod("TermSubview", "ICeCoffEEMenuOnly", "ICeCoffEEMenuSuper", "menuForEvent:");
    86             apeprintf("ICeCoffEE APE: loading in Terminal!\n");
     93            ICCF_PatchMethod("TermSubview", "ICeCoffEEMenuOnly", "ICeCoffEEMenuSuper", "menuForEvent:") &&
     94            ICCF_PatchMethod("TermSubview", "ICeCoffEETerminal", "ICECoffEETermSubviewSuper", "selectedRange") &&
     95            ICCF_PatchMethod("TermSubview", "ICeCoffEETerminal", "ICECoffEETermSubviewSuper", "attributedSubstringFromRange:") &&
     96            ICCF_PatchMethod("TermSubview", "ICeCoffEETerminal", "ICECoffEETermSubviewSuper", "mouseDown:") &&
     97            ICCF_PatchMethod("TermSubview", "ICeCoffEETerminal", "ICECoffEETermSubviewSuper", "mouseUp:") &&
     98            ICCF_PatchMethod("TermSubview", "ICeCoffEETerminal", "ICECoffEETermSubviewSuper", "_optionClickEvent:::") ,
     99            ICapeprintf("ICeCoffEE APE: loaded in TermSubview for Terminal!\n");
    87100        } else if (CFStringCompare(bundleID, CFSTR("com.apple.safari"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
    88             ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "mouseUp:");
    89             ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "mouseDown:");
    90             ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "menuForEvent:");
    91             apeprintf("ICeCoffEE APE: loading in Safari!\n");
     101            ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "mouseUp:") &&
     102            ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "mouseDown:") &&
     103            ICCF_PatchMethod("WebHTMLView", "ICeCoffEEWebKit", "ICeCoffEEWebKitSuper", "menuForEvent:") ,
     104            ICapeprintf("ICeCoffEE APE: loaded in WebHTMLView for Safari!\n");
    92105        }
    93106    }
    94107
    95     if (shouldLoadAlways) {
    96         ICCF_PatchMethod("NSTextView", "ICeCoffEE", "ICeCoffEESuper", "mouseDown:");
    97         ICCF_PatchMethod("NSTextView", "ICeCoffEE", "ICeCoffEESuper", "menuForEvent:");
    98         apeprintf("ICeCoffEE APE: loading\n");
    99     }
    100 
    101     ICCF_AddServicesMenu();
     108    if (shouldLoadInNSTextView) {
     109        ICCF_PatchMethod("NSTextView", "ICeCoffEE", "ICeCoffEESuper", "mouseDown:") &&
     110        ICCF_PatchMethod("NSTextView", "ICeCoffEE", "ICeCoffEESuper", "menuForEvent:") ,
     111        ICapeprintf("ICeCoffEE APE: loaded generic NSTextView support\n");
     112    }
     113
     114    gTEClick = APEPatchCreate(&TEClick, &ICCF_TEClick);
     115    if (gTEClick != NULL) {
     116        ICapeprintf("ICeCoffEE APE: patched TEClick\n");
     117    }
     118
     119    ICCF_ReloadPrefs();
    102120       
    103121    return;
     
    107125OSStatus APEBundleMessage(CFStringRef message,CFDataRef inData,CFDataRef *outData)
    108126{
    109     apeprintf("ICeCoffEE APE: message '%@' (inData = %@)\n", message, inData);
    110    
    111     if (CFStringCompare(message, CFSTR("Refresh"), NULL) == kCFCompareEqualTo)         
     127    ICapeprintf("ICeCoffEE APE: message '%@' (inData = %@)\n", message, inData);
     128   
     129    if (CFStringCompare(message, kICPreferencesChanged, NULL) == kCFCompareEqualTo)             
    112130    {   // request to reload prefs from our preference pane
    113131        ICCF_ReloadPrefs();
     
    117135}
    118136
    119 // Reload our settings from the (nonexistent) plist
    120 static void ICCF_ReloadPrefs()
    121 {
    122     CFPreferencesAppSynchronize(CFSTR("net.sabi.ICeCoffEE"));
    123 
    124     // Load your preferences here...
    125 }
     137Boolean ICCF_GetBooleanPref(CFStringRef prefKey, Boolean defaultValue) {
     138    Boolean keyExists;
     139    Boolean value = CFPreferencesGetAppBooleanValue(prefKey, kICBundleIdentifier, &keyExists);
     140    if (keyExists) return value;
     141    CFPreferencesSetAppValue(prefKey, defaultValue ? kCFBooleanTrue : kCFBooleanFalse, kICBundleIdentifier);
     142    return defaultValue;
     143}
     144
     145CFIndex ICCF_GetCFIndexPref(CFStringRef prefKey, CFIndex defaultValue) {
     146    Boolean keyExists;
     147    CFIndex value = CFPreferencesGetAppIntegerValue(prefKey, kICBundleIdentifier, &keyExists);
     148    if (keyExists) return value;
     149    CFNumberRef defaultValueNumber = CFNumberCreate(NULL, kCFNumberCFIndexType, &defaultValue);
     150    CFPreferencesSetAppValue(prefKey, defaultValueNumber, kICBundleIdentifier);
     151    CFRelease(defaultValueNumber);
     152    return defaultValue;
     153}
     154
     155// to test: defaults write net.sabi.ICeCoffEE "Excluded Applications" -array '{CFBundleID = "com.apple.projectbuilder"; }' '{CFBundleID = "net.sabi.Pester"; }' '{CFBundleID = "com.apple.foobar"; }'
     156static void ICCF_MigratePrefs() {
     157   
     158    CFArrayRef prefExcludedApps = CFPreferencesCopyAppValue(kIC12PrefExcluded, kICBundleIdentifier);
     159
     160    if (prefExcludedApps == NULL) return;
     161
     162    if (CFGetTypeID(prefExcludedApps) != CFArrayGetTypeID()) {
     163        CFRelease(prefExcludedApps);
     164        return;
     165    }
     166   
     167    CFMutableArrayRef excludedApps = CFArrayCreateMutableCopy(NULL, 0, prefExcludedApps);
     168    CFRelease(prefExcludedApps); prefExcludedApps = NULL;
     169
     170    ICapeprintf("Excluded apps: %@\n", excludedApps);
     171
     172    CFIndex excludedAppCount = CFArrayGetCount(excludedApps);
     173    CFIndex excludedAppIndex;
     174
     175    CFDictionaryRef excludedAppSpecifiers = NULL;
     176    CFStringRef excludedAppBundleID = NULL;
     177    CFURLRef excludedAppURL = NULL;
     178    CFBundleRef excludedAppBundle = NULL;
     179
     180    BOOL postponeMigrationForApp;
     181
     182    for (excludedAppIndex = excludedAppCount - 1 ; excludedAppIndex >= 0 ; excludedAppIndex--) {
     183        if ( (excludedAppSpecifiers = CFArrayGetValueAtIndex(excludedApps, excludedAppIndex)) == NULL || CFGetTypeID(excludedAppSpecifiers) != CFDictionaryGetTypeID()) {
     184            CFArrayRemoveValueAtIndex(excludedApps, excludedAppIndex);
     185            continue;
     186        }
     187
     188        postponeMigrationForApp = NO;
     189        if ( (excludedAppBundleID = CFDictionaryGetValue(excludedAppSpecifiers, kIC12PrefExcludedAppSpecifierBundleID)) != NULL
     190             && CFGetTypeID(excludedAppBundleID) == CFStringGetTypeID()
     191             && CFStringCompare(excludedAppBundleID, CFSTR("com.apple.projectbuilder"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) {
     192            if (LSFindApplicationForInfo(kLSUnknownCreator, excludedAppBundleID, NULL, NULL, &excludedAppURL) == noErr) {
     193                excludedAppBundle = CFBundleCreate(NULL, excludedAppURL);
     194                if (excludedAppBundle != NULL) {
     195                    APEToolsAddToExcludeList(kICBundleIdentifier, excludedAppBundle);
     196                } else postponeMigrationForApp = YES; // can't create bundle
     197            } else postponeMigrationForApp = YES; // can't find app
     198        }
     199        // don't release excludedAppSpecifiers, used Get
     200        // don't release excludedAppBundleID, used Get
     201        if (excludedAppURL != NULL) { CFRelease(excludedAppURL); excludedAppURL = NULL; }
     202        if (excludedAppBundle != NULL) { CFRelease(excludedAppBundle); excludedAppBundle = NULL; }
     203        if (!postponeMigrationForApp) CFArrayRemoveValueAtIndex(excludedApps, excludedAppIndex);
     204    }
     205
     206    ICapeprintf("Excluded apps remaining: %@\n", excludedApps);
     207    CFPreferencesSetAppValue(kIC12PrefExcluded, (CFArrayGetCount(excludedApps) == 0 ? NULL : excludedApps), kICBundleIdentifier);
     208    CFRelease(excludedApps);
     209
     210    CFPreferencesAppSynchronize(kICBundleIdentifier);
     211}
     212
     213static void ICCF_ReloadPrefs() {
     214    CFPreferencesAppSynchronize(kICBundleIdentifier);
     215
     216    ICCF_prefs.commandClickEnabled = ICCF_GetBooleanPref(kICCommandClickEnabled, YES);
     217    ICCF_prefs.textBlinkEnabled = ICCF_GetBooleanPref(kICTextBlinkEnabled, YES);
     218    ICCF_prefs.textBlinkCount = ICCF_GetCFIndexPref(kICTextBlinkCount, 3);
     219    ICCF_prefs.servicesInContextualMenu = ICCF_GetBooleanPref(kICServicesInContextualMenu, YES);
     220    ICCF_prefs.servicesInMenuBar = ICCF_GetBooleanPref(kICServicesInMenuBar, NO);
     221    ICCF_prefs.errorSoundEnabled = ICCF_GetBooleanPref(kICErrorSoundEnabled, NO);
     222    ICCF_prefs.errorDialogEnabled = ICCF_GetBooleanPref(kICErrorDialogEnabled, YES);
     223
     224    CFPreferencesAppSynchronize(kICBundleIdentifier);
     225
     226    ICCF_AddRemoveServicesMenu();
     227}
Note: See TracChangeset for help on using the changeset viewer.