/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* 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) ; }