home *** CD-ROM | disk | FTP | other *** search
- /*
- * startup code for preferences programs.
- *
- * Copyright (c) 1991, Mike Meyer
- * All Rights Reserved
- *
- * See the file "ShadowMaster:Distribution" for information on distribution.
- *
- * ===build instructions
- * % lc prefs ; output= prefs.o input= prefs.c
- * ===endbuild
- */
-
- #include <dos.h>
- #include <string.h>
-
- #include <exec/types.h>
- #include <exec/execbase.h>
- #include <utility/tagitem.h>
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <intuition/intuition.h>
- #include <graphics/gfx.h>
- #include <libraries/gadtools.h>
- #include <libraries/asl.h>
- #include <workbench/startup.h>
- #include <workbench/workbench.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/gadtools.h>
- #include <proto/asl.h>
- #include <proto/icon.h>
- #include <clib/alib_stdio_protos.h>
-
- /* User supplied values */
- extern int windowheight ; /* Height to open the window to */
- extern int windowwidth ; /* Width to open the window to */
- extern char *basename ; /* env:basename/appname.prefs */
- extern char *appname ; /* is the default prefs file */
- extern char *errname ; /* error reports look like errname: text */
-
- /* User functions */
- extern int SaveFile(char *) ; /* Save current preferences to named file */
- extern int LoadFile(char *) ; /* Load preferences from named file */
- extern int Undo(void) ; /* Undo last action */
- extern int Defaults(void) ; /* Reset to defaults */
- extern int UserGadgets(struct Gadget *, /* Add user gadgets to window */
- struct NewGadget *) ;
- extern void CleanUp(int) ; /* Cleans up before exit */
-
- /* My functions, supplied here */
- static int OpenFile(void) ;
- static int SaveAs(void) ;
- static int Quit(void) ;
- static int gQuit(struct Gadget *, UWORD) ;
- static int LastSaved(void) ;
- static int Icons(void) ;
- static int Use(struct Gadget *, UWORD) ;
- static int Save(struct Gadget *, UWORD) ;
- static int Restore(void) ;
- static void SaveIcon(char *) ;
- void dowbmessage(char *) ;
-
- /* Static data for the world */
- static int icons = TRUE ; /* Create icons on save? */
- static char save[FMSIZE] ; /* envarc: file name */
- static char use[FMSIZE] ; /* env: file name */
- static char *edit ; /* File we were invoked on */
- struct Window *window = NULL ; /* So I can set the wait pointer for it */
-
- /* Library bases we allow the user to access */
- struct ExecBase *SysBase = NULL ;
- struct DosLibrary *DOSBase = NULL ;
- struct IntuitionBase *IntuitionBase = NULL ;
- struct GfxBase *GfxBase = NULL ;
- struct Library *GadToolsBase = NULL ;
- struct Library *AslBase = NULL ;
- struct Library *IconBase = NULL ;
-
- /* Initialization data */
- static struct TextAttr topaz_8 = { "topaz.font", 8, 0, 0 } ;/* Blame this on GadTools */
-
- static struct NewMenu pref_menu[] = {
- { NM_TITLE, "Project", 0, 0, 0, 0},
- { NM_ITEM, "Open...", "O", 0, 0, (APTR) &OpenFile},
- { NM_ITEM, "Save As...", "A", 0, 0, (APTR) &SaveAs},
- { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0},
- { NM_ITEM, "Quit", "Q", 0, 0, (APTR) &Quit},
-
- { NM_TITLE, "Edit", 0, 0, 0, 0},
- { NM_ITEM, "Reset to Default", "D", 0, 0, (APTR) &Defaults},
- { NM_ITEM, "Last Saved", "L", 0, 0, (APTR) &LastSaved},
- { NM_ITEM, "Restore", "R", 0, 0, (APTR) &Restore},
- { NM_ITEM, "Undo", "U", 0, 0, (APTR) &Undo},
-
- { NM_TITLE, "Options", 0, 0, 0, 0},
- { NM_ITEM, "Create Icons?", 0, CHECKIT|MENUTOGGLE|CHECKED, 0,
- (APTR) &Icons},
- { NM_END, 0, 0, 0, 0, 0}
- } ;
-
- #define TEMPLATE "FROM,EDIT/S,USE/S,SAVE/S,PUBSCREEN/K"
- static enum {FROM_POS, EDIT_POS, USE_POS, SAVE_POS, SCREEN_POS} ;
-
- #define done(x, m) do {mess = m; status = x; goto out; } while (0)
- static int __saveds
- start(void) {
- int status = RETURN_OK, (*menufunc)(void),
- (*gadfunc)(struct Gadget *, UWORD), i,
- action_use = FALSE, action_save = FALSE ;
- char *mess = NULL, *tool ;
- long opts[5] = {&use[0], 1, 0, 0, 0} ;
- WORD iconic[] = {0, 0, 200, 11} ;
- BPTR olddir = NULL ;
- struct Menu *menu = NULL ;
- struct MenuItem *menuitem = NULL ;
- USHORT menunumber ;
- struct Screen *pubsc = NULL ;
- struct RDArgs *args = NULL ;
- struct TextFont *font = NULL ;
- struct IntuiMessage *bounce, in ;
- struct Gadget *gadget_crap = NULL, *gadtools_turd, *ingad ;
- struct NewGadget no_good ;
- struct WBStartup *wbmessage = NULL ;
- struct WBArg *wbargs ;
- struct DiskObject *my_icon ;
-
- /* Open the libraries */
- SysBase = *((struct ExecBase **) 4);
- if (!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
- done(RETURN_FAIL, "You need 2.04 or later") ;
- if (!(IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library", 37)))
- done(RETURN_FAIL, "Can't open intuition.library") ;
- if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 37)))
- done(RETURN_FAIL, "Can't open graphics.library") ;
- if (!(GadToolsBase = OpenLibrary("gadtools.library", 37)))
- done(RETURN_FAIL, "Can't open gadtools.library") ;
- if (!(AslBase = OpenLibrary("asl.library", 37)))
- done(RETURN_FAIL, "Can't open asl.library") ;
- if (!(IconBase = OpenLibrary("icon.library", 37)))
- done(RETURN_FAIL, "Can't open icon.library") ;
-
- /* Make file names that we edit */
- sprintf(save, "envarc:%s/%s.prefs", basename, appname) ;
- sprintf(use, "env:%s/%s.prefs", basename, appname) ;
-
- /* Argument processing, if needed */
- if (((struct Process *) SysBase->ThisTask)->pr_CLI) { /* do CLI args */
- if (!(args = ReadArgs(TEMPLATE, opts, NULL)))
- done(RETURN_ERROR, "Invalid arguments") ;
- edit = (char *) opts[FROM_POS] ;
- action_use = opts[USE_POS] ;
- action_save = opts[SAVE_POS] ;
- }
- else { /* Do WB args */
- edit = use ; /* To make sure we have *something* */
- WaitPort(&((struct Process *) SysBase->ThisTask)->pr_MsgPort) ;
- wbmessage = (struct WBStartup *)
- GetMsg(&((struct Process *) SysBase->ThisTask)->pr_MsgPort) ;
- wbargs = wbmessage->sm_ArgList ;
- i = wbmessage->sm_NumArgs ;
- olddir = CurrentDir(wbargs->wa_Lock) ;
- while (i-- > 0) {
- CurrentDir(wbargs->wa_Lock) ;
- if (my_icon = GetDiskObjectNew(wbargs->wa_Name)) {
- if (my_icon->do_Type == WBPROJECT)
- edit = wbargs->wa_Name ;
- if (tool = FindToolType(my_icon->do_ToolTypes, "ACTION"))
- if (!stricmp(tool, "use")) {
- action_use = TRUE ;
- i = 0 ;
- }
- else if (!stricmp(tool, "save")) {
- action_save = TRUE ;
- i = 0 ;
- }
- else if (!stricmp(tool, "edit")) i = 0 ;
- FreeDiskObject(my_icon) ;
- }
- wbargs += 1 ;
- }
- }
-
- /* Load up file we want to work on, and run it */
- if (!LoadFile(edit)) Defaults() ;
- if (action_save) {
- Save(NULL, 0) ;
- done(RETURN_OK, NULL) ;
- }
- if (action_use) {
- Use(NULL, 0) ;
- done(RETURN_OK, NULL) ;
- }
-
- /* Otherwise, we're editing, so open the bloody window... */
-
- if (!(pubsc = LockPubScreen((char *) opts[SCREEN_POS])))
- done(RETURN_ERROR, "Can't lock requested public screen") ;
- if (!(no_good.ng_VisualInfo = GetVisualInfoA(pubsc, NULL)))
- done(RETURN_FAIL, "internal error: VISINFO") ;
- if (!(font = OpenFont(&topaz_8)))
- done(RETURN_FAIL, "Can't open topaz font") ;
- if (!(menu = CreateMenusA(pref_menu, NULL)))
- done(RETURN_FAIL, "Internal error: MENUS") ;
- if (!LayoutMenusA(menu, no_good.ng_VisualInfo, NULL))
- done(RETURN_FAIL, "Internal error: LAYOUT") ;
-
- /* Set up the unchanging no good gadget stuff */
- if (!(gadtools_turd = CreateContext(&gadget_crap)))
- done(RETURN_FAIL, "Internal error: CONTEXT") ;
- no_good.ng_TextAttr = &topaz_8 ;
- no_good.ng_Flags = no_good.ng_GadgetID = 0 ;
- no_good.ng_Height = 12 ;
- no_good.ng_Width = 67 ;
- no_good.ng_TopEdge = pubsc->WBorTop + pubsc->Font->ta_YSize + windowheight - 13 ;
-
- /* standard cancel gadget */
- no_good.ng_LeftEdge = windowwidth - 87 ;
- no_good.ng_GadgetText = "Cancel" ;
- no_good.ng_UserData = (APTR) &gQuit ;
- if (!(gadtools_turd = CreateGadgetA(BUTTON_KIND, gadtools_turd, &no_good, NULL)))
- done(RETURN_FAIL, "internal error: CANCEL") ;
-
- /* standard use gadget */
- no_good.ng_LeftEdge = (windowwidth - no_good.ng_Width) / 2 ;
- no_good.ng_GadgetText = "Use" ;
- no_good.ng_UserData = (APTR) &Use ;
- if (!(gadtools_turd = CreateGadgetA(BUTTON_KIND, gadtools_turd, &no_good, NULL)))
- done(RETURN_FAIL, "internal error: USE") ;
-
- /* standard save gadget */
- no_good.ng_LeftEdge = 13 ;
- no_good.ng_GadgetText = "Save" ;
- no_good.ng_UserData = (APTR) &Save ;
- if (!(gadtools_turd = CreateGadgetA(BUTTON_KIND, gadtools_turd, &no_good, NULL)))
- done(RETURN_FAIL, "internal error: SAVE") ;
-
- /* The users gadgets (if any) */
- if (!UserGadgets(gadtools_turd, &no_good))
- done(RETURN_FAIL, "internal error: GADGETS") ;
-
- if (!(window = OpenWindowTags(NULL,
- WA_Left, 0, WA_InnerWidth, windowwidth,
- WA_Top, 11, WA_InnerHeight, windowheight, WA_AutoAdjust, 1,
- WA_Title, "ScreenSaver Preferences",
- WA_DragBar, 1, WA_Zoom, iconic, WA_DepthGadget, 1,
- WA_Gadgets, gadget_crap,
- WA_IDCMP, LISTVIEWIDCMP|IDCMP_MENUPICK,
- WA_PubScreen, pubsc, WA_PubScreenFallBack, 1,
- TAG_DONE, 0)))
- done(RETURN_FAIL, "Can't open window") ;
-
- SetMenuStrip(window, menu) ;
- GT_RefreshWindow(window, NULL) ;
-
- FOREVER {
- WaitPort(window->UserPort) ;
- while (bounce = GT_GetIMsg(window->UserPort)) {
- in = *bounce ;
- GT_ReplyIMsg(bounce) ;
- switch (in.Class) {
- case IDCMP_GADGETUP:
- ingad = (struct Gadget *) in.IAddress ;
- gadfunc = (int (*)()) ingad->UserData ;
- if (gadfunc(ingad, in.Code))
- done(RETURN_OK, NULL) ;
- break ;
- case IDCMP_MENUPICK:
- menunumber = in.Code ;
- while (menunumber != MENUNULL) {
- menuitem = ItemAddress(menu, menunumber) ;
- menufunc = (int (*)()) GTMENUITEM_USERDATA(menuitem) ;
- if (menufunc()) done(RETURN_OK, NULL) ;
- menunumber = menuitem->NextSelect ;
- }
- break ;
-
- case IDCMP_REFRESHWINDOW:
- GT_BeginRefresh(window);
- GT_EndRefresh(window, TRUE);
- break ;
- }
- }
- }
-
- out:
- if (mess && DOSBase) {
- if (wbmessage && IntuitionBase) dowbmessage(mess) ;
- else {
- PutStr(errname) ;
- PutStr(": ") ;
- PutStr(mess) ;
- PutStr("\n") ;
- }
- }
-
- if (window) {
- ClearMenuStrip(window) ;
- CloseWindow(window) ;
- }
- if (gadget_crap) FreeGadgets(gadget_crap) ;
- if (pubsc) UnlockPubScreen(NULL, pubsc) ;
- if (no_good.ng_VisualInfo) FreeVisualInfo(no_good.ng_VisualInfo) ;
- if (font) CloseFont(font) ;
- if (menu) FreeMenus(menu) ;
- if (args) FreeArgs(args) ;
- if (olddir) CurrentDir(olddir) ;
- if (IconBase) CloseLibrary(IconBase) ;
- if (AslBase) CloseLibrary(AslBase) ;
- if (GfxBase) CloseLibrary((struct Library *) GfxBase) ;
- if (GadToolsBase) CloseLibrary(GadToolsBase) ;
- if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase) ;
- if (wbmessage) {
- Forbid() ;
- ReplyMsg((struct Message *) wbmessage) ;
- }
- if (DOSBase) CloseLibrary((struct Library *) DOSBase) ;
- return status ;
- }
-
- /* The functions that actually *do* things */
- /* Note: an exit that *doesn't* change env:... must go through here */
- static int
- Quit(void) {
- CleanUp(FALSE) ;
- return 1 ;
- }
- static int gQuit(struct Gadget *g, UWORD code) { return Quit(); }
-
- static int
- LastSaved(void) {
- if (!LoadFile(save)) dowbmessage("Could not load saved file") ;
- return 0 ;
- }
-
- static int
- Icons(void) {
- icons = !icons ; /* Tacky, but so is the menu facility */
- return 0 ;
- }
-
- /* Note: an exit that changes env:... must go through herre! */
- static int
- Use(struct Gadget *g, UWORD code) {
- if (!SaveFile(use)) {
- dowbmessage("Could not save file in env:") ;
- return 0 ;
- }
- CleanUp(TRUE) ;
- return 1 ;
- }
-
- static int
- Save(struct Gadget *g, UWORD code) {
- if (!SaveFile(save)) {
- dowbmessage("Could not save file in envarc:") ;
- return 0 ;
- }
- return Use(g, code) ;
- }
-
- static int
- Restore(void) {
- if (!LoadFile(edit)) dowbmessage("Could not reload file") ;
- return 0 ;
- }
-
- /* 2.0 Busy Pointer data From of Steve Tibbett's PointerX */
- USHORT __chip BusyPointerData[] = {
- 0x0000,0x0000,
- 0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
- 0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
- 0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
- 0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
- 0x0000,0x0000,
- } ;
-
- static char *
- GetFileName(char *prompt, int flags) {
- struct FileRequester *my_req = NULL ;
- char filename[FNSIZE], hail[FMSIZE], *out = NULL ;
- static char dirname[FMSIZE] ;
-
- sprintf(filename, "%s.prefs", appname) ;
- sprintf(dirname, "envarc:%s", basename) ;
- sprintf(hail, "%s %s preferences", prompt, appname) ;
-
- if (!(my_req = AllocAslRequestTags(ASL_FileRequest,
- ASL_TopEdge, 11, ASL_LeftEdge, 0, ASL_Window, window,
- ASL_Dir, dirname, ASL_File, filename, ASL_FuncFlags, flags,
- ASL_Hail, hail, TAG_DONE, 0)))
- return NULL ;
-
- SetPointer(window, BusyPointerData, 16, 16, -6, 0) ;
- if (RequestFile(my_req)) {
- strcpy(dirname, my_req->rf_Dir) ;
- AddPart(dirname, my_req->rf_File, FMSIZE) ;
- out = dirname ;
- }
- ClearPointer(window) ;
- FreeAslRequest(my_req) ;
-
- return out ;
- }
-
- static int
- SaveAs(void) {
- struct DiskObject *deficon ;
- char defname[FMSIZE] ;
- char *file = GetFileName("Save", FILF_SAVE) ;
-
- if (!file) return 0 ;
- if (!SaveFile(file)) dowbmessage("Could not open file") ;
- else if (icons) {
- sprintf(defname, "env:%s/%s", basename, appname) ;
- /* If there is no default icon, we don't create them */
- if (deficon = GetDiskObjectNew(defname)) {
- PutDiskObject(file, deficon) ;
- FreeDiskObject(deficon) ;
- }
- }
- return 0 ;
- }
-
- static int
- OpenFile(void) {
- char *file = GetFileName("Load", 0) ;
- if (!file) return 0 ;
- if (!LoadFile(file)) dowbmessage("Could not open file") ;
- return 0 ;
- }
-
- void
- dowbmessage(char *message) {
- struct EasyStruct req ;
-
- req.es_StructSize = sizeof(req) ;
- req.es_Flags = 0 ;
- req.es_Title = errname ;
- req.es_TextFormat = message ;
- req.es_GadgetFormat = "Okay" ;
- EasyRequestArgs(window, &req, NULL, NULL) ;
- }
-