Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
NotificationMon.ƒ/Source/NotificationMon.c
#include "NotificationMon.h" |
#include <GestaltTalk.h> |
#include "Event.h" |
short GetSleepTime() |
{ |
if(InBackGround) |
return MainView->prefs.backTime; |
else |
return MainView->prefs.foreTime; |
} |
Boolean IsNotificationDoc(WindowPeek wp) |
{ |
return (wp->windowKind == notifyKind); |
} |
void InitNotificationDoc(notificationDoc *nmd) |
{ |
Handle emptyMessage; |
GrafPtr savePort; |
FontInfo fi; |
nmd->ncount = 0; |
nmd->nHead = nil; |
nmd->nTail = nil; |
nmd->vScroll = nil; |
nmd->nSelection = 0; |
GetPort(&savePort); |
SetPort(&nmd->nWin); |
GetFontInfo(&fi); |
nmd->lineHt = fi.ascent + fi.descent + fi.leading; |
emptyMessage = GetResource('STR ',128); |
HLock(emptyMessage); |
nmd->longestLine = StringWidth(*emptyMessage) + RIGHT_MARGIN; |
HUnlock(emptyMessage); |
SetPort(savePort); |
} |
void RegisterNotificationMonitor() |
{ |
GestaltTalkPB gPB; |
OSErr err; |
ProcessSerialNumber psn; |
if(!MainView) return; |
err = GetCurrentProcess(&psn); |
if(err) { |
DebugStr("\pError in GetCurrentProcess"); |
} |
gPB.command = gregister; |
gPB.datalength = sizeof(ProcessSerialNumber); |
gPB.data = &psn; |
gPB.gtData = nil; |
err = GestaltTalk(&gPB); |
if(err) { |
DebugStr("\p GestaltTalk register failed."); |
} |
} |
void UnregisterNotificationMonitor() |
{ |
GestaltTalkPB gPB; |
OSErr err; |
if(!MainView) return; |
gPB.command = gunregister; |
gPB.datalength = 0; |
gPB.data = nil; |
gPB.gtData = nil; |
err = GestaltTalk(&gPB); |
if(err) { |
DebugStr("\p GestaltTalk UNregister failed."); |
} |
} |
notificationDoc *NewNotificationDoc(short wID) |
{ |
notificationDoc *nmd; |
nmd = NewPtr(sizeof(notificationDoc)); |
if(!nmd) { |
DebugStr("\pMemory Allocation Fail. in NewNotficationDoc"); |
} |
(void) GetNewWindow(wID,&nmd->nWin,(WindowPtr)-1); |
nmd->nWin.windowKind = notifyKind; |
InitNotificationDoc(nmd); |
InitNotificationPrefs(nmd); |
InitNotificationWindow(nmd); |
ShowWindow(&nmd->nWin); |
return nmd; |
} |
void AddNotification(Str255 notification, notificationDoc *nmd) |
{ |
Handle icon = nil, sound = nil, message = nil; |
short err = 0; |
Size msgLen = 0; |
nnH nCurs; |
GrafPtr savePort; |
short msgPixLen; |
Rect content; |
msgLen = notification[0] +1; |
message = NewHandle(msgLen); |
if(!message) { |
DebugStr("\pNewHandle fail in AddNotification[1]"); |
return; |
} |
BlockMove(notification, *message, msgLen); |
nCurs = NewHandle(sizeof(neoNotification)); |
if(!nCurs) { |
DebugStr("\pNewHandle fail in AddNotification[2]"); |
return; |
} |
(**nCurs).icon = icon; |
(**nCurs).sound = sound; |
(**nCurs).message = message; |
(**nCurs).next = nil; |
if(nmd->nHead == nil) { |
nmd->nHead = nmd->nTail = nCurs; |
} |
else { |
(**(nmd->nTail)).next = nCurs; |
nmd->nTail = nCurs; |
} |
nmd->ncount++; |
GetPort(&savePort); |
SetPort(&nmd->nWin); |
msgPixLen = StringWidth(notification) + RIGHT_MARGIN; |
if(msgPixLen > nmd->longestLine) |
nmd->longestLine = msgPixLen; |
UpdateScrollMax(nmd); |
NotificationCheckScrollVis(); |
content = nmd->nWin.port.portRect; |
content.right -= 16; |
InvalRect(&content); |
SetPort(savePort); |
} |
void KillNotifications(notificationDoc *nmd) |
{ |
nnH nCurs; |
GrafPtr savePort; |
if(!nmd->ncount) return; |
while(nmd->ncount--) { |
nCurs = nmd->nHead; |
if((**nCurs).icon) |
DisposHandle((**nCurs).icon); |
if((**nCurs).sound) |
DisposHandle((**nCurs).sound); |
if((**nCurs).message) |
DisposHandle((**nCurs).message); |
nmd->nHead = (**nCurs).next; |
DisposHandle(nCurs); |
} |
nmd->ncount = 0; |
nmd->nHead = nil; |
nmd->nTail = nil; |
GetPort(&savePort); |
SetPort(&nmd->nWin); |
InvalRect(&nmd->nWin.port.portRect); |
SetPort(savePort); |
} |
nnH GetNotificationEntryByNumber(notificationDoc *nmd, short num) |
{ |
short count; |
nnH target; |
if(num > nmd->ncount) return nmd->nTail; |
if(num < 1) return nmd->nHead; |
target = nmd->nHead; |
while(--num) { |
target = (**target).next; |
} |
return target; |
} |
void DrawNotification(nnH n) |
{ |
if(!n) { |
DebugStr("\p n was nil in DrawNotification"); |
return; |
} |
HLock((Handle)(**n).message); |
DrawString(*(**n).message); |
HUnlock((Handle)(**n).message); |
} |
void UpdateNotifications(notificationDoc *nmd, short first) |
{ |
nnH nCurs; |
short numToDraw; |
FontInfo fi; |
short i; |
GrafPtr savePort; |
Handle emptyMessage; |
Rect clip, selRect; |
GetPort(&savePort); |
SetPort(&nmd->nWin.port); |
clip = nmd->nWin.port.portRect; |
clip.right -= 16; |
ClipRect(&clip); |
EraseRect(&clip); |
if(!nmd->ncount) { |
MoveTo(4,nmd->lineHt); |
emptyMessage = GetResource('STR ',128); |
HLock(emptyMessage); |
DrawString(*emptyMessage); |
HUnlock(emptyMessage); |
return; |
} |
nCurs = GetNotificationEntryByNumber(nmd,first); |
for(i = 0; i <= nmd->ncount - first; i++) { |
if(nmd->nSelection && (i == nmd->nSelection) ) { |
selRect = nmd->nWin.port.portRect; |
selRect.right -= 16; |
selRect.bottom = selRect.top + nmd->lineHt; |
if(nmd->nSelection > 1) |
OffsetRect(&selRect, 0, nmd->lineHt * nmd->nSelection); |
FillRect(&selRect,black); |
MoveTo(4,(i+1)*nmd->lineHt); |
TextMode(srcXor); |
DrawNotification(nCurs); |
TextMode(srcOr); |
} else { |
MoveTo(4,(i+1)*nmd->lineHt); |
DrawNotification(nCurs); |
} |
nCurs = (**nCurs).next; |
if(!nCurs) break; |
} |
ClipRect(&nmd->nWin.port.portRect); |
SetPort(savePort); |
} |
void CheckNotifications() |
{ |
GestaltTalkPB gPB; |
OSErr err; |
Str255 message; |
if(!MainView) return; |
gPB.command = gstatus; |
gPB.datalength = 0; |
gPB.data = nil; |
gPB.gtData = nil; |
err = GestaltTalk(&gPB); |
if(err) { |
error("\p CheckNotification failed.",err); |
return; |
} |
if(!gPB.datalength) return; |
gPB.command = gread; |
/* using datalength returned from status call */ |
gPB.data = message; |
gPB.gtData = nil; |
err = GestaltTalk(&gPB); |
if(err) { |
error("\p CheckNotifications read error. ",err); |
} |
AddNotification(message, MainView); |
PostNotificationIcon(); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14