home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / da / genericd.sit / GenericCDA.c < prev    next >
Text File  |  1986-11-08  |  10KB  |  384 lines

  1. /*
  2.  *    
  3.  *    A Generic Desk Accessory written in LightSpeedC¬
  4.  *
  5.  *    By David HM Spector
  6.  *    Copyright ⌐1986, All Rights Reserved
  7.  *
  8.  * Permission is granted for unlimited non-commercial use.
  9.  * Permission is granted for commercial use provided credit is given in the
  10.  * desk accessory and its documentation.
  11.  *
  12.  *
  13.  *  Please mail suggestions, et al to:
  14.  *
  15.  *    US Snail:    David HM Spector
  16.  *                310 West 18th St. #5A
  17.  *                New York, NY 10011
  18.  *
  19.  *    ARPAnet:    SPECTOR@NYU.EDU         
  20.  *    USEnet:        ...{allegra,siesmo, rocky, ihnp4}!cmcl2!spector
  21.  *    MCIMail:    DSPECTOR
  22.  *    GEnie:        XJM21945
  23.  *
  24.  *
  25.  *  This is a Generic DA written in LightSpeedC¬.  I wrote it because I often
  26.  *  write DA's, and I hate to start them from scratch each and every time.
  27.  *  Gutting other DA's is also, to say the least, a pain. So I decided to write
  28.  *  a complete minimal Desk Accessory that would do everything a real DA
  29.  *  could do and still be simple to modify and understand.  Hence, the GenericDA.
  30.  *
  31.  *    Among other things, GenericDA will do the following:
  32.  *        o put up its own window
  33.  *        o put up its own menu(s) (with an about box)
  34.  *        o respond to update events
  35.  *        o respond to activate events (including inserting/removing its menu)
  36.  *        o respond to keydown/autokey events (you'll have to write your own edit
  37.  *          functions though)
  38.  *
  39.  *
  40.  *    What you need:
  41.  *    1. LightSpeedC¬ version 1.05 or later.
  42.  *    2. RMaker1.01b1 or later (for the GenericDA.r file) -or- ResEdit1.0 or later
  43.  *
  44.  *    Compiling the DA:
  45.  *    1. Make a new project and add this file, and the MacTraps library.
  46.  *    2. Set the project type to "Desk Accessory" (and pick a name).
  47.  *    3. Edit the GenericDA file to use the correct path names for your system
  48.  *    4. Compile and save the DA.
  49.  *    5. Edit the RMaker file to reflect the path name for the name you gave the
  50.  *       DA you just compiled.
  51.  *    6. Run the RMaker on the Rmaker file and install the DA with Font/DA Mover.
  52.  *
  53.  *
  54.  *
  55.  *                        Revision History
  56.  *
  57.  *        Date    Version        Who                        What
  58.  *  11/8/86            0.0        DHMS        Start. Defined routines, added
  59.  *                                        event handler.
  60.  *                    0.5        DHMS        Added Menus and owned resources
  61.  *                    1.0        DHMS        Fixed bug in doEvent.[ Forgot to
  62.  *                                        Cast csParam[0] to be (EventRecord *)
  63.  *                                        -- causes an address error...
  64.  */
  65.  
  66.  
  67. /*    This covers almost all of the available include files, some of these may 
  68.  *  not be needed by your Desk Accessory... it would speed compilation to
  69.  *  remove all but the ones you need.
  70.  *
  71.  *  Note:  The path name will have to be changed to match your configuration.
  72.  */
  73. #include "HD╨20:Compilers:LS C:Mac #Includes:MacTypes.h"
  74. #include "HD╨20:Compilers:LS C:Mac #Includes:AppleTalk.h"
  75. #include "HD╨20:Compilers:LS C:Mac #Includes:ControlMgr.h"
  76. #include "HD╨20:Compilers:LS C:Mac #Includes:DeskMgr.h"
  77. #include "HD╨20:Compilers:LS C:Mac #Includes:DeviceMgr.h"
  78. #include "HD╨20:Compilers:LS C:Mac #Includes:DialogMgr.h"
  79. #include "HD╨20:Compilers:LS C:Mac #Includes:EventMgr.h"
  80. #include "HD╨20:Compilers:LS C:Mac #Includes:HFS.h"    /* only for LSC 2.0 or later! */
  81. #include "HD╨20:Compilers:LS C:Mac #Includes:MemoryMgr.h"
  82. #include "HD╨20:Compilers:LS C:Mac #Includes:MenuMgr.h"
  83. #include "HD╨20:Compilers:LS C:Mac #Includes:OSUtil.h"
  84. #include "HD╨20:Compilers:LS C:Mac #Includes:PackageMgr.h"
  85. #include "HD╨20:Compilers:LS C:Mac #Includes:Quickdraw.h"
  86. #include "HD╨20:Compilers:LS C:Mac #Includes:ResourceMgr.h"
  87. #include "HD╨20:Compilers:LS C:Mac #Includes:StdFilePkg.h"
  88. #include "HD╨20:Compilers:LS C:Mac #Includes:TextEdit.h"
  89. #include "HD╨20:Compilers:LS C:Mac #Includes:ToolboxUtil.h"
  90. #include "HD╨20:Compilers:LS C:Mac #Includes:WindowMgr.h"
  91.  
  92. /* Misc useful define's */
  93. #define    NIL    0        /* for pointers, etc */             
  94. #define    INFRONT    -1    /* for windows */
  95. #define    False 0
  96. #define    True 0xFF
  97. #define    OFF    0        /* RadioButton control values */
  98. #define    ON    1
  99. #define    ACTIVE    0    /* For fiddling with other control states */
  100. #define    INACTIVE 255
  101.  
  102. #define    drvrOpen    0
  103. #define    drvrPrime    1
  104. #define    drvrControl    2
  105. #define    drvrStatus    3
  106. #define    drvrClose    4
  107.  
  108. #define    WINDOWTYPE     rDocProc
  109. #define    WINDOWTITLE "\pA Generic DA"
  110. #define    THEMENUID    1    /*     this is a local ID that must be resolved    */
  111. #define    ABOUTBOX    1    /*    The    About╔ box for this DA                    */
  112.  
  113.  
  114. Rect windowRect = {40, 20, 100, 200};
  115. MenuHandle ourMenu = 0;
  116. int    refNum = 0;    /* this is the drivers refnum that is in dce->dCtlRefNum */
  117.  
  118. /*                Routines used by the driver's main routines                */
  119. int    resolveid(refNum,theid)
  120.     int refNum;
  121.     int theid;
  122.     /* See Inside Macintosh, Vol.I, Pp.109-110 for info on calculating owned IDs */
  123.     {
  124.     return ( ( 0xC000 | (refNum<<5) ) + theid);
  125.     }
  126.  
  127. char validWindow(window)
  128.   WindowPtr window;
  129.   {
  130.   WindowPtr nextWindow;
  131.   
  132.   if (window)
  133.     {
  134.         nextWindow = FrontWindow();
  135.     while (nextWindow)
  136.      if (window == nextWindow) return (1);
  137.         else nextWindow = (WindowPtr)(((WindowPeek)nextWindow)->nextWindow);
  138.      }
  139.     return 0;
  140.   }
  141.  
  142. doAboutBox(window)
  143. WindowPtr window;
  144. {
  145.  DialogPtr theDialog;
  146.  
  147.  theDialog = GetNewDialog(resolveid(refNum,ABOUTBOX),NIL,INFRONT);
  148.  SetPort(theDialog);
  149.  DrawDialog(theDialog);
  150.    do 
  151.     ;
  152.    while (!Button());
  153.  CloseDialog(theDialog);
  154.  SetPort(window);
  155. }
  156.     
  157.  
  158. /*                    Driver Routines Live Here                            */
  159.     
  160. open(iopb,dce)
  161.     cntrlParam *iopb;    /*     pointer to parameter block    */
  162.     DCtlPtr dce;        /*     the device control entry    */
  163.     {
  164.     WindowPtr window;
  165.     GrafPtr oldPort;
  166.     
  167.      refNum = dce->dCtlRefNum;
  168.      if (refNum < 0)
  169.         refNum = -refNum;
  170.     refNum = refNum - 1;
  171.         
  172.   if ((window = dce->dCtlWindow) == 0) /* already have a window? */
  173.     { 
  174.     GetPort(&oldPort);/* no, make new one╔ */
  175.     window = NewWindow(0, &windowRect, WINDOWTITLE, 0, WINDOWTYPE,INFRONT, 1, 0);
  176.     SetPort(window);
  177.     ((WindowPeek)window)->windowKind = dce->dCtlRefNum;
  178.     dce->dCtlWindow = window;
  179.     
  180.     ourMenu = GetMenu(resolveid(refNum,THEMENUID));    
  181.     dce->dCtlMenu = resolveid(refNum,THEMENUID);
  182.     InsertMenu(ourMenu,0);
  183.  
  184.     SetPort(oldPort);
  185.     }
  186.   return(0);
  187.   }
  188.     
  189. prime(iopb,dce)
  190.     cntrlParam *iopb;    /*     pointer to parameter block    */
  191.     DCtlPtr dce;        /*     the device control entry    */
  192.     {
  193.     /*    Generally, only 'real' device drivers respond to prime calls    */
  194.     return(0);
  195.     }
  196.     
  197. control(iopb,dce)
  198.     cntrlParam *iopb;    /*     pointer to parameter block    */
  199.     DCtlPtr dce;        /*     the device control entry    */
  200.     {
  201.     GrafPtr ourPort;
  202.     WindowPtr window;
  203.     
  204.     if (validWindow(window = dce->dCtlWindow))
  205.         {
  206.         GetPort(&ourPort);
  207.         SetPort(window);
  208.         
  209.         switch (iopb->csCode)
  210.             {
  211.             case accEvent:
  212.              doEvent(((EventRecord *) * (long *) &iopb->csParam),window);
  213.                     break;
  214.             case accRun:
  215.                     /* If you are getting time from the system, here's where to 
  216.                      * do your thing.
  217.                      */
  218.                     break;
  219.             case accCursor:
  220.                     break;
  221.             case accMenu:
  222.                     {
  223.                     int menuItem;
  224.                     menuItem = iopb->csParam[1];
  225.                     switch (menuItem)
  226.                         {
  227.                         /* Handle your menu items here╔     */
  228.                         case 1:
  229.                             doAboutBox(window);
  230.                             break;
  231.                         case 2:
  232.                             SysBeep(3); 
  233.                             break;
  234.                             /* ╔ */
  235.                         default:
  236.                             SysBeep(3); 
  237.                             break;
  238.                     }
  239.                 HiliteMenu(0);
  240.                 break;
  241.                 }
  242.             case accUndo:
  243.                     SysBeep(2);
  244.                     break; 
  245.             case accCut:
  246.                     SysBeep(2); 
  247.                     break; 
  248.             case accCopy:
  249.                     SysBeep(2); 
  250.                     break; 
  251.             case accPaste:
  252.                     SysBeep(2); 
  253.                     break; 
  254.             case accClear:
  255.                     SysBeep(2);
  256.                     break; 
  257.                 }
  258.         SetPort(ourPort);
  259.         }
  260.  return(0);
  261.  }
  262.  
  263. doEvent(event, window)
  264.     EventRecord *event;
  265.     WindowPtr    window;
  266.     {
  267.     SetPort(window);
  268.     switch (event->what)
  269.         {
  270.             case keyDown:
  271.             case autoKey:
  272.                 if ((event->modifiers & cmdKey))
  273.                     {
  274.                     switch ((char) (event->message))
  275.                         {
  276.                         case 'c':
  277.                         case 'C':
  278.                             SysBeep(2);
  279.                             break;
  280.                         case 'v':
  281.                         case 'V':
  282.                             SysBeep(2);
  283.                             break;
  284.                         case 'x':
  285.                         case 'X':
  286.                             SysBeep(2);
  287.                             break;
  288.                         default:
  289.                             SysBeep(2);
  290.                         }
  291.                     break;
  292.                     }
  293.                     return;
  294.             
  295.             case mouseDown:
  296.                     GlobalToLocal(&event->where);
  297.                     return;
  298.             
  299.             case updateEvt:
  300.                     SetPort(window);
  301.                     BeginUpdate(window);
  302.                     /*    Do update stuff here */
  303.                     EndUpdate(window);
  304.                     return;
  305.                     
  306.             case activateEvt:
  307.                     if ((event->modifiers & activeFlag)) {
  308.                         InsertMenu(ourMenu,0);    /* put menu up */
  309.                         DrawMenuBar();
  310.                         }
  311.                     else {
  312.                           DeleteMenu(resolveid(refNum,THEMENUID));
  313.                           DrawMenuBar();
  314.                          }
  315.                          return;
  316.             }
  317.         }
  318.         
  319.         
  320. status(iopb,dce)
  321.     cntrlParam *iopb;    /*     pointer to parameter block    */
  322.     DCtlPtr dce;        /*     the device control entry    */
  323.     {
  324.     /*    Generally, only 'real' device drivers respond to status calls    */
  325.     return(0);
  326.     }
  327.     
  328. close(iopb,dce)
  329.     cntrlParam *iopb;    /*     pointer to parameter block    */
  330.     DCtlPtr dce;        /*     the device control entry    */
  331.     {
  332.    WindowPtr window;
  333.    
  334.      if (validWindow(window = dce->dCtlWindow))
  335.      {
  336.        DeleteMenu(resolveid(refNum,THEMENUID));
  337.        DrawMenuBar();
  338.        dce->dCtlMenu = NIL;
  339.        DisposeWindow(window);
  340.        dce->dCtlWindow = NIL;
  341.      }
  342.     return(0);
  343.     }
  344.  
  345.  
  346. main(iopb, dce, n)
  347.     cntrlParam *iopb;    /*     pointer to parameter block    */
  348.     DCtlPtr dce;        /*     the device control entry    */
  349.     int    n;                /*    routine selector            */
  350.     {
  351.     
  352.     /*    Make sure that our 'globals' we actually allocated for us.
  353.      *    give up if they weren't.
  354.      */
  355.     if (dce->dCtlStorage == 0) {
  356.         if (n == 0) {    /*  open, but no data  */
  357.             SysBeep(3);
  358.             CloseDriver(dce->dCtlRefNum);
  359.         }
  360.         return(0);
  361.     }
  362.     /*            Since we're here, we have our globals, now set the flags╔        */
  363.     dce->dCtlFlags |= dNeedLock | dNeedTime;
  364.     dce->dCtlDelay = 60;    /* 1 second - 60 ticks    */
  365.  
  366.     switch (n) {
  367.     case drvrOpen:            
  368.             open(iopb,dce);
  369.             break;
  370.     case drvrPrime:
  371.             prime(iopb,dce);
  372.             break;
  373.     case drvrControl:
  374.             control(iopb,dce);
  375.             break;
  376.     case drvrStatus:
  377.             status(iopb,dce);
  378.             break;
  379.     case drvrClose:
  380.             close(iopb,dce);
  381.             break;
  382.         }
  383.     
  384.     }