home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************/
- /* Ascii Chart - a Desk Accessory for the Macintosh written by: */
- /* Wade S. Blomgren (c) 1986 version 1.0 */
- /* UC San Diego */
- /* */
- /* Both source and executable files may be freely distributed for */
- /* NON-COMMERCIAL USE ONLY provided this copyright notice is left */
- /* intact. */
- /* */
- /* This program is intended as an example for persons beginning to */
- /* learn about programming the Macintosh. It is NOT meant to be an */
- /* example of excellent programming or a particularly fabulous */
- /* idea for a program. It IS supposed to be chock full of comments */
- /* and to have some examples of common uses for the toolbox. */
- /* */
- /* This program was written using LightspeedC (c) from Think */
- /* Technologies, INC. and therefore includes material that is */
- /* copyright Think Technologies INC. */
- /* */
- /* Some techniques were gleaned from a PD desk accessory called */
- /* ZoomIdle by Paul DuBois, University of Wisconsin */
- /* */
- /* Wade S. Blomgren UCSD-ACS mailcode B-028 La Jolla, CA 92093 */
- /* */
- /*************************************************************************/
-
- #include "devicemgr.h"
- #include "quickdraw.h"
- #include "windowmgr.h"
- #include "dialogmgr.h"
- #include "eventmgr.h"
- #include "controlmgr.h"
-
- /* since this is a DA and not a standalone application we do not have to */
- /* initialize the various managers */
-
- /* Global Variables for the DA */
-
- /* the chart data is stored in two dimensional arrays so we can use the */
- /* drawtext routine (faster than repeated calls to drawchar) (IM I-172) */
-
- char octdata[23][47] = {
- "000 NUL 026 SYC 054 , 102 B 130 X 156 n ",
- "001 SOH 027 ETB 055 - 103 C 131 Y 157 o ",
- "002 STX 030 CAN 056 . 104 D 132 Z 160 p ",
- "003 ETX 031 EM 057 / 105 E 133 [ 161 q ",
- "004 EOT 032 SUB 060 0 106 F 134 \\ 162 r ",
- "005 ENQ 033 ESC 061 1 107 G 135 ] 163 s ",
- "006 ACK 034 FS 062 2 110 H 136 ^ 164 t ",
- "007 BEL 035 GS 063 3 111 I 137 _ 165 u ",
- "010 BS 036 RS 064 4 112 J 140 ` 166 v ",
- "011 HT 037 US 065 5 113 K 141 a 167 w ",
- "012 LF 040 SPA 066 6 114 L 142 b 170 x ",
- "013 VT 041 ! 067 7 115 M 143 c 171 y ",
- "014 FF 042 '' 070 8 116 N 144 d 172 z ",
- "015 CR 043 # 071 9 117 O 145 e 173 { ",
- "016 SO 044 $ 072 : 120 P 146 f 174 | ",
- "017 SI 045 % 073 ; 121 Q 147 g 175 } ",
- "020 DLE 046 & 074 < 122 R 150 h 176 ~ ",
- "021 DC1 047 ' 075 = 123 S 151 i 177 DEL",
- "022 DC2 050 ( 076 > 124 T 152 j ",
- "023 DC3 051 ) 077 ? 125 U 153 k ",
- "024 DC4 052 * 100 @ 126 V 154 l ",
- "025 NAK 053 + 101 A 127 W 155 m "};
-
- char decdata[23][47] = {
- "000 NUL 022 SYC 044 , 066 B 088 X 110 n ",
- "001 SOH 023 ETB 045 - 067 C 089 Y 111 o ",
- "002 STX 024 CAN 046 . 068 D 090 Z 112 p ",
- "003 ETX 025 EM 047 / 069 E 091 [ 113 q ",
- "004 EOT 026 SUB 048 0 070 F 092 \\ 114 r ",
- "005 ENQ 027 ESC 049 1 071 G 093 ] 115 s ",
- "006 ACK 028 FS 050 2 072 H 094 ^ 116 t ",
- "007 BEL 029 GS 051 3 073 I 095 _ 117 u ",
- "008 BS 030 RS 052 4 074 J 096 ` 118 v ",
- "009 HT 031 US 053 5 075 K 097 a 119 w ",
- "010 LF 032 SPA 054 6 076 L 098 b 120 x ",
- "011 VT 033 ! 055 7 077 M 099 c 121 y ",
- "012 FF 034 '' 056 8 078 N 100 d 122 z ",
- "013 CR 035 # 057 9 079 O 101 e 123 { ",
- "014 SO 036 $ 058 : 080 P 102 f 124 | ",
- "015 SI 037 % 059 ; 081 Q 103 g 125 } ",
- "016 DLE 038 & 060 < 082 R 104 h 126 ~ ",
- "017 DC1 039 ' 061 = 083 S 105 i 127 DEL",
- "018 DC2 040 ( 062 > 084 T 106 j ",
- "019 DC3 041 ) 063 ? 085 U 107 k ",
- "020 DC4 042 * 064 @ 086 V 108 l ",
- "021 NAK 043 + 065 A 087 W 109 m " };
-
- char hexdata[23][47] = {
-
- "000 NUL 016 SYC 02C , 042 B 058 X 06E n ",
- "001 SOH 017 ETB 02D - 043 C 059 Y 06F o ",
- "002 STX 018 CAN 02E . 044 D 05A Z 070 p ",
- "003 ETX 019 EM 02F / 045 E 05B [ 071 q ",
- "004 EOT 01A SUB 030 0 046 F 05C \\ 072 r ", /* escape the \ character */
- "005 ENQ 01B ESC 031 1 047 G 05D ] 073 s ",
- "006 ACK 01C FS 032 2 048 H 05E ^ 074 t ",
- "007 BEL 01D GS 033 3 049 I 05F _ 075 u ",
- "008 BS 01E RS 034 4 04A J 060 ` 076 v ",
- "009 HT 01F US 035 5 04B K 061 a 077 w ",
- "00A LF 020 SPA 036 6 04C L 062 b 078 x ",
- "00B VT 021 ! 037 7 04D M 063 c 079 y ",
- "00C FF 022 '' 038 8 04E N 064 d 07A z ",
- "00D CR 023 # 039 9 05F O 065 e 07B { ",
- "00E SO 024 $ 03A : 050 P 066 f 07C | ",
- "00F SI 025 % 03B ; 051 Q 067 g 07D } ",
- "010 DLE 026 & 03C < 052 R 068 h 07E ~ ",
- "011 DC1 027 ' 03D = 053 S 069 i 07F DEL",
- "012 DC2 028 ( 03E > 054 T 06A j ",
- "013 DC3 029 ) 03F ? 055 U 06B k ",
- "014 DC4 02A * 040 @ 056 V 06C l ",
- "015 NAK 02B + 041 A 057 W 06D m " };
-
- DCtlPtr dce; /* pointer to the device control entry struct */
- int DAisOpen = 0; /* flag so we know if the DA is already open */
-
- #define rALRT 0 /* the About box's resource ID # */
-
- /* allocate control handles to the various control buttons */
-
- ControlHandle OctPtr,HexPtr,DecPtr,curControl,whichControl,AbPtr;
-
-
- int line; /* counter for the text drawing loop */
- int y; /* coordinate variable for positioning the text */
-
- /* define rectangles for the DA's window and the control buttons */
- /* BlankRect is the entire data area & is used to erase the data */
- static Rect bounds = { 60,60, 335, 350 };
- static Rect OctRect = { 225,12,242,80 };
- static Rect HexRect = { 225,115, 242, 185 };
- static Rect DecRect = { 225,200, 242, 268 };
- static Rect AbRect = { 250,85, 270, 205 };
- static Rect BlankRect = { 3,12,220,280 };
-
- /* various functions begin here - see 'main' for calling sequence */
-
-
- aboutDA() /* creates an alert dialog message about */
- /* the DA and gives an OK button to exit */
- {
- /* the alert resource and accompanying item list are stored in a */
- /* file called "ascii_chart.rsrc" which was created with ResEdit */
- /* ..since the OK button is the default (highlighted) choice, we */
- /* do not have to have a filterProc (IM I-419) */
- /* If you examine the DA file with ResEdit, you will see that the */
- /* resource ID for the ALRT is -16000, which translates into an */
- /* 'owned' resource ID of '0' (zero) for a DRVR (our program) */
- /* with an ID of '12'. This is the ID number that LightspeedC */
- /* assigns to a Desk Accesory that it creates. When you install */
- /* a DA with the Font/DA mover, it checks to see that the ID# does */
- /* not conflict with that of an existing DA. If it does, the F/DA */
- /* will change our DA's ID to an unused #, and all of the 'owned' */
- /* resource ID's will be shifted accordingly. Read IM I-108,109. */
-
- Alert(rsrcID(rALRT),0L); /* invoke the alert (IM I-418) */
-
- }
-
- /* this routine from the LightspeedC demo DA by Michael Kahl... */
- /* returns the correct resource ID number "no matter what driver # */
- /* the Font/DA Mover has assigned us... " (IM I-109) */
-
- rsrcID(id)
- {
- return(0xc000 + (~dce->dCtlRefNum << 5 ) + id);
- }
-
-
- /* window update routine - if it's a result of a radix change, scope */
- /* is 0 (update everything) - if it is a system update event, update */
- /* only the area that needs it, by using BeginUpdate & EndUpdate */
- /* (see calls to 'updateDisplay()' in 'main' and 'DAEvent' */
-
- updateDisplay(scope)
- int scope;
- {
-
- GrafPtr currentPort;
- Ptr dataAddr; /* a generic 'pointer' data type */
-
- GetPort(¤tPort); /* save the current grafport (IM I-447) */
- SetPort(dce->dCtlWindow); /* set the grafport to our window */
-
- if (scope)
- BeginUpdate(dce->dCtlWindow); /* set the visRgn to only the part */
- /* that needs updating (IM I-292) */
- /* otherwise, redraw the whole window */
-
- DrawControls(dce->dCtlWindow); /* draw the controls in our window */
- EraseRect(&BlankRect); /* blank out the old data (IM I-177) */
- y = 10;
-
- if (curControl == OctPtr) /* determine which control was pressed */
- dataAddr = (Ptr) octdata; /* & cast the address of the 2D array */
- else if (curControl == DecPtr) /* into our generic data pointer */
- dataAddr = (Ptr) decdata;
- else if (curControl == HexPtr)
- dataAddr = (Ptr) hexdata;
-
- TextFont(4); /* Monaco font for evenly spaced columns (IM I-219) */
- TextSize(9); /* these are quickdraw functions */
-
- for (line = 0; line < 22; line++) {
-
- /* we have 23 lines per 'page' - use quickdraw to output the data */
- /* the starting address for DrawText is (line# * 47) to get to the */
- /* proper position in the 2D array */
-
- MoveTo(12,y);
- DrawText(dataAddr + (line * 47),0,46); /* (IM I-172) */
- y = y +10;
- }
-
- if (scope) EndUpdate(dce->dCtlWindow);
-
- SetPort(currentPort); /* restore the current grafport (IM I-447) */
-
- } /* end of updateDisplay */
-
-
-
- openDA() /* open the desk accessory */
- {
-
- GrafPtr currentPort;
-
- if (DAisOpen) return; /* if it is already open, just ignore */
- GetPort(¤tPort); /* save the current grafport */
-
- /* create our window, set the device control entry (dce) window field */
- /* to our window, set the window's windowKind field to the reference # */
- /* for the driver (IM I-445) */
-
- dce->dCtlWindow = NewWindow(0,&bounds,"\pAscii Chart",0,16,-1,1,0);
- ((WindowPeek) (dce->dCtlWindow))->windowKind = dce->dCtlRefNum;
-
- SetPort(dce->dCtlWindow); /* set the grafport to our window */
- ShowWindow(dce->dCtlWindow); /* display the window */
-
-
- /* create new controls for the various radixes and the about box */
- /* set the octal radix control to be 'on'... (IM I-319) */
- OctPtr = NewControl(dce->dCtlWindow,&OctRect,"\poctal",1,1,0,1,2,0);
- HexPtr = NewControl(dce->dCtlWindow,&HexRect,"\phex",1,0,0,1,2,0);
- DecPtr = NewControl(dce->dCtlWindow,&DecRect,"\pdecimal",1,0,0,1,2,0);
- AbPtr = NewControl(dce->dCtlWindow,&AbRect,"\pabout ascii chart",1,1,0,0,0,0);
-
- curControl = OctPtr; /* set default for current control button */
-
- /* we do not need to explicitly call "updateDisplay" because the open */
- /* routine will cause an update event to be sent to the Desk Manager */
-
- DAisOpen = 1; /* set the DA 'on' (our own flag) */
- SetPort(currentPort); /* restore original grafport */
-
- return(0);
-
- } /* end of the openDA routine */
-
-
- DAevent(theEvent)
- EventRecord *theEvent; /* argument is a pointer to an event record */
- {
-
- GrafPtr currentPort;
-
- GetPort(¤tPort); /* save the system's current grafport */
-
- /* at this point we know there has been an event in the DA window */
- /* content region, so we must process the event */
-
- SetPort(dce->dCtlWindow); /* set the port to our window */
-
- switch (theEvent->what) { /* examine the 'what' field of event */
- /* (IM I-263,264) */
- case activateEvt: /* the DA window has become active */
- updateDisplay(1);
- return(0);
-
- case updateEvt: /* we need to update (result of drag, etc) */
- updateDisplay(1);
- return(0);
-
- case mouseDown:
- /* convert the location to local coordinates (IM I-193,323) */
- GlobalToLocal(&(theEvent->where));
-
- /* find where mouse was pressed - (the part code) (IM I-334) */
-
- switch (FindControl(theEvent->where,dce->dCtlWindow,&whichControl)) {
-
- case (11): /* a RADIO button has been hit - track it */
-
- /* track control routine makes sure mouse is released in button */
- if (TrackControl(whichControl,theEvent->where,0)) {
-
- if (whichControl != curControl) { /* a new radix */
- SetCtlValue(curControl,0);
- curControl = whichControl; /* set new 'current' ctl */
- SetCtlValue(curControl,1);
- updateDisplay(0); /* update whole window */
- } /* end new radix */
- } /* end if track control */
- break;
- case (10): /* SIMPLE button (must be the about box) */
-
- /* create an alert dialog with an OK button to terminate */
-
- aboutDA();
- break;
-
- } /* end possible control mousedown */
-
- LocalToGlobal(&theEvent->where); /* put the coordinates back to global */
-
- } /* end of the event switch */
-
- SetPort(currentPort); /* restore the grafport */
-
- } /* end of DAevent */
-
-
-
- /* close DA function */
-
- closeDA()
- {
- GrafPtr currentPort;
-
- GetPort(¤tPort); /* save the system's grafport */
- DisposeWindow(dce->dCtlWindow);/* dispose our window */
- dce->dCtlWindow = 0L; /* set the driver's window ptr to null */
- /* (IM I-446) */
- SetPort(currentPort); /* restore the system's grafport */
- return(0);
-
- }
- /* main driver routine - three parameters are passed to us through the */
- /* device manager. 1. the control parameter pointer */
- /* 2. the pointer to the dce record */
- /* 3. the driver routine (open, control, or close) */
- /* (IM II-201, I-445 ) */
-
-
- main (p,d,n)
- cntrlParam *p;
- DCtlPtr d;
- int n;
-
-
- {
-
- if (d->dCtlStorage == 0 ) {
- if (n == 0) { /* open but no data */
- SysBeep(3);
- CloseDriver(d->dCtlRefNum);
- }
- return(0);
- }
-
- dce = d;
-
- /* find the appropriate driver routine */
-
- switch(n) { /* 0 = open, 2 = control event, 4 = close */
-
- case 0: /* open the DA */
- openDA();
- break;
-
- case 2: /* action in the DA */
- switch(p->csCode) {
-
- case accEvent:
- DAevent(((EventRecord *) * (long *) &p->csParam));
-
- /* casting the *address of* p->csParam as an pointer to a long, and the */
- /* long is cast as a pointer to a pointer to an Event Record (I think?) */
- /* (from ZoomIdle 1.1 by Paul DuBois) */
- /* the pointer is passed as the parameter to DAevent */
-
-
- } /* end of case 2 switch */
- break;
-
- case 4: /* close box has been clicked */
- closeDA();
- break;
-
- } /* end of the main switch */
-
- return(0);
-
-
- } /* end of main */
-
-
-
-
-