fjh@bentley.UUCP (FJ Hirsch) (08/27/84)
# # Here is Michael Schuster's desk accessory launcher/installer for # non-ARPA people. # Fred. # #Date: Wed, 22 Aug 84 19:12:23 pdt #---------------------------------------------------------------------------- #! /bin/sh echo x - desk.c cat > desk.c << '{~}{~}' /* * Desk accessory launcher/installer. * * (C) Copyright 1984 Michael Schuster * All Rights Reserved */ /* * 08/10/84 Schuster Created * 08/21/84 Schuster Search for unused resource id */ #include "quickdraw.h" #include "osintf.h" #include "toolintf.h" #define NIL 0 #define FALSE 0 #define TRUE 1 #define minID 12 #define maxID 31 #define appleMenu 1 #define fileMenu 2 #define editMenu 3 #define closeItem 1 #define installItem 2 #define quitItem 3 #define undoItem 1 #define cutItem 3 #define copyItem 4 #define pasteItem 5 #define clearItem 6 MenuHandle menus[editMenu + 1]; main() { struct QDVar QDVar; EventRecord event; WindowPtr window; Rect dragRect; QD = &QDVar; InitGraf(&thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); dragRect = QD->screenBits.bounds; menus[appleMenu] = NewMenu(appleMenu, "\24"); AddResMenu(menus[appleMenu], "DRVR"); InsertMenu(menus[appleMenu], 0); menus[fileMenu] = NewMenu(fileMenu, "File"); AppendMenu(menus[fileMenu], "Close"); AppendMenu(menus[fileMenu], "Install"); AppendMenu(menus[fileMenu], "Quit"); InsertMenu(menus[fileMenu], 0); menus[editMenu] = NewMenu(editMenu, "Edit"); AppendMenu(menus[editMenu], "Undo/Z"); AppendMenu(menus[editMenu], "(-"); AppendMenu(menus[editMenu], "Cut/X"); AppendMenu(menus[editMenu], "Copy/C"); AppendMenu(menus[editMenu], "Paste/V"); AppendMenu(menus[editMenu], "Clear/B"); InsertMenu(menus[editMenu], 0); DrawMenuBar(); SetCursor(&QD->arrow); while (TRUE) { SystemTask(); if (FrontWindow()) DisableItem(menus[fileMenu], installItem); else EnableItem(menus[fileMenu], installItem); if (!GetNextEvent(everyEvent, &event)) continue; switch (event.what) { case mouseDown: switch (FindWindow(&event.where, &window)) { case inMenuBar: SetCursor(&QD->arrow); commandEvent(MenuSelect(&event.where)); HiliteMenu(0); break; case inSysWindow: SystemClick(&event, window); break; case inDrag: DragWindow(window, &event.where, &dragRect); break; case inGoAway: if (TrackGoAway(window, &event.where)) commandEvent((fileMenu << 16) | closeItem); break; case inContent: if (window != FrontWindow()) SelectWindow(window); break; } break; case keyDown: case autoKey: if (event.modifiers & cmdKey) { commandEvent(MenuKey(event.message & 0xff)); HiliteMenu(0); } break; } } } commandEvent(menuItem) { WindowPtr window; int menu; int item; char name[64]; char *c2pnstr(); window = FrontWindow(); SetPort(window); menu = HiWord(menuItem); item = LoWord(menuItem); switch (menu) { case appleMenu: GetItem(menus[appleMenu], item, name); OpenDeskAcc(c2pnstr(name)); break; case fileMenu: switch (item) { case closeItem: CloseDeskAcc(((WindowPeek) window)->windowKind); break; case installItem: install(); break; case quitItem: ExitToShell(); break; } break; case editMenu: switch (item) { case undoItem: SystemEdit(undoCmd); break; case cutItem: SystemEdit(cutCmd); break; case copyItem: SystemEdit(copyCmd); break; case pasteItem: SystemEdit(pasteCmd); break; case clearItem: SystemEdit(clearCmd); break; } break; } } /* install local drivers as system drivers */ install() { int i; int j; int k; int rsrc; Handle oldHandle; Handle handle; Handle drivers[16]; ResType type; int id; int newId; int oldId; int attrs; char name[256]; j = CountResources("DRVR"); k = 0; rsrc = CurResFile(); SetResLoad(FALSE); for (i = 1; i <= j; i++) { handle = GetIndResource("DRVR", i); if (handle) { ReleaseResource(handle); handle = GetIndResource("DRVR", i); } if (handle && HomeResFile(handle) == rsrc) drivers[++k] = handle; } SetResLoad(TRUE); for (i = 1; i <= k; i++) { UseResFile(rsrc); LoadResource(drivers[i]); handle = NewHandle(GetHandleSize(drivers[i])); if (!MemError()) { BlockMove(*drivers[i], *handle, GetHandleSize(handle)); GetResInfo(drivers[i], &id, type.s, name); attrs = GetResAttrs(drivers[i]); ReleaseResource(drivers[i]); UseResFile(0); if (oldHandle = GetNamedResource("DRVR", name)) { GetResInfo(oldHandle, &oldId, type.s, name); UseResFile(rsrc); if (installAlert(name, "DRVR", oldId) == 2) continue; UseResFile(0); RmveResource(oldHandle); DisposHandle(oldHandle); id = oldId; } else { SetResLoad(FALSE); newId = minID; while (newId <= maxID && (oldHandle = GetResource("DRVR", newId))) { ReleaseResource(oldHandle); newId++; } SetResLoad(TRUE); id = (newId <= maxID) ? newId : id; if (oldHandle = GetResource("DRVR", id)) { UseResFile(rsrc); if (installAlert(name, "DRVR", id) == 2) continue; UseResFile(0); RmveResource(oldHandle); DisposHandle(oldHandle); } } AddResource(handle, "DRVR", id, name); if (!ResError()) { WriteResource(handle); SetResAttrs(handle, attrs); } } else ReleaseResource(drivers[i]); } UpdateResFile(0); UseResFile(rsrc); } /* install alert */ installAlert(name, type, id) char *name; char *type; int id; { char idstring[16]; NumToString(id, idstring); ParamText(name, type, idstring, ""); return CautionAlert(256, (ProcPtr) NIL); } /* convert a C string to a Pascal string with a leading NUL character */ char *c2pnstr(s) char *s; { extern char *isapstr(); char *t; int i; int j; i = 0; while (*s++) i++; j = i; t = s - 2; while (j--) *s-- = *t--; *s-- = 0; *s = (char) i + 1; return(isapstr(s)); } {~}{~} echo x - print.c cat > print.c << '{~}{~}' /* * Print desk accessory * * (C) Copyright 1984 Michael Schuster * All Rights Reserved * */ /* * 08/21/84 Schuster Created */ #include "quickdraw.h" #include "osintf.h" #include "toolintf.h" #include "packintf.h" #include "device.h" #define NIL 0 #define FALSE 0 #define TRUE 1 #define pageLen 62 #define topOfForm pChar('\014') #define topSpace pChar('\n'); pChar('\n') typedef struct { int volumn; /* file volumn */ char name[64]; /* file name */ } File; #define queueLen 8 File queue[queueLen]; /* file queue */ int indent; /* indentation counter for tab handler */ int lines; /* line counter for top of form handler */ #define bufferLen 64 char buffer[bufferLen]; /* io buffer */ int port; /* printer port ID */ int file; /* file ID */ int open; /* TRUE if file open */ int inSFGetFile; /* TRUE if SFGetFile dialog active */ /* * file routines */ /* * put a file into the queue */ putFile(name, length, volumn) char *name; { register int i; for (i = 0; i < queueLen; i++) { if (!*queue[i].name) { BlockMove(name, queue[i].name, length); queue[i].name[length] = '\0'; queue[i].volumn = volumn; return; } } } /* * get a file from the queue, if any */ getFile() { register int i; if (open) return TRUE; else { for (i = 0; i < queueLen; i++) { if (*queue[i].name) { open = (FSOpen(queue[i].name, queue[i].volumn, &file)) ? FALSE : TRUE; if (open) { pChar('\033'); /* software reset */ pChar('c'); topSpace; } *queue[i].name = 0; lines = indent = 0; return open; } } return FALSE; } } /* * close the open file and optionally purge all files from the queue */ closeFile(purge) { register int i; if (open) { topOfForm; FSClose(file); } open = FALSE; if (purge) for (i = 0; i < queueLen; i++) *queue[i].name = 0; } /* * driver routines */ /* * driver open routine */ drvrOpen(pb, dce) CntrlParam *pb; struct dce *dce; { Point point; SFReply sfReply; SFTypeList sfTypeList; FSOpen(".BOut", 0, &port); SetPt(&point, 50, 50); inSFGetFile = TRUE; BlockMove("TEXT", sfTypeList.ftype[0].s, 4); SFGetFile(&point,"",(ProcPtr)NIL,1,(Ptr)&sfTypeList,(ProcPtr)NIL,&sfReply); inSFGetFile = FALSE; if (sfReply.good) putFile(&sfReply.fName[1], sfReply.fName[0], sfReply.vRefNum); return(IOrts); } /* * driver close routine */ drvrClose(pb, dce) CntrlParam *pb; struct dce *dce; { closeFile(FALSE); return(IOrts); } /* * driver control routine */ drvrCtl(pb, dce) CntrlParam *pb; struct dce *dce; { int chars; switch (pb->CSCode) { case accRun: if (inSFGetFile) ; else if (getFile() && !portHeldUp()) { chars = bufferLen; FSRead(file, &chars, buffer); if (chars) pText(chars, buffer); else closeFile(FALSE); } else ; /* CloseDeskAcc(dce->dCtlRefNum); */ break; } return(IOrts); } /* * return TRUE if port held up */ portHeldUp() { OpParamType param; Status(port, 8, ¶m); return param.ASStaRec.CTSHold; } /* * write char to port */ pChar(c) char c; { int chars; chars = 1; FSWrite(port, &chars, &c); } /* * write text to port */ pText(chars, buffer) char *buffer; { register char *b; register char *p; register char *e; b = p = e = buffer; e += chars; while (p < e) { if (*p == '\r') { *p++ = '\n'; indent = 0; lines++; if (!(lines % pageLen)) { chars = p - b; FSWrite(port, &chars, b); b = p; topOfForm; topSpace; } } else if (*p == '\t') { chars = p - b; FSWrite(port, &chars, b); b = ++p; chars = 8 - (indent % 8); FSWrite(port, &chars, " "); indent += chars; } else if (*p < '\040' || *p > '\176') { *p++ = ' '; indent++; } else { p++; indent++; } } chars = p - b; FSWrite(port, &chars, b); } /* * driver status routine */ drvrStatus(pb, dce) CntrlParam *pb; struct dce *dce; { return(IOrts); } /* * driver prime routine */ drvrPrime(pb, dce) CntrlParam *pb; struct dce *dce; { return(IOrts); } {~}{~} echo x - crtprint.s cat > crtprint.s << '{~}{~}' | | crtterm.s - self relocating C runtime startoff for Mac desk accessory | | Copyright (C) 1984, Stanford Univ. SUMEX project | May be used but not sold without permission. | | history | 07/20/84 Croft Created. | 08/21/84 Schuster Customize for Print. | .data .text .globl _savea5 .globl drvr .globl drvrOpen,drvrPrime,drvrCtl,drvrStatus,drvrClose | driver header drvr: .word 0x2400 | enable control, need time .word 60 | every second .word 0 | no events .word 0 | no menu doffset: .word reloc-drvr | replaced by "dopen-drvr" after initialization .word dprime-drvr .word dctl-drvr .word dstatus-drvr .word dclose-drvr .byte 6 .byte 0 .ascii "Print" .blkb 25 | 32 bytes total for name reloc: jra .L21 .long 0,0,0,0,0,0,0,0,0,0 | longruns from rmaker _savea5:.long 0 | | a1 = next longrun address | a2 = current reloc address | d1 = relocation factor | .L21: moveml #0xffff,sp@- lea pc@([drvr-.-2]),a1 | reloc factor movl a1,d1 lea pc@([reloc+2-.-2]),a1 movl a1@+,a2 | pickup 1st relocation addl d1,a2 .L16: | for(;;) { | i = *a2; | *a2 = 0; | *(u_long *)a2 += (u_long)d1; | if (i == 0377) | goto start; | if (i == 0) { | a2 = *a1++; | a2 += d1; | continue; | } | a2 += (i << 1); | } movb a2@,d7 andl #255,d7 clrb a2@ addl d1,a2@ cmpl #255,d7 beqs .L18 tstl d7 bnes .L19 movl a1@+,a2 addl d1,a2 bras .L16 .L19: roll #1,d7 addl d7,a2 bras .L16 | | if shift button is pressed on entry, beep and hang around for an NMI. | .L18: btst #0,0x17b beqs .L31 | if not pressed movw #1,sp@- | sysbeep, duration 1 .word /A9C8 moveq #1,d0 .L22: tstl d0 bnes .L22 | hang, waiting for NMI .L31: movl a5,_savea5 movw doff2,doffset | above code is once-only moveml sp@+,#0xffff | | driver entry points | dopen: movl #drvrOpen,d0 bras call dclose: movl #drvrClose,d0 bras call dctl: movl #drvrCtl,d0 bras call dstatus: movl #drvrStatus,d0 bras call dprime: movl #drvrPrime,d0 call: moveml #0x3ffc,sp@- movl a1,sp@- movl a0,sp@- movl d0,a0 jsr a0@ addql #8,sp moveml sp@+,#0x3ffc cmpl #0x40000000,d0 bnes done clrl d0 rts jiodone = 0x8fc done: movl jiodone,sp@- rts doff2: .word dopen-drvr {~}{~} echo x - desk.rc cat > desk.rc << '{~}{~}' desk.rsrc Type ALRT ,256(32) 60 81 180 431 256 5555 Type DITL ,256(32) 3 BtnItem Enabled 90 10 110 80 OK BtnItem Enabled 90 270 110 340 Cancel StatText Disabled 10 60 70 350 Replace system resource ^0 type=^1 id=^2? Type DRVR print|Print,30(48) Type CODE desk,0 {~}{~} echo x - Makefile cat > Makefile << '{~}{~}' .SUFFIXES: .rsrc .b .ln .s .c BIN=/usr1/mac/bin/ INCLUDE=/usr1/mac/include CFILES = desk.c print.c SFILES = crtprint.s .c.b: $(BIN)cc68 -I$(INCLUDE) -c $< .c.s: $(BIN)cc68 -I$(INCLUDE) -S $< .s.b: $(BIN)cc68 -c $< .c.ln: $(BIN)lint -I$(INCLUDE) -lmac $< > $*.ln print: print.b crtprint.b $(BIN)ld68 -X -r -d -e drvr -T 0 crtprint.b print.b -lmac -lc -x -o print desk: desk.b $(BIN)cc68 -m desk.b -o desk desk.rsrc: print desk desk.rc $(BIN)rmaker desk.rc all: desk.rsrc put: desk.rsrc $(BIN)macput -o -r desk lint: print.ln desk.ln desk.shar: $(CFILES) $(SFILES) desk.rc Makefile csh shar desk.shar $(CFILES) $(SFILES) desk.rc Makefile clean: rm -f *.b *.rsrc print desk {~}{~} -- <*> Fred Hirsch <*> AT&T Bell Laboratories <*> ihnp4!bentley!fjh <*>