/* * TinyFinder.c - 21-Feb-85 * * This program is an alternative Finder that is very fast and small, * and limited in its abilities compared to the real Finder. It is * written in Aztec 68000 C (version 1.06D). * * copyright (c) 1985 by: * Kent Kersten * Harrison Systems * 437 Atlas Drive * Nashville, TN 37211 * (615) 834-1366 * CompuServe CIS [72277,2726] * * To compile & link this file: * cc TinyFinder.c * ln -m TinyFinder.o sys:lib/sacroot.o -lc */ #include <quickdraw.h> #include <window.h> #include <event.h> #include <menu.h> #include <desk.h> #include <dialog.h> #include <resource.h> #include <segment.h> #include <packages.h> #include <pb.h> #include <syserr.h> #include <inits.h> #define nil (long) 0 #define NUM_MENUS 4 #define AppleMenu 256 #define FileMenu 257 #define EditMenu 258 #define SpecialMenu 259 #define ABOUT_DLOG 256 /* resource id # of our 'About...' box */ #define GENERAL_ERROR_ALRT 500 MenuHandle TFMenu[NUM_MENUS]; Point whereOpen = { 80, 80 }; /* where to put the SF dialog */ Boolean DoCommand(), ProcessEvents(); main() { InitGraf(&thePort); InitFonts(); InitWindows(); InitMenus(); InitDialogs(nil); TEInit(); FlushEvents(everyEvent, 0); /* flush ALL events */ FormMenuBar(); CheckForFinder(); InitCursor(); LaunchAppl(); while(ProcessEvents()) ; } /* * Get events and process them. Return FALSE to exit. */ Boolean ProcessEvents() { char theChar; Boolean NoQuitFlag = TRUE; WindowPtr whichWindow; EventRecord TFEvent; GrafPtr savePort; HiliteMenu(0); /* turn off any highlighting in menu bar */ SystemTask(); GetNextEvent(everyEvent, &TFEvent); switch(TFEvent.what) { case mouseDown: switch(FindWindow(pass(TFEvent.where), &whichWindow)) { /* major Aztec C68K hack-ack (pass) */ case inMenuBar: NoQuitFlag = DoCommand(MenuSelect(pass(TFEvent.where))); /* Aztec hack */ break; case inSysWindow: SystemClick(&TFEvent,whichWindow); break; } break; case keyDown: case autoKey: theChar = TFEvent.message % 256; if((TFEvent.modifiers & cmdKey) != 0) /* command key pressed */ NoQuitFlag = DoCommand(MenuKey(theChar)); break; case updateEvt: GetPort(&savePort); SetPort(TFEvent.message); BeginUpdate(TFEvent.message); EndUpdate(TFEvent.message); SetPort(savePort); break; } return NoQuitFlag; } /* * Decipher menu commands here. Return FALSE to quit. */ Boolean DoCommand(command) long command; { char name[256]; short MenuNum, ItemNum; Boolean NoQuitFlag = TRUE; InitCursor(); MenuNum = HiWord(command); ItemNum = LoWord(command); switch(MenuNum) { case AppleMenu: if(ItemNum == 1) AboutTinyFinder(); /* do our "About..." box */ else { GetItem(TFMenu[0], ItemNum, name); OpenDeskAcc(name); } break; case FileMenu: switch(ItemNum) { case 1: LaunchAppl(); break; case 2: GoFinder(); break; case 4: NoQuitFlag = FALSE; break; } break; case EditMenu: switch(ItemNum) { case 1: SystemEdit(undoCmd); break; case 3: SystemEdit(cutCmd); break; case 4: SystemEdit(copyCmd); break; case 5: SystemEdit(pasteCmd); break; case 6: SystemEdit(clearCmd); break; } break; case SpecialMenu: switch(ItemNum) { case 1: ShutDown(); break; } } return NoQuitFlag; } /* * This pops up a dialog for our 'About...' box. */ AboutTinyFinder() { int type, ItemHit; Handle hdl; DialogPtr DPtr; Rect tBox; InitCursor(); DPtr = GetNewDialog(ABOUT_DLOG, nil, (long) -1); SetPort(DPtr); GetDItem(DPtr, 2, &type, &hdl, &tBox); /* icon */ PlotIcon(&tBox, GetIcon(256)); PenPat(&gray); GetDItem(DPtr, 6, &type, &hdl, &tBox); /* dividing line */ MoveTo(tBox.left, tBox.top); LineTo(tBox.right, tBox.top); GetDItem(DPtr, 7, &type, &hdl, &tBox); /* dividing line */ MoveTo(tBox.left, tBox.top); LineTo(tBox.right, tBox.top); PenPat(&black); while(1) { ModalDialog(nil, &ItemHit); if(ItemHit == 1) { CloseDialog(DPtr); /* 'OK' */ break; } } } /* * Check to see if the file named 'Finder' exists on the default volume. * If not, then disable the command in the 'File' menu that allows the user to * launch the Apple Finder. Note that this is fairly dumb, in that if it * finds ANY file named 'Finder' it thinks it is the one. Could be made * smarter by checking the type and creator bytes for the file, but I * didn't feel that I should, in case there is an application by that name. */ CheckForFinder() { Finfo fndrInfo; if(GetFInfo("\006Finder", 0, &fndrInfo) < 0) /* use default volume */ DisableItem(TFMenu[1], 2); } /* * Create our menu bar. */ FormMenuBar() { int i; TFMenu[0] = GetMenu(AppleMenu); TFMenu[1] = GetMenu(FileMenu); TFMenu[2] = GetMenu(EditMenu); TFMenu[3] = GetMenu(SpecialMenu); AddResMenu(TFMenu[0], 'DRVR'); for(i = 0;i < NUM_MENUS;++i) InsertMenu(TFMenu[i], 0); DrawMenuBar(); } /* * This alert takes care of our general error messages. We can * pass up to four Str255 types (pointers to them, that is), and * they are combined end to end with a single space between them. */ GeneralError(str1, str2, str3, str4) char *str1, *str2, *str3, *str4; /* Pascal format */ { InitCursor(); ParamText("\000", "\000", "\000", "\000"); ParamText(str1, str2, str3, str4); StopAlert(GENERAL_ERROR_ALRT, nil); } /* * Launch the Apple Finder. This command is disabled in the menu bar * if the program does not find the Finder on the default disk when * we boot up and begin execution. */ GoFinder() { long zeroes = 0; Launch("\006Finder", &zeroes); } /* * Come here when the 'Launch' menu command is given. */ LaunchAppl() { long zeroes = 0; short numTypes = 1; Ptr prompt = nil; Ptr fileFilter = nil; Handle hdl; SFReply rec; SFTypeList typeList; typeList[0] = 'APPL'; /* filter out all but 'APPL' types */ SFGetFile(pass(whereOpen), prompt, fileFilter, numTypes, typeList, nil, &rec); if(rec.good == 0) /* 'Cancel' button hit */ return; if(SetVol(nil, rec.vRefNum) < 0) { /* set the new default volume */ hdl = GetString(256); GeneralError(*hdl, nil, nil, nil); return; } Launch(rec.fName, &zeroes); } /* * This is the equivalent of Apple Finder v4.1's 'Shut Down' command, * in which the diskettes are ejected from the internal & external * drives and a system reset is issued. Any other volumes that happen * to be mounted will NOT be handled. */ ShutDown() { int vRefNum; long freeBytes; char volName[256]; GetVInfo(1, volName, &vRefNum, &freeBytes); /* internal drive */ Eject(volName, vRefNum); if(GetVInfo(2, volName, &vRefNum, &freeBytes) != ParamErr) /* external */ Eject(volName, vRefNum); /* pulse the 68000's RESET pin via a direct assembler call */ #asm Reset #endasm }