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.
NotificationTrash.ƒ/ShowInitIcon.c
/* |
ShowInitIcon.c : Shows the icon during the init loading time |
*/ |
/* |
Note: This code is roughly based on an assembly language routine by |
Paul Mercer, Darin Adler, and Paul Snively from an idea by Steve Capps. |
We use this method to be compatible with other Mac INITs. |
It was converted to Think C by Eric Shapiro. |
10/6/91 ebs Added HNoPurge call just to be extra safe. |
4/26/91 ebs Added wrap-to-next-line support from James W. Walker |
3/29/91 ebs Changed function name, added CIconHandle typecasts |
12/12/89 ebs Called ClosePort() to release port memory |
*/ |
/* The low memory CurApName is a convenient place to store |
four bytes of information so the next INIT doesn't |
overwrite our ICON. We store into my_h the horizontal |
pixel location where the next INIT should go. We checksum |
the value and store the checksum in the next two bytes, |
so that INITs can determine whether they're the 1st one loaded. |
*/ |
#define CurApName 0x910 |
extern short my_h : CurApName+32-4; |
extern short my_check : CurApName+32-2; |
#ifndef NULL |
#define NULL ( (void *)0 ) |
#endif |
#define ICON_HEIGHT 32 |
#define ICON_WIDTH 32 |
#define FIRST_X 8 /* don't change this */ |
#define BOTTOM_MARGIN 8 |
#define DEF_MOVE_X_BY 40 |
#define CHECKSUM_CONST 0x1021 |
#define MIN_BIT_DEPTH 4 /* if 16 colors or more, use color icon */ |
/* |
ShowInitIcon: Shows the icon specified in the correct place during startup |
NOTE: |
If Color QDraw is present and the main device has at least MIN_BIT_DEPTH |
set, we'll look for a color icon ('cicn' resource) first. If we can't |
find one, we'll look for the 'ICN#' resource. |
Passed: |
short icon_num; 'ICN#' or 'cicn' resource id |
short move_x_by; Pass -1 for default |
Returns: |
int 0=No error, <0=Error number |
*/ |
OSErr ShowInitIcon( short icon_num, short move_x_by) |
{ |
short err; |
Handle icon_h=NULL; /* handle to 'ICN#' or 'cicn' resource */ |
Boolean in_color=FALSE; /* TRUE='cicn' resource, else 'ICN#' */ |
GrafPtr oldport; |
GrafPort newport; /* Entire GrafPort structure */ |
Rect r; /* where to put the icon */ |
SysEnvRec sys_rec; |
short screen_width; |
/* check for color quickdraw. If present, check bit depth of mainscreen. |
if >= MIN_BIT_DEPTH, then try to use color icon. |
*/ |
if ( err = SysEnvirons(1, &sys_rec) ) |
return(err); |
if ( sys_rec.hasColorQD ) /* a Mac II or later... */ |
{ |
GDHandle gdev = GetGDevice(); /* get main screen */ |
if ( (*(*gdev)->gdPMap)->pixelSize >= MIN_BIT_DEPTH ) |
icon_h = (Handle)GetCIcon(icon_num); |
if ( icon_h != NULL ) |
in_color = TRUE; |
} |
if ( icon_h == NULL ) /* no icon yet, try a B&W one */ |
icon_h = Get1Resource('ICN#', icon_num); |
if ( icon_h == NULL ) |
return(resNotFound); /* we're SOL here */ |
HNoPurge( icon_h ); |
GetPort(&oldport); /* save old GrafPort for later restoring */ |
/* open a port so we can draw directly to screen. WindowMgrPort |
may not be initialized at this time. |
*/ |
OpenPort(&newport); |
SetPort(&newport); |
/* do a checksum on low memory to see if we're the 1st icon */ |
/* if we are, then set x location. ^=XOR. */ |
if ( ((my_h <<1) ^ CHECKSUM_CONST) != my_check ) |
my_h = FIRST_X; |
#ifdef OLD_VERSION |
/* now plot the icon */ |
r = newport.portRect; |
r.top = newport.portRect.bottom - (BOTTOM_MARGIN+ICON_HEIGHT); |
r.bottom = newport.portRect.bottom - BOTTOM_MARGIN; |
r.left = my_h; |
r.right = r.left + ICON_WIDTH; |
#endif |
/* now plot the icon 4/26/91 updated */ |
screen_width = newport.portRect.right - newport.portRect.left; |
screen_width -= screen_width % DEF_MOVE_X_BY; /* in case screen isn't multiple of 40 */ |
r.left = my_h % screen_width; |
r.right = r.left + ICON_WIDTH; |
r.top = newport.portRect.bottom - ((BOTTOM_MARGIN+ICON_HEIGHT) * (1 + my_h / screen_width)); |
r.bottom = r.top + ICON_HEIGHT; |
if ( in_color ) |
PlotCIcon(&r, (CIconHandle)icon_h); /* Toolbox's plot routine */ |
else |
plot_icn(&r, icon_h); /* our routine */ |
/* now offset the low memory location by move_x_by pixels */ |
if ( move_x_by == -1 ) |
move_x_by = DEF_MOVE_X_BY; |
my_h += move_x_by; |
my_check = (my_h<<1) ^ CHECKSUM_CONST; |
/* release the icon, restore the port */ |
if ( in_color ) |
DisposCIcon((CIconHandle)icon_h); |
else |
ReleaseResource(icon_h); |
SetPort(oldport); |
ClosePort(&newport); /* ebs 12/12/89 */ |
return(0); |
} |
/* |
plot_icn : Plots an ICN# (ICON+mask) just the the Finder. |
*/ |
plot_icn(r, icn_handle) |
Rect *r; |
Handle icn_handle; |
{ |
BitMap bm; |
char flags; |
GrafPtr cur_port; |
flags = HGetState(icn_handle); |
HLock(icn_handle); |
GetPort(&cur_port); |
/* we have to set up a BitMap structure to pass to CopyBits. We |
might be able to use CopyMask() call instead, but this should |
work on all Macs and CopyMask is only Mac+ or later. The 1st |
BitMap we use has baseAddr pointing 128 bytes into the ICN#, |
at the 1st bit of the mask. The 2nd BitMap points to the ICON. |
*/ |
bm.baseAddr = *icn_handle + ICON_WIDTH*ICON_HEIGHT/8; /* points to mask */ |
bm.rowBytes = ICON_WIDTH / 8; /* ICON_WIDTH/8 must be power of 2 */ |
SetRect(&bm.bounds, 0, 0, ICON_WIDTH, ICON_HEIGHT); |
/* punch a hole in the Desktop using bit-clear mode and the mask */ |
CopyBits(&bm, &cur_port->portBits, &bm.bounds, r, srcBic, NULL); |
/* now copy the icon into the punched hole */ |
bm.baseAddr = *icn_handle; /* points to ICON */ |
CopyBits(&bm, &cur_port->portBits, &bm.bounds, r, srcOr, NULL); |
HSetState(icn_handle, flags); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14