home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
telex1.sit
/
Telexƒ
/
Init.c
next >
Wrap
C/C++ Source or Header
|
1991-05-10
|
9KB
|
206 lines
/* ====================================== *\
** == AppleTalk Teletype == **
** == Installation code == **
** == (INIT) == **
** == Copyright ⌐ Gamma Software, 1990 == **
** == Think C version == **
\* ====================================== */
#include "TelexDef"
typedef unsigned long unlong;
static GrafPtr GetGlobal(void);
#define sysMemTop MemTop /* Low-memory addresses to install */
#define sysBufPtr BufPtr /* the code in RAM */
#define FictName "\pHacker" /* implicit (if Chooser name is abs)*/
#define ServerType "\pTelex"
#define ResidCode 'TELX' /* Resource type of Listener code */
#define KeyMask 0x0000810D /* Tab, Cmd, Control,Option, Shift */
typedef void (*Starter)(Storage*); /* starter procedure in the Listener*/
static int InstallIt(void); /* installation routine */
static void DrawIcon(short); /* draw icon on startup screen */
/*
* Installer code
*/
void main() {
short refNum;
KeyMap theKeys;
asm { /* load A4 for global access */
MOVE.L A0,A4 /* (see Think C manual for */
} /* code resources) */
GetKeys(&theKeys); /* read keyboard state */
DrawIcon(!Button() && /* the mouse button isn't pressed */
!(theKeys.Key[1] & KeyMask) && /* none of "spec-keys" is pressed */
OpenDriver("\p.MPP",&refNum) == noErr && /* AppleTalk opened */
InstallIt() ? /* and installation was successful */
OKiconID : BadIconID); /* if OllKorrect, draw OK, else Bad*/
}
/*
* This procedure:
* 1. installs the Listener code in the TopMem;
* 2. reserves storage for Listener buffers (messages, etc);
* 3. starts the Listener.
* If any step fails, the procedure returns FASE, otherwise - TRUE
*/
static int InstallIt() {
Storage* theData;
Handle theCode= GetResource(ResidCode,1);/* Read Listener code form the file*/
short i;
long codeSize;
char* codeAddr;
if(theCode == NIL) return(false); /* the Listener code not found... */
codeSize = GetHandleSize(theCode); /* calculate the code size */
/* Get memory for code & data (moving BufPtr) */
{ /* see IM v.IV to understand this */
if((unlong)sysBufPtr - sizeof(Storage) - codeSize <
((unlong)sysMemTop >> 1) + 1024) return(false);
theData = (Storage*) (sysBufPtr -= sizeof(Storage));
codeAddr = (char*) (sysBufPtr -= codeSize);
}
BlockMove(*theCode,codeAddr,(short)codeSize);
/* Initiate message records */
for(i=0; i<Nnotes; ++i) { /* for all elements: */
NoteBuf* ptr = theData->NoteBlocks+i;
ptr->q.qLink = NIL; /* initiate Notification Manager */
ptr->q.qType = nmType; /* records: Queue, marks, etc */
ptr->q.nmMark = 0;
ptr->q.nmSIcon = 0;
ptr->q.nmSound = (Handle) -1; /* to produce SysBeep on output */
ptr->q.nmStr = ptr->mess;
ptr->q.nmRefCon = 0l;
ptr->busy = FALSE; /* this element is free (no msg) */
}
/* Now we look for the header string and fill the header buffer*/
{
Handle theHeader;
if((theHeader = (Handle) GetString(HeaderSTRID)) != NIL) {
int i; /* Yes, we've found the STR rsrc */
for(i=1; i<= **theHeader && i<sizeof(theData->MessHeader); ++i) {
theData->MessHeader[i] = (*theHeader)[i];
}
*theData->MessHeader = (unsigned char) (i-1);
} else { /* No, the header isn't found -> */
*theData->MessHeader = 0; /* set an empty header (leng = 0) */
}
}
/* Install our Named Socket in the AppleTalk network */
{
AddrBlock ForAll = {0,0,0}; /* Glad to hear from everybody */
theData->ReqSocket = 0; /* automatically assigned socket */
if(ATPOpenSocket(ForAll,&theData->ReqSocket) != noErr) return(FALSE);
}
/* Assign the name to the socket: type = Telex, Name = from Chooser (is any)*/
{
MPPParamBlock regRecord;
short nodeid;
StringHandle HomeName;
unchar* pname = NIL;
char* pident = theData->NbpEntry.entityData;
int length;
/* form the NBP table entry */
GetNodeAddress(&nodeid,&theData->NbpEntry.nteAddress.aNet);
theData->NbpEntry.nteAddress.aNode = (unchar) nodeid;
theData->NbpEntry.nteAddress.aSocket = theData->ReqSocket;
theData->NbpEntry.qNext = NIL;
/* Set Server (Listener) Name */
if((HomeName=GetString(HomeID)) != NIL){ /* we've found the "Chooser" name */
pname= *HomeName; /* -> we'll use it */
} else { /* if your computer has no Chooser:*/
pname = (unchar*)FictName; /* YOU ARE A HACKER! (Shame on you)*/
}
if((length = *(unsigned char*)pname++)>=32) length = 32; /* AppleTalk limit */
*pident++ = (char)length; /* put the Name into the NBP elem. */
while(--length>=0) *pident++ = *pname++;
pname = (unchar*)ServerType; /* put the Type into the NBP elem. */
*pident++ = length = *pname++;
while(--length>=0) *pident++ = *pname++;
*pident++ = 1; *pident++ = '*'; /* put the Zone into the NBP elem. */
regRecord.MPPcsCode = tNBPRegister; /* Now fill all fields for the call*/
regRecord.NBPinterval = RegTimeOut;
regRecord.NBPcount = Nrepeat;
regRecord.NBPverifyFlag = 1;
regRecord.NBPntQElPtr = (Ptr)&theData->NbpEntry;
if(PRegisterName(®Record,FALSE) != 0){/* Registration failed -> */
ATPCloseSocket(theData->ReqSocket); /* close our socket */
return(FALSE);
}
}
theData->RespBlock.ATPioResult = 2; /* this value is used in Listener */
(*(Starter)codeAddr)(theData); /* Call the Listener to start it */
return(TRUE); /* Everything is done -> return OK */
}
/*
* Get QuickDraw Globals address
*/
static GrafPtr GetGlobal() { /* This procedure returns the */
asm { /* address of our Globals (A5) - */
MOVE.L A5,D0 /* sizeof(Ptr) */
SUBQ #4,D0 /* i.e. it's equiv. &thePort in an */
} /* application */
}
/*
* Draw an Icon on the StartUp Screen
*/
void DrawIcon(short code) {
short* pShift = (short*) 0x92C; /* this magic addresses are used */
short* pCheck = (short*) 0x92E; /* to draw an array of Icons. */
short Mask = 0x1021; /* 5th Generation's method, I think*/
GrafPort thePort;
Rect where;
Handle theIcon= GetResource('ICN#',code);/* read the Icon to draw */
BitMap theMap = {NIL,4,{0,0,32,32}}; /* the BitMap for theIcon */
InitGraf(GetGlobal()); /* We InitGraf(A5) */
OpenPort(&thePort); /* open thePort (main screen) */
where.left = 8; /* magic calculations to find the */
where.top = thePort.portRect.bottom-40; /* Icon Array's tail (Am I right?) */
if(((*pShift<<1) ^ Mask) == *pCheck) where.left = *pShift;
where.bottom = where.top + 32; /* Our Icon is a 32x32 bitmap */
where.right = where.left + 32;
HLock(theIcon); /* Lock the ICN# resource */
theMap.baseAddr = *theIcon+128; /* build a BitMap for the Icon Mask*/
CopyBits(&theMap,&thePort.portBits, /* and punch a hole in the desktop */
&theMap.bounds,&where,srcBic,NIL);/* with this BitMap */
theMap.baseAddr = *theIcon; /* build a BitMap for the Icon Body*/
CopyBits(&theMap,&thePort.portBits, /* and draw it in the punched hole */
&theMap.bounds,&where,srcOr ,NIL);
ClosePort(&thePort); /* All done -> close thePort */
*pShift = where.left += 40; /* correct magic values of the */
*pCheck = (where.left<<1) ^ Mask; /* Icon Array */
}