home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d597
/
shadowmaster.lha
/
ShadowMaster
/
source
/
config
/
prefs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-01
|
14KB
|
447 lines
/*
* 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) ;
}