]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOS9/ShowInitIcon.c
mDNSResponder-258.13.tar.gz
[apple/mdnsresponder.git] / mDNSMacOS9 / ShowInitIcon.c
1 // ShowInitIcon - version 1.0.1, May 30th, 1995
2 // This code is intended to let INIT writers easily display an icon at startup time.
3 // View in Geneva 9pt, 4-space tabs
4
5 // Written by: Peter N Lewis <peter@mail.peter.com.au>, Jim Walker <JWWalker@aol.com>
6 // and François Pottier <pottier@dmi.ens.fr>, with thanks to previous ShowINIT authors.
7 // Send comments and bug reports to François Pottier.
8
9 // This version features:
10 // - Short and readable code.
11 // - Correctly wraps around when more than one row of icons has been displayed.
12 // - works with System 6
13 // - Built with Universal Headers & CodeWarrior. Should work with other headers/compilers.
14
15 #include <Memory.h>
16 #include <Resources.h>
17 #include <Icons.h>
18 #include <OSUtils.h>
19 #include "ShowInitIcon.h"
20
21 // You should set SystemSixOrLater in your headers to avoid including glue for SysEnvirons.
22
23 // ---------------------------------------------------------------------------------------------------------------------
24 // Set this flag to 1 if you want to compile this file into a stand-alone resource (see note below).
25 // Set it to 0 if you want to include this source file into your INIT project.
26
27 #if 0
28 #define ShowInitIcon main
29 #endif
30
31 // ---------------------------------------------------------------------------------------------------------------------
32 // The ShowINIT mechanism works by having each INIT read/write data from these globals.
33 // The MPW C compiler doesn't accept variables declared at an absolute address, so I use these macros instead.
34 // Only one macro is defined per variable; there is no need to define a Set and a Get accessor like in <LowMem.h>.
35
36 #define LMVCheckSum (* (unsigned short*) 0x928)
37 #define LMVCoord (* ( short*) 0x92A)
38 #define LMHCoord (* ( short*) 0x92C)
39 #define LMHCheckSum (* (unsigned short*) 0x92E)
40
41 // ---------------------------------------------------------------------------------------------------------------------
42 // Prototypes for the subroutines. The main routine comes first; this is necessary to make THINK C's "Custom Header" option work.
43
44 static unsigned short CheckSum (short x);
45 static void ComputeIconRect (Rect* iconRect, Rect* screenBounds);
46 static void AdvanceIconPosition (Rect* iconRect);
47 static void DrawBWIcon (short iconID, Rect *iconRect);
48
49 // ---------------------------------------------------------------------------------------------------------------------
50 // Main routine.
51
52 typedef struct {
53 QDGlobals qd; // Storage for the QuickDraw globals
54 long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
55 } QDStorage;
56
57 pascal void ShowInitIcon (short iconFamilyID, Boolean advance)
58 {
59 long oldA5; // Original value of register A5
60 QDStorage qds; // Fake QD globals
61 CGrafPort colorPort;
62 GrafPort bwPort;
63 Rect destRect;
64 SysEnvRec environment; // Machine configuration.
65
66 oldA5 = SetA5((long) &qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
67 InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
68
69 SysEnvirons(curSysEnvVers, &environment); // Find out what kind of machine this is
70
71 ComputeIconRect(&destRect, &qds.qd.screenBits.bounds); // Compute where the icon should be drawn
72
73 if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
74 OpenCPort(&colorPort);
75 PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
76 CloseCPort(&colorPort);
77 }
78 else {
79 OpenPort(&bwPort);
80 DrawBWIcon(iconFamilyID, &destRect);
81 ClosePort(&bwPort);
82 }
83
84 if (advance)
85 AdvanceIconPosition (&destRect);
86
87 SetA5(oldA5); // Restore A5 to its previous value
88 }
89
90 // ---------------------------------------------------------------------------------------------------------------------
91 // A checksum is used to make sure that the data in there was left by another ShowINIT-aware INIT.
92
93 static unsigned short CheckSum (short x)
94 {
95 return (unsigned short)(((x << 1) | (x >> 15)) ^ 0x1021);
96 }
97
98 // ---------------------------------------------------------------------------------------------------------------------
99 // ComputeIconRect computes where the icon should be displayed.
100
101 static void ComputeIconRect (Rect* iconRect, Rect* screenBounds)
102 {
103 if (CheckSum(LMHCoord) != LMHCheckSum) // If we are first, we need to initialize the shared data.
104 LMHCoord = 8;
105 if (CheckSum(LMVCoord) != LMVCheckSum)
106 LMVCoord = (short)(screenBounds->bottom - 40);
107
108 if (LMHCoord + 34 > screenBounds->right) { // Check whether we must wrap
109 iconRect->left = 8;
110 iconRect->top = (short)(LMVCoord - 40);
111 }
112 else {
113 iconRect->left = LMHCoord;
114 iconRect->top = LMVCoord;
115 }
116 iconRect->right = (short)(iconRect->left + 32);
117 iconRect->bottom = (short)(iconRect->top + 32);
118 }
119
120 // AdvanceIconPosition updates the shared global variables so that the next extension will draw its icon beside ours.
121
122 static void AdvanceIconPosition (Rect* iconRect)
123 {
124 LMHCoord = (short)(iconRect->left + 40); // Update the shared data
125 LMVCoord = iconRect->top;
126 LMHCheckSum = CheckSum(LMHCoord);
127 LMVCheckSum = CheckSum(LMVCoord);
128 }
129
130 // DrawBWIcon draws the 'ICN#' member of the icon family. It works under System 6.
131
132 static void DrawBWIcon (short iconID, Rect *iconRect)
133 {
134 Handle icon;
135 BitMap source, destination;
136 GrafPtr port;
137
138 icon = Get1Resource('ICN#', iconID);
139 if (icon != NULL) {
140 HLock(icon);
141 // Prepare the source and destination bitmaps.
142 source.baseAddr = *icon + 128; // Mask address.
143 source.rowBytes = 4;
144 SetRect(&source.bounds, 0, 0, 32, 32);
145 GetPort(&port);
146 destination = port->portBits;
147 // Transfer the mask.
148 CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
149 // Then the icon.
150 source.baseAddr = *icon;
151 CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
152 }
153 }
154
155 // ---------------------------------------------------------------------------------------------------------------------
156 // Notes
157
158 // Checking for PlotIconID:
159 // We (PNL) now check for system 7 and colour QD, and use colour graf ports and PlotIconID only if both are true
160 // Otherwise we use B&W grafport and draw using PlotBWIcon.