PoliteNotification.ƒ/NMInstallPatch.c

#ifndef THINK_C
    #include <GestaltEQU.h>
    #include <OSUtils.h>
    #include <Notification.h>
    #include <Resources.h>
#endif
 
    #include <Traps.h>
    #include <gestaltEQU.h>
    #include <Processes.h>
    #include "GestaltTalk.h"    
    
pascal void DeNotification();
OSErr ShowInitIcon( short icon_num, short move_x_by);
long  *GetStashSpotAddr();
OSErr InstallGestaltTalk();
 
pascal OSErr GetIconSuite(Handle *iconSuite, short resID, short sel) =
{0x303c, 0x0501, 0xabc9};
 
pascal OSErr NewIconSuite(Handle *iconSuite) = {0x303c, 0x0207, 0xabc9};
 
pascal OSErr AddIconToSuite(Handle *data, Handle suite, long restype) =
{0x303c, 0x0609, 0xabc9};
 
Handle SetUpIcons()
{
    Handle  icon[6];
    Handle  suite;
    
 
    suite = GetResource('SICN',129);
    DetachResource(suite);
    return suite;
 
 
 
 
 
/*
    Something bad is happening here and I don't want to find it.
    If you fix this so it works, send me an AppleLink at BRIGHAM.
    It was supposed to load in an icon family to be used for notifications that
    do not use an icon.
*/
 
#if 0
    icon[0] = Get1Resource('icl8',129);
    DetachResource(icon);
 
    icon[1] = Get1Resource('icl4',129);
    DetachResource(icon);
 
    icon[2] = Get1Resource('ics8',129);
    DetachResource(icon);
 
    icon[3] = Get1Resource('ics4',129);
    DetachResource(icon);
 
    icon[4] = Get1Resource('ICN#',129);
    DetachResource(icon);
 
    icon[5] = Get1Resource('ics#',129);
    DetachResource(icon);
    
    SetZone(SystemZone());
    NewIconSuite(&suite);
    SetZone(ApplicZone());
    
    AddIconToSuite(icon[0],suite,'icl8');
    AddIconToSuite(icon[1],suite,'icl4');
    AddIconToSuite(icon[2],suite,'ics8');
    AddIconToSuite(icon[3],suite,'ics4');
    AddIconToSuite(icon[4],suite,'ICN#');
    AddIconToSuite(icon[5],suite,'ics#');
 
    return suite;
    
#endif
}
 
pascal void main()
{
    Handle  initCodeHandle;
    long    *localRealAddr;
    short   err;
    long    sysVersion;
    
    
    /* don't load unless we are on 7.0 or later */
    err = Gestalt(gestaltSystemVersion,&sysVersion);
    if(sysVersion < 0x0700) return;
    
    
    if (err = InstallGestaltTalk()) {
        DebugStr("\p InstallGestaltTalk Failed.");
        return;
    }
    
    initCodeHandle = GetResource('INIT',0);
    DetachResource(initCodeHandle);
 
    localRealAddr = GetStashSpotAddr();
    
    *localRealAddr = GetOSTrapAddress( (short)0xA05E );
    SetOSTrapAddress((long)DeNotification, (short)0xA05E);
 
    localRealAddr++;    
    localRealAddr = SetUpIcons();
 
    (void) ShowInitIcon( 128, -1);
}
 
OSErr InstallGestaltTalk()
{
    OSErr           err;
    GestaltTalkPB   initPB;
    
    
    err = NewGestalt(gestaltTalkSelector,(ProcPtr)GestaltTalkGestalt);
    if(err) {
        DebugStr("\p InstallGestaltTalk - NewGestalt failed.");
        goto bail;
    }
 
    initPB.command = ginit;
    initPB.datalength = 0;
    initPB.data = nil;
    initPB.gtData = nil;
    
    err =  GestaltTalk(&initPB);    
    if(err) {
        DebugStr("\p InstallGestaltTalk - GestaltTalk ginit failed.");
        goto bail;
    }
 
bail:       
    return err;
}
 
short pstrlen(Str255 str)
{
    return str[0];
}
 
 
void KillNotificationDialog(NMRecPtr notification)
{
    long                *stashAddr;
    GestaltTalkPB       writePB,getappPB;
    short               err;
    ProcessSerialNumber curPSN;
    ProcessInfoRec      info;
    Str255              message;
    short               divider = 0x01CA;
    long                *iconSuite;
    
    if(notification->nmStr)
    {
        
        if(!notification->nmIcon) {
            /* add an icon to notification's that do not use one */
            iconSuite = (Handle)GetStashSpotAddr();
            iconSuite++;
            notification->nmIcon = iconSuite;
        }
 
        writePB.command = gwrite;
        writePB.datalength = pstrlen(notification->nmStr) + 1;
        writePB.data = notification->nmStr;
        writePB.gtData = nil;
        
        err =  GestaltTalk(&writePB);
 
        /* Do the dirty deed... kill the notification dialog */
        notification->nmStr = nil;      
        
        /* give the monitor that is registered some time */
        getappPB.command = ggetapp;
        getappPB.datalength = 0;
        getappPB.data = nil;
        getappPB.gtData = nil;
        
        err =  GestaltTalk(&getappPB);
 
        if( !err  ) {
            err = WakeUpProcess(getappPB.data);
        }
    }
}
 
pascal void DeNotification()
{
    
    asm {
            move.l  d0,-(sp)                        // save some regs we use            
            
            move.l  a0,-(sp)                        // NMRecPtr on stack
            jsr     KillNotificationDialog          // kill the dialog
            addq.l  #4,sp                           // fix the stack
            
@callOriginal
            jsr     GetStashSpotAddr                // get pointer to real NMinstall address
 
            movea.l d0,a1                           // get pointer to storage
            move.l  (a1),a1                         // save addr of NMInstall           
            move.l  (sp)+,d0                        // restore regs used            
            jmp     (a1)                            // 
                                                    // 
    }
}
 
/* this gives us storage, but why didn't I use THINKs a4 crap? */
long *GetStashSpotAddr()
{
    asm {
            bsr.s @skipStorage
            dc.l    0x00            // pointer to real NMINstall
            dc.l    0x00            // 
        @skipStorage:
            move.l  (sp)+,d0
    }
}