[comp.sys.mac.programmer] Parameterizable INITs

ech@poseidon.UUCP (Edward C Horvath) (09/07/88)

From article <6860023@vx2.NYU.EDU>, by spector@vx2.NYU.EDU (David HM Spector):
> As I recall from looking at an LSC version of ShowINIT (a klone of the
> MPW object written by Apple's Paul Mercer) which shows the icons of INITs
> at System startup time, you need to have your own QD globals set up, because
> at INIT31 time the universe is not fully formed yet, and as such QuickDraw
> and things that rely upon it are most likely bound to do bad things.

I don't remember which TechNote addresses this issue, but there is one
(somewhere in the 70-100 range, I think, check the TN index).  I do recall
that QuickDraw HAS been set up, but not the Window Manager.  The
"Welcome to Macintosh" pseudo-window is actually drawn by the System Error
package -- see IM-2.  When an INIT blows away that fake window, it just
called InitWindows.  INITs essentially have a partially-initialized
application going for them: there IS an application heap, and so things
like the Resource Manager and Memory Manager are available.

But if you really need an INIT that is "parameterizable," consider doing
a cdev instead, with default behavior set to be innocuous.  That way,
the user can install your goody by just dropping it into the System
Folder, configure it now or later with the Control Panel, then reboot to
get the full effect.

On that same subject, there was discussion recently of installing a DRVR
at INIT time that the cdev could later communicate with.  That gives me
a problem: there is VERY limited space in the unit table -- i.e. there
aren't that many DRVR slots -- and they ALL appear to be "pre-allocated"
by Apple.  So which ones do you use?  What do you do if your favorite
slot is occupied?

I'm considering a different approach: let the INIT add a task to the VBL
queue, with a long timeout, and leave the cdev's name in a prominent
place in the header of the VBL task.  This requires the cdev to scan the
VBL queue intead of just doing an _Open, but has the same desired effect.

Granted, VBL tasks don't have the same "stature" as a DRVR -- the MacOS
doesn't maintain a DCE or feed you accRun (or other useful) events --
but for many purposes those may not be required.  Is there some reason
this won't work?  Other comments?

=Ned Horvath=

spector@vx2.NYU.EDU (David HM Spector) (09/14/88)

Sure... here it is.  This comes off of CompuServe.
I don't remember who the author is, it wasn't in the file on
compuserve...

/* -------------------  ShowInit.c   ----------------------------*/
/*
	Simple INIT notification routine in LightSpeedC 2.15
*/

#include <QuickDraw.h>

#define CKSM(i)				\
	asm {					\
		ROL #1,i			\
		EOR #0x1021,i		\
	}

typedef struct QuickDraw {		/* QuickDraw globals */
	char private[76];
	long randSeed;
	BitMap screenBits;
	Cursor arrow;
	Pattern dkGray;
	Pattern ltGray;
	Pattern gray;
	Pattern black;
	Pattern white;
	GrafPtr thePort;
} QuickDraw;

extern short myH : 0x92C;		/* CurApName + 28 */
extern short myCheck: 0x92E;	/* CurApName + 30 */
extern long oldSig: 0xA78;		/* ApplScratch */
extern short oldH: 0xA7E;		/* ApplScratch + 6 */

void ShowINIT(iconID)
register short iconID;			/* ICN# resource ID */
{
	register Handle h;
	register short i;
	Rect srcRect, destRect;
	BitMap myBitMap;
	GrafPort myPort;
	QuickDraw qdGlobals;
	Ptr localA5;

	asm {
		MOVE.L A5,-(SP)
		LEA.L localA5,A5
	}
	if (!(h = GetResource('ICN#', iconID)))
		goto out;	/* Error */
	InitGraf(&qdGlobals.thePort);
	OpenPort(&myPort);

	i = myH;
	CKSM(i);
	if (i == myCheck)
		i = myH;
	else
		if (oldSig == 'Paul')
			i = oldH;
		else
			i = 8;
	destRect.bottom = myPort.portRect.bottom - 8;
	destRect.left = myPort.portRect.left + i;
	destRect.top = destRect.bottom - 32;
	destRect.right = destRect.left + 32;
	i += 40;
	myH = i;
	CKSM(i);
	myCheck = i;

	HLock(h);
	srcRect.top = srcRect.left = 0;
	srcRect.bottom = srcRect.right = 32;
	myBitMap.rowBytes = 4;
	myBitMap.bounds = srcRect;
	myBitMap.baseAddr = *h + 128;	/* Skip to mask */
	CopyBits(&myBitMap, &myPort.portBits, &srcRect, &destRect, srcBic, 0L);
	myBitMap.baseAddr = *h;			/* Now draw icon */
	CopyBits(&myBitMap, &myPort.portBits, &srcRect, &destRect, srcOr, 0L);
	HUnlock(h);
	ReleaseResource(h);

	ClosePort(&myPort);
out:
	asm {
		MOVE.L (SP)+,A5
	}
}
/*  end of ShowInit.c */
-------------------------------------------------------------------------------
David HM Spector				   New York University
Senior Systems Programmer			   Graduate School of Business
ARPAnet: SPECTOR@GBA.NYU.EDU			   Academic Computing Center
USEnet:...!{allegra,rocky,harvard}!cmcl2!spector   90 Trinity Place, Rm C-4
HamRadio: N2BCA      MCIMail: DSpector             New York, New York 10006
AppleLink: D1161     CompuServe: 71260,1410        (212) 285-6080
"What computer puts out work like this?"          "Hire us and we'll tell you."

bob@eecs.nwu.edu (Bob Hablutzel) (09/14/88)

> Looking at INIT31 reveals that InitGraf has already been called.
> However, some Inits do it themselves and leave A5 pointing to anything at all
> afterwards, so it's bad to call InitGraf (using your own port) and it may
> create problems not to... Anyone have a good procedure to check if InitGraf
> has been called? (Like comparing Arrow to a resource which contains a cloned
> version of the standard cursor?)

It doesn't really matter what INITs leave A5 pointing to, as INIT 31 saves
and restores ALL registers (except A7, of course) as part of calling
the INIT. Go ahead and call initGraf if you need to - just set up
your A5 world first.

> As an aside, Init31 also checks if the Cached bit is set and skips the
> INIT/RDEV/cdev file if it is. Anyone have a newer version of AAsk (or a patch
> which looks at that bit instead of changing the file type to "xNIT" and
> similar nonsense :-( ?

Don't know about Ask, but I am working in a project which does all that
and much, much more. More facts when they are available (but it will
be ready VERY SOON).

Bob Hablutzel	BOB@NUACC.ACNS.NWU.EDU

msurlich@faui44.informatik.uni-erlangen.de ( scheme) (10/03/88)

In article <10050016@eecs.nwu.edu> bob@eecs.nwu.edu (Bob Hablutzel) writes:
In sone other article I wrote:
> > Looking at INIT31 reveals that InitGraf has already been called.
> > However, some Inits do it themselves and leave A5 pointing to anything at all
> > afterwards, so it's bad to call InitGraf (using your own port) and it may
> > create problems not to... Anyone have a good procedure to check if InitGraf
> > has been called? (Like comparing Arrow to a resource which contains a cloned
> > version of the standard cursor?)
> 
> It doesn't really matter what INITs leave A5 pointing to, as INIT 31 saves
> and restores ALL registers (except A7, of course) as part of calling
> the INIT. Go ahead and call initGraf if you need to - just set up
> your A5 world first.

Oops... should have looked more carefully. And well, because InitGraf already
has been called for me, I won't call it again.

And yes, I still need a good general procedure to tell me if The ROM has been
initialized. Nosy mentions some low memory globals like WWExist(s)(?)
(telling me if the Window Manager has been initialized). The version
of Smart Alarms I checked looks at the center of the top row of the menu bar
to see if it's white (sorry, I Kolor'ed my menu bar and so I can't use
Smart Alarms :-( )...
Any word from Apple?

> > As an aside, Init31 also checks if the Cached bit is set and skips the
> > INIT/RDEV/cdev file if it is. Anyone have a newer version of AAsk (or a patch
> > which looks at that bit instead of changing the file type to "xNIT" and
> > similar nonsense :-( ?
> 
> Don't know about Ask, but I am working in a project which does all that
> and much, much more. More facts when they are available (but it will
> be ready VERY SOON).
> 
Exactly what I need (Aask is too slow for me, anyway, because by now it
displays about five and a half rows of INITs on my Mac II and the Disk Cach
is INIT 35 and gets installed after all other INITs ...)
How will I (or anybody else, for that matter) be able to get it?

steve@ivucsb.UUCP (Steve Lemke <steve>) (10/08/88)

In article <646@faui10.informatik.uni-erlangen.de> m_urlichs@msn.rmi.de writes:
>Exactly what I need (Aask is too slow for me, anyway, because by now it
>displays about five and a half rows of INITs on my Mac II and the Disk Cach
>is INIT 35 and gets installed after all other INITs ...)

Geez, five and a half rows?  And I thought my two rows were a lot...  How much
memory do you have in that machine?  5 or 8mb?  What kinds of things are you
running for inits?  I've found that even with two rows, it can be a real pain
to get everything working properly (right order, compatibilities, etc.).  Even
still, when the machine crashes periodically I never really know what to blame
it on.  How did you get five rows to all work together?

 
----- Steve Lemke ------------------- "MS-DOS (OS/2, etc.) - just say no!"
----- Internet: steve@ivucsb.UUCP; lemke@apple.COM   AppleLink:  LEMKE
----- uucp:     pyramid!comdesign!ivucsb!steve       CompuServe: 73627,570
----- alt.uucp: {decwrl!}sun!apple!lemke             GEnie:      S.Lemke
----- Quote:    "What'd I go to college for?"   "You had fun, didn't you?"