home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel Volume 2 #1
/
carousel.iso
/
mactosh
/
da
/
genericd.sit
/
GenericCDA.c
< prev
next >
Wrap
Text File
|
1986-11-08
|
10KB
|
384 lines
/*
*
* A Generic Desk Accessory written in LightSpeedC¬
*
* By David HM Spector
* Copyright ⌐1986, All Rights Reserved
*
* Permission is granted for unlimited non-commercial use.
* Permission is granted for commercial use provided credit is given in the
* desk accessory and its documentation.
*
*
* Please mail suggestions, et al to:
*
* US Snail: David HM Spector
* 310 West 18th St. #5A
* New York, NY 10011
*
* ARPAnet: SPECTOR@NYU.EDU
* USEnet: ...{allegra,siesmo, rocky, ihnp4}!cmcl2!spector
* MCIMail: DSPECTOR
* GEnie: XJM21945
*
*
* This is a Generic DA written in LightSpeedC¬. I wrote it because I often
* write DA's, and I hate to start them from scratch each and every time.
* Gutting other DA's is also, to say the least, a pain. So I decided to write
* a complete minimal Desk Accessory that would do everything a real DA
* could do and still be simple to modify and understand. Hence, the GenericDA.
*
* Among other things, GenericDA will do the following:
* o put up its own window
* o put up its own menu(s) (with an about box)
* o respond to update events
* o respond to activate events (including inserting/removing its menu)
* o respond to keydown/autokey events (you'll have to write your own edit
* functions though)
*
*
* What you need:
* 1. LightSpeedC¬ version 1.05 or later.
* 2. RMaker1.01b1 or later (for the GenericDA.r file) -or- ResEdit1.0 or later
*
* Compiling the DA:
* 1. Make a new project and add this file, and the MacTraps library.
* 2. Set the project type to "Desk Accessory" (and pick a name).
* 3. Edit the GenericDA file to use the correct path names for your system
* 4. Compile and save the DA.
* 5. Edit the RMaker file to reflect the path name for the name you gave the
* DA you just compiled.
* 6. Run the RMaker on the Rmaker file and install the DA with Font/DA Mover.
*
*
*
* Revision History
*
* Date Version Who What
* 11/8/86 0.0 DHMS Start. Defined routines, added
* event handler.
* 0.5 DHMS Added Menus and owned resources
* 1.0 DHMS Fixed bug in doEvent.[ Forgot to
* Cast csParam[0] to be (EventRecord *)
* -- causes an address error...
*/
/* This covers almost all of the available include files, some of these may
* not be needed by your Desk Accessory... it would speed compilation to
* remove all but the ones you need.
*
* Note: The path name will have to be changed to match your configuration.
*/
#include "HD╨20:Compilers:LS C:Mac #Includes:MacTypes.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:AppleTalk.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:ControlMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:DeskMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:DeviceMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:DialogMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:EventMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:HFS.h" /* only for LSC 2.0 or later! */
#include "HD╨20:Compilers:LS C:Mac #Includes:MemoryMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:MenuMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:OSUtil.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:PackageMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:Quickdraw.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:ResourceMgr.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:StdFilePkg.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:TextEdit.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:ToolboxUtil.h"
#include "HD╨20:Compilers:LS C:Mac #Includes:WindowMgr.h"
/* Misc useful define's */
#define NIL 0 /* for pointers, etc */
#define INFRONT -1 /* for windows */
#define False 0
#define True 0xFF
#define OFF 0 /* RadioButton control values */
#define ON 1
#define ACTIVE 0 /* For fiddling with other control states */
#define INACTIVE 255
#define drvrOpen 0
#define drvrPrime 1
#define drvrControl 2
#define drvrStatus 3
#define drvrClose 4
#define WINDOWTYPE rDocProc
#define WINDOWTITLE "\pA Generic DA"
#define THEMENUID 1 /* this is a local ID that must be resolved */
#define ABOUTBOX 1 /* The About╔ box for this DA */
Rect windowRect = {40, 20, 100, 200};
MenuHandle ourMenu = 0;
int refNum = 0; /* this is the drivers refnum that is in dce->dCtlRefNum */
/* Routines used by the driver's main routines */
int resolveid(refNum,theid)
int refNum;
int theid;
/* See Inside Macintosh, Vol.I, Pp.109-110 for info on calculating owned IDs */
{
return ( ( 0xC000 | (refNum<<5) ) + theid);
}
char validWindow(window)
WindowPtr window;
{
WindowPtr nextWindow;
if (window)
{
nextWindow = FrontWindow();
while (nextWindow)
if (window == nextWindow) return (1);
else nextWindow = (WindowPtr)(((WindowPeek)nextWindow)->nextWindow);
}
return 0;
}
doAboutBox(window)
WindowPtr window;
{
DialogPtr theDialog;
theDialog = GetNewDialog(resolveid(refNum,ABOUTBOX),NIL,INFRONT);
SetPort(theDialog);
DrawDialog(theDialog);
do
;
while (!Button());
CloseDialog(theDialog);
SetPort(window);
}
/* Driver Routines Live Here */
open(iopb,dce)
cntrlParam *iopb; /* pointer to parameter block */
DCtlPtr dce; /* the device control entry */
{
WindowPtr window;
GrafPtr oldPort;
refNum = dce->dCtlRefNum;
if (refNum < 0)
refNum = -refNum;
refNum = refNum - 1;
if ((window = dce->dCtlWindow) == 0) /* already have a window? */
{
GetPort(&oldPort);/* no, make new one╔ */
window = NewWindow(0, &windowRect, WINDOWTITLE, 0, WINDOWTYPE,INFRONT, 1, 0);
SetPort(window);
((WindowPeek)window)->windowKind = dce->dCtlRefNum;
dce->dCtlWindow = window;
ourMenu = GetMenu(resolveid(refNum,THEMENUID));
dce->dCtlMenu = resolveid(refNum,THEMENUID);
InsertMenu(ourMenu,0);
SetPort(oldPort);
}
return(0);
}
prime(iopb,dce)
cntrlParam *iopb; /* pointer to parameter block */
DCtlPtr dce; /* the device control entry */
{
/* Generally, only 'real' device drivers respond to prime calls */
return(0);
}
control(iopb,dce)
cntrlParam *iopb; /* pointer to parameter block */
DCtlPtr dce; /* the device control entry */
{
GrafPtr ourPort;
WindowPtr window;
if (validWindow(window = dce->dCtlWindow))
{
GetPort(&ourPort);
SetPort(window);
switch (iopb->csCode)
{
case accEvent:
doEvent(((EventRecord *) * (long *) &iopb->csParam),window);
break;
case accRun:
/* If you are getting time from the system, here's where to
* do your thing.
*/
break;
case accCursor:
break;
case accMenu:
{
int menuItem;
menuItem = iopb->csParam[1];
switch (menuItem)
{
/* Handle your menu items here╔ */
case 1:
doAboutBox(window);
break;
case 2:
SysBeep(3);
break;
/* ╔ */
default:
SysBeep(3);
break;
}
HiliteMenu(0);
break;
}
case accUndo:
SysBeep(2);
break;
case accCut:
SysBeep(2);
break;
case accCopy:
SysBeep(2);
break;
case accPaste:
SysBeep(2);
break;
case accClear:
SysBeep(2);
break;
}
SetPort(ourPort);
}
return(0);
}
doEvent(event, window)
EventRecord *event;
WindowPtr window;
{
SetPort(window);
switch (event->what)
{
case keyDown:
case autoKey:
if ((event->modifiers & cmdKey))
{
switch ((char) (event->message))
{
case 'c':
case 'C':
SysBeep(2);
break;
case 'v':
case 'V':
SysBeep(2);
break;
case 'x':
case 'X':
SysBeep(2);
break;
default:
SysBeep(2);
}
break;
}
return;
case mouseDown:
GlobalToLocal(&event->where);
return;
case updateEvt:
SetPort(window);
BeginUpdate(window);
/* Do update stuff here */
EndUpdate(window);
return;
case activateEvt:
if ((event->modifiers & activeFlag)) {
InsertMenu(ourMenu,0); /* put menu up */
DrawMenuBar();
}
else {
DeleteMenu(resolveid(refNum,THEMENUID));
DrawMenuBar();
}
return;
}
}
status(iopb,dce)
cntrlParam *iopb; /* pointer to parameter block */
DCtlPtr dce; /* the device control entry */
{
/* Generally, only 'real' device drivers respond to status calls */
return(0);
}
close(iopb,dce)
cntrlParam *iopb; /* pointer to parameter block */
DCtlPtr dce; /* the device control entry */
{
WindowPtr window;
if (validWindow(window = dce->dCtlWindow))
{
DeleteMenu(resolveid(refNum,THEMENUID));
DrawMenuBar();
dce->dCtlMenu = NIL;
DisposeWindow(window);
dce->dCtlWindow = NIL;
}
return(0);
}
main(iopb, dce, n)
cntrlParam *iopb; /* pointer to parameter block */
DCtlPtr dce; /* the device control entry */
int n; /* routine selector */
{
/* Make sure that our 'globals' we actually allocated for us.
* give up if they weren't.
*/
if (dce->dCtlStorage == 0) {
if (n == 0) { /* open, but no data */
SysBeep(3);
CloseDriver(dce->dCtlRefNum);
}
return(0);
}
/* Since we're here, we have our globals, now set the flags╔ */
dce->dCtlFlags |= dNeedLock | dNeedTime;
dce->dCtlDelay = 60; /* 1 second - 60 ticks */
switch (n) {
case drvrOpen:
open(iopb,dce);
break;
case drvrPrime:
prime(iopb,dce);
break;
case drvrControl:
control(iopb,dce);
break;
case drvrStatus:
status(iopb,dce);
break;
case drvrClose:
close(iopb,dce);
break;
}
}