home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / telex1.sit / Telexƒ / Init.c next >
C/C++ Source or Header  |  1991-05-10  |  9KB  |  206 lines

  1.                             /* ====================================== *\
  2.                             ** ==         AppleTalk  Teletype      == **
  3.                             ** ==          Installation code       == **
  4.                             ** ==               (INIT)             == **
  5.               ** == Copyright ⌐ Gamma Software, 1990 == **
  6.               ** ==           Think C version        == **
  7.                             \* ====================================== */
  8.  
  9. #include "TelexDef"
  10. typedef unsigned long unlong;
  11.  
  12.   static GrafPtr GetGlobal(void);
  13.  
  14. #define sysMemTop MemTop                     /* Low-memory addresses to install  */
  15. #define sysBufPtr BufPtr                     /* the code in RAM                  */
  16.  
  17. #define FictName   "\pHacker"                /* implicit (if Chooser name is abs)*/
  18. #define ServerType "\pTelex"
  19. #define ResidCode  'TELX'                    /* Resource type of Listener code   */ 
  20.  
  21. #define KeyMask    0x0000810D                /* Tab, Cmd, Control,Option, Shift  */ 
  22.  
  23. typedef void (*Starter)(Storage*);           /* starter procedure in the Listener*/
  24.  
  25.   static int  InstallIt(void);               /* installation routine             */
  26.   static void DrawIcon(short);               /* draw icon on startup screen      */
  27.  
  28. /*
  29.  * Installer code
  30.  */
  31. void main() {
  32.   short  refNum;
  33.   KeyMap theKeys;
  34.   asm {                                      /* load A4 for global access       */
  35.     MOVE.L A0,A4                             /* (see Think C manual for         */
  36.   }                                          /*  code resources)                */
  37.  
  38.   GetKeys(&theKeys);                         /* read keyboard state             */
  39.  
  40.     DrawIcon(!Button() &&                      /* the mouse button isn't pressed  */
  41.              !(theKeys.Key[1] & KeyMask) &&    /* none of "spec-keys" is pressed  */
  42.              OpenDriver("\p.MPP",&refNum) == noErr && /* AppleTalk opened         */
  43.              InstallIt() ?                     /* and installation was successful */
  44.                         OKiconID : BadIconID); /* if OllKorrect, draw OK, else Bad*/
  45. }
  46.  
  47. /*
  48.  * This procedure:
  49.  * 1. installs the Listener code in the TopMem;
  50.  * 2. reserves storage for Listener buffers (messages, etc);
  51.  * 3. starts the Listener.
  52.  * If any step fails, the procedure returns FASE, otherwise - TRUE
  53.  */
  54. static int InstallIt() {
  55.   Storage* theData;
  56.     Handle   theCode= GetResource(ResidCode,1);/* Read Listener code form the file*/
  57.     short    i;
  58.     long     codeSize;
  59.     char*    codeAddr;
  60.  
  61.   if(theCode == NIL) return(false);          /* the Listener code not found...  */
  62.  
  63.     codeSize = GetHandleSize(theCode);         /* calculate the code size         */
  64.  
  65.   /* Get memory for code & data (moving BufPtr) */
  66.     {                                          /* see IM v.IV to understand this  */
  67.       if((unlong)sysBufPtr - sizeof(Storage) - codeSize < 
  68.                ((unlong)sysMemTop >> 1) + 1024) return(false);
  69.     theData  = (Storage*) (sysBufPtr -= sizeof(Storage));
  70.         codeAddr = (char*)    (sysBufPtr -= codeSize);
  71.     }
  72.   BlockMove(*theCode,codeAddr,(short)codeSize);
  73.     
  74.   /* Initiate message records */
  75.   for(i=0; i<Nnotes; ++i) {                  /* for all elements:               */ 
  76.       NoteBuf* ptr    = theData->NoteBlocks+i;
  77.     ptr->q.qLink    = NIL;                   /* initiate Notification Manager   */
  78.         ptr->q.qType    = nmType;                /* records: Queue, marks, etc      */
  79.         ptr->q.nmMark   = 0;
  80.         ptr->q.nmSIcon  = 0;
  81.         ptr->q.nmSound  = (Handle) -1;           /* to produce SysBeep on output    */
  82.         ptr->q.nmStr    = ptr->mess;
  83.         ptr->q.nmRefCon = 0l;
  84.         ptr->busy       = FALSE;                 /* this element is free (no msg)   */
  85.     }
  86.  
  87.   /* Now we look for the header string and fill the header buffer*/
  88.   {
  89.     Handle theHeader;
  90.         if((theHeader = (Handle) GetString(HeaderSTRID)) != NIL) {
  91.           int i;                                 /* Yes, we've found the STR rsrc   */ 
  92.           for(i=1; i<= **theHeader && i<sizeof(theData->MessHeader); ++i) {
  93.               theData->MessHeader[i] = (*theHeader)[i];
  94.             }
  95.             *theData->MessHeader = (unsigned char) (i-1);
  96.         } else {                                 /* No, the header isn't found ->   */
  97.             *theData->MessHeader = 0;              /* set an empty header (leng = 0)  */
  98.         }
  99.     }
  100.  
  101.     /* Install our Named Socket in the AppleTalk network */
  102.     {
  103.       AddrBlock ForAll = {0,0,0};              /* Glad to hear from everybody     */
  104.         theData->ReqSocket = 0;                  /* automatically assigned socket   */
  105.       if(ATPOpenSocket(ForAll,&theData->ReqSocket) != noErr) return(FALSE);
  106.     }
  107.     
  108.   
  109.   /* Assign the name to the socket: type = Telex, Name = from Chooser (is any)*/
  110.   {
  111.     MPPParamBlock regRecord;
  112.     short         nodeid;
  113.     StringHandle  HomeName;
  114.     unchar*       pname  = NIL;
  115.     char*         pident = theData->NbpEntry.entityData;
  116.     int           length;
  117.  
  118.     /* form the NBP table entry     */
  119.     GetNodeAddress(&nodeid,&theData->NbpEntry.nteAddress.aNet);
  120.     theData->NbpEntry.nteAddress.aNode   = (unchar) nodeid;
  121.     theData->NbpEntry.nteAddress.aSocket = theData->ReqSocket;
  122.     theData->NbpEntry.qNext              = NIL;
  123.  
  124.     /* Set Server (Listener) Name  */
  125.     if((HomeName=GetString(HomeID)) != NIL){ /* we've found the "Chooser" name  */
  126.       pname= *HomeName;                      /* -> we'll use it                 */
  127.     } else {                                 /* if your computer has no Chooser:*/
  128.       pname = (unchar*)FictName;             /* YOU ARE A HACKER! (Shame on you)*/
  129.     }
  130.     if((length = *(unsigned char*)pname++)>=32) length = 32; /* AppleTalk limit */
  131.     *pident++  = (char)length;               /* put the Name into the NBP elem. */
  132.     while(--length>=0) *pident++ = *pname++;
  133.     pname = (unchar*)ServerType;             /* put the Type into the NBP elem. */
  134.     *pident++ = length = *pname++;
  135.     while(--length>=0) *pident++ = *pname++;
  136.     *pident++ = 1; *pident++ = '*';          /* put the Zone into the NBP elem. */
  137.  
  138.     regRecord.MPPcsCode     = tNBPRegister;  /* Now fill all fields for the call*/
  139.     regRecord.NBPinterval   = RegTimeOut;
  140.     regRecord.NBPcount      = Nrepeat;
  141.     regRecord.NBPverifyFlag = 1;
  142.     regRecord.NBPntQElPtr   = (Ptr)&theData->NbpEntry;
  143.  
  144.     if(PRegisterName(®Record,FALSE) != 0){/* Registration failed ->          */
  145.       ATPCloseSocket(theData->ReqSocket);    /* close our socket                */
  146.       return(FALSE);
  147.     }
  148.     }
  149.  
  150.     theData->RespBlock.ATPioResult = 2;        /* this value is used in Listener  */
  151.  
  152.   (*(Starter)codeAddr)(theData);             /* Call the Listener to start it   */
  153.  
  154.     return(TRUE);                              /* Everything is done -> return OK */
  155. }    
  156.  
  157.  
  158. /*
  159.  * Get QuickDraw Globals address
  160.  */
  161. static GrafPtr GetGlobal() {                 /* This procedure returns the      */
  162.   asm {                                      /* address of our Globals (A5) -   */ 
  163.     MOVE.L A5,D0                             /* sizeof(Ptr)                     */
  164.     SUBQ   #4,D0                             /* i.e. it's equiv. &thePort in an */
  165.   }                                          /* application                     */
  166. }
  167.  
  168. /*
  169.  * Draw an Icon on the StartUp Screen
  170.  */
  171. void DrawIcon(short code)    {
  172.     short*   pShift = (short*) 0x92C;          /* this magic addresses are used   */
  173.     short*   pCheck = (short*) 0x92E;          /* to draw an array of Icons.      */
  174.     short    Mask   = 0x1021;                  /* 5th Generation's method, I think*/
  175.     GrafPort thePort;
  176.     Rect     where;
  177.     Handle   theIcon= GetResource('ICN#',code);/* read the Icon to draw           */
  178.     BitMap   theMap = {NIL,4,{0,0,32,32}};     /* the BitMap for theIcon          */
  179.     
  180.     InitGraf(GetGlobal());                     /* We InitGraf(A5)                 */
  181.  
  182.     OpenPort(&thePort);                        /* open thePort (main screen)      */
  183.  
  184.     where.left = 8;                            /* magic calculations to find the  */
  185.     where.top  = thePort.portRect.bottom-40;   /* Icon Array's tail (Am I right?) */ 
  186.     if(((*pShift<<1) ^ Mask) == *pCheck) where.left = *pShift;
  187.  
  188.     where.bottom = where.top  + 32;            /* Our Icon is a 32x32 bitmap      */
  189.     where.right  = where.left + 32;
  190.  
  191.     HLock(theIcon);                            /* Lock the ICN# resource          */
  192.  
  193.     theMap.baseAddr = *theIcon+128;            /* build a BitMap for the Icon Mask*/
  194.     CopyBits(&theMap,&thePort.portBits,        /* and punch a hole in the desktop */
  195.              &theMap.bounds,&where,srcBic,NIL);/* with this BitMap                */
  196.  
  197.     theMap.baseAddr = *theIcon;                /* build a BitMap for the Icon Body*/
  198.     CopyBits(&theMap,&thePort.portBits,        /* and draw it in the punched hole */
  199.              &theMap.bounds,&where,srcOr ,NIL);
  200.  
  201.     ClosePort(&thePort);                       /* All done -> close thePort       */
  202.  
  203.     *pShift = where.left += 40;                /* correct magic values of the     */
  204.     *pCheck = (where.left<<1) ^ Mask;          /* Icon Array                      */
  205. }
  206.