/* * Prefs programming for setting up Shadow Master. Uses prefs.o as for * startup code. * * Copyright (c) 1991, Mike Meyer * All Rights Reserved * * See the file "ShadowMaster:Distribution" for information on distribution. * * ===build instructions * % lc guard ; output= guard.o input= guard.c * % build prefs.c ; output= prefs.o input= prefs.c * % blink prefs.o+guard.o lib lib:amiga.lib+lib:lcr.lib to guard SC SD ; output= guard input= guard.o prefs.o * % copy guard //config * ===endbuild */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Values for feed to prefs.o */ int windowheight = 82 ; /* Height to open the window to */ int windowwidth = 350 ; /* Width to open the window to */ char *basename = "shadowmaster" ; /* env:basename/appname.prefs */ char *appname = "guard" ; /* is the default prefs file */ char *errname = "guard" ; /* error reports look like errname: text */ /* Values I get from prefs.o, either NULL or open */ extern struct Window *window ; extern USHORT __far BusyPointerData[] ; extern void dowbmessage(char *) ; /* Flags indicating which corners are guarded */ #define TOP_LEFT 1 #define TOP_RIGHT 2 #define BOTTOM_LEFT 4 #define BOTTOM_RIGHT 8 /* The two values I write to the preferences file, plus values for undo */ #define MAXSTRING 200 static int size = 5, old_size = 5, corners = TOP_LEFT, old_corners = TOP_LEFT ; static char command[MAXSTRING], old_command[MAXSTRING] = "" ; /* Things I need to save my state */ static struct Gadget *gad_size, *gad_command, *gad_topleft, *gad_topright, *gad_bottomleft, *gad_bottomright ; static int undo_size = FALSE, undo_command = FALSE, undo_corners = FALSE ; struct RxsLib *RexxSysBase = NULL ; #define UPDATE_SIZE(value) do { old_size = size; size = value; \ undo_size = TRUE; if (window) GT_SetGadgetAttrs(gad_size, window, \ NULL, GTIN_Number, size, TAG_DONE, 0); } while (0) #define UPDATE_CORNERS(value) do { old_corners = corners; corners = value; \ undo_corners = TRUE; if (window) { \ GT_SetGadgetAttrs(gad_topleft, window, NULL, GTCB_Checked, corners & TOP_LEFT, TAG_DONE, 0); \ GT_SetGadgetAttrs(gad_topright, window, NULL, GTCB_Checked, corners & TOP_RIGHT, TAG_DONE, 0); \ GT_SetGadgetAttrs(gad_bottomleft, window, NULL, GTCB_Checked, corners & BOTTOM_LEFT, TAG_DONE, 0); \ GT_SetGadgetAttrs(gad_bottomright, window, NULL, GTCB_Checked, corners & BOTTOM_RIGHT, TAG_DONE, 0); \ } } while (0) #define UPDATE_COMMAND(value) do { strcpy(old_command, command); \ strcpy(command, value); undo_command = TRUE; if (window) \ GT_SetGadgetAttrs(gad_command, window, NULL, GTST_String, \ command, TAG_DONE, 0); } while(0) int LoadFile(char *) ; /* Functions that do the gadgets. Return TRUE to exit, FALSE otherwise */ static int select(struct Gadget *g, UWORD code) { struct FileRequester *my_req = NULL ; if (!(my_req = AllocAslRequestTags(ASL_FileRequest, ASL_TopEdge, 11, ASL_LeftEdge, 0, ASL_Window, window, ASL_Dir, "shadowmaster:savers", ASL_FrontPen, 1, ASL_BackPen, 0, ASL_Hail, "Select Module", TAG_DONE, 0))) return FALSE ; SetPointer(window, BusyPointerData, 16, 16, -6, 0) ; if (RequestFile(my_req)) { UPDATE_COMMAND(my_req->rf_File) ; undo_size = FALSE ; } ClearPointer(window) ; FreeAslRequest(my_req) ; return FALSE ; } static int config(struct Gadget *g, UWORD code) { char config[2 * MAXSTRING], tempfile[MAXSTRING] ; BPTR out ; char *cp ; /* Build strings we need to run */ sprintf(tempfile, "t:sm.%ld", FindTask(NULL)) ; if (!(out = Open(tempfile, MODE_READWRITE))) return FALSE ; strcpy(command, ((struct StringInfo *) gad_command->SpecialInfo)->Buffer) ; sprintf(config, "shadowmaster:config/%s", command) ; /* Run the command (with a busy pointer) */ SetPointer(window, BusyPointerData, 16, 16, -6, 0) ; if (SystemTags(config, SYS_Output, out, TAG_DONE, 0)) { sprintf(config, "No config available for\n%s", command) ; dowbmessage(config) ; } else { /* Check the output */ Seek(out, 0, OFFSET_BEGINNING) ; if (FGets(out, config, MAXSTRING)) { if (cp = strchr(config, '\n')) *cp = '\0' ; UPDATE_COMMAND(config) ; undo_size = FALSE ; } } /* Now clean up */ ClearPointer(window) ; Close(out) ; DeleteFile(tempfile) ; return FALSE ; } static char * RexxIt(char *com, struct MsgPort *port, int flags) { struct RexxMsg *msg ; struct MsgPort *out ; char *result = NULL ; if (!(msg = CreateRexxMsg(port, NULL, NULL))) return NULL ; msg->rm_Action = RXCOMM | flags ; msg->rm_Args[0] = com ; if (!FillRexxMsg(msg, 1, 0)) dowbmessage("Internal error: REXX") ; else { Forbid() ; if (out = FindPort("SHADOWMASTER")) PutMsg(out, (struct Message *) msg) ; Permit() ; if (!out) dowbmessage("ShadowMaster is not running!") ; else for (;;) { WaitPort(port) ; msg = (struct RexxMsg *) GetMsg(port) ; if (msg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) break ; msg->rm_Result1 = 10 ; msg->rm_Result2 = 10 ; ReplyMsg((struct Message *) msg) ; } if (msg->rm_Result1 == 0) result = (char *) msg->rm_Result2 ; ClearRexxMsg(msg, 1) ; } DeleteRexxMsg(msg) ; return result ; } static int test(struct Gadget *g, UWORD code) { struct MsgPort *myport ; char buffer[2 * MAXSTRING], *old ; if (!RexxSysBase && !(RexxSysBase = (struct RxsLib *) OpenLibrary("rexxsyslib.library", 0))) { dowbmessage("Can't open rexx.library; test not possible.") ; return FALSE ; } if (!(myport = CreateMsgPort())) { dowbmessage("Can't create rexx port; test not possible.") ; return FALSE ; } sprintf(buffer, "command shadowmaster:savers/%s", command) ; old = RexxIt(buffer, myport, RXFF_RESULT) ; if (old) { /* It worked */ RexxIt("blank", myport, 0) ; sprintf(buffer, "command %s", old) ; DeleteArgstring(old) ; RexxIt(buffer, myport, 0) ; } /* Send rexx messages to twiddle the command and blank the thing... */ DeleteMsgPort(myport) ; return FALSE ; } static int Size(struct Gadget *g, UWORD code) { UPDATE_SIZE(((struct StringInfo *) g->SpecialInfo)->LongInt) ; undo_command = FALSE ; return FALSE ; } static int Corners(struct Gadget *g, UWORD code){ UPDATE_CORNERS((g->GadgetID) ^ corners) ; return FALSE ; } static int Command(struct Gadget *g, UWORD code) { UPDATE_COMMAND(((struct StringInfo *) g->SpecialInfo)->Buffer) ; undo_size = FALSE ; return FALSE ; } /* Undos the last action */ int Undo(void) { int save_size, save_corners ; char save_command[MAXSTRING] ; if (undo_size) { save_size = old_size ; UPDATE_SIZE(save_size) ; } if (undo_command) { strcpy(save_command, old_command) ; UPDATE_COMMAND(save_command) ; } if (undo_corners) { save_corners = old_corners ; UPDATE_CORNERS(save_corners) ; } return FALSE ; } /* Resets the edit data to default values */ int Defaults(void) { UPDATE_COMMAND("black") ; UPDATE_SIZE(5) ; UPDATE_CORNERS(TOP_LEFT) ; return FALSE ; } /* Build the edit gadgets, return TRUE if all, FALSE otherwise */ int UserGadgets(struct Gadget *gad, struct NewGadget *ng) { /* Bottom row: select */ ng->ng_TopEdge -= ng->ng_Height + 10 ; ng->ng_LeftEdge = 13 ; ng->ng_GadgetText = "Select" ; ng->ng_UserData = &select ; if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL))) return FALSE ; /* Bottom row: config */ ng->ng_LeftEdge = (windowwidth - ng->ng_Width) / 2 ; ng->ng_GadgetText = "Config" ; ng->ng_UserData = &config ; if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL))) return FALSE ; /* Bottom row: test */ ng->ng_LeftEdge = windowwidth - 87 ; ng->ng_GadgetText = "Test" ; ng->ng_UserData = &test ; if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL))) return FALSE ; /* Middle row: Command gadget */ ng->ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT ; ng->ng_TopEdge -= ng->ng_Height + 3 ; ng->ng_LeftEdge = 80 ; ng->ng_Width = windowwidth - 100 ; ng->ng_GadgetText = "Command" ; ng->ng_UserData = &Command ; if (!(gad_command = gad = CreateGadget(STRING_KIND, gad, ng, GTST_String, command, GTST_MaxChars, MAXSTRING - 1, TAG_DONE, 0))) return FALSE ; /* Top row: size gadget */ ng->ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT ; ng->ng_TopEdge -= (ng->ng_Height / 2) + 15 ; ng->ng_LeftEdge = 120 ; ng->ng_GadgetText = "Size" ; ng->ng_UserData = &Size ; ng->ng_Width = 67 ; if (!(gad_size = gad = CreateGadget(INTEGER_KIND, gad, ng, GTIN_Number, size, TAG_DONE, 0))) return FALSE ; /* Top row: corner gadgets */ ng->ng_TopEdge -= (ng->ng_Height / 2) ; ng->ng_Flags = 0 ; ng->ng_Width = 5 ; ng->ng_Height = 5 ; ng->ng_GadgetText = "" ; ng->ng_UserData = &Corners ; ng->ng_LeftEdge = 13 ; ng->ng_GadgetID = TOP_LEFT ; if (!(gad_topleft = gad = CreateGadget(CHECKBOX_KIND, gad, ng, GTCB_Checked, corners & TOP_LEFT, TAG_DONE, 0))) return FALSE ; ng->ng_LeftEdge = 39 ; ng->ng_GadgetID = TOP_RIGHT ; if (!(gad_topright = gad = CreateGadget(CHECKBOX_KIND, gad, ng, GTCB_Checked, corners & TOP_RIGHT, TAG_DONE, 0))) return FALSE ; ng->ng_TopEdge += 11 ; ng->ng_GadgetID = BOTTOM_RIGHT ; if (!(gad_bottomright = gad = CreateGadget(CHECKBOX_KIND, gad, ng, GTCB_Checked, corners & BOTTOM_RIGHT, TAG_DONE, 0))) return FALSE ; ng->ng_LeftEdge = 13 ; ng->ng_GadgetID = BOTTOM_LEFT ; if (!(gad_bottomleft = gad = CreateGadget(CHECKBOX_KIND, gad, ng, GTCB_Checked, corners & BOTTOM_LEFT, TAG_DONE, 0))) return FALSE ; undo_size = undo_command = undo_corners = FALSE ; return TRUE; } /* This saves the preferences data to the named file. Returns FALSE if open fails */ int SaveFile(char *file) { BPTR fh ; if (!(fh = Open(file, MODE_NEWFILE))) return FALSE ; if (window) { strcpy(command, ((struct StringInfo *) gad_command->SpecialInfo)->Buffer) ; size = ((struct StringInfo *) gad_size->SpecialInfo)->LongInt ; } FPrintf(fh, "%ld\n%ld\nshadowmaster:savers/%s\n", corners, size, command) ; Close(fh) ; return TRUE ; } /* This loads the named file into the editor. Returns FALSE if the open fails */ int LoadFile(char *file) { BPTR fh ; int tmp_corners ; char *cp, buffer[MAXSTRING] ; if (!(fh = Open(file, MODE_OLDFILE))) return FALSE ; FGets(fh, buffer, MAXSTRING) ; tmp_corners = atoi(buffer) ; UPDATE_CORNERS(tmp_corners ? tmp_corners : TOP_LEFT) ; FGets(fh, buffer, MAXSTRING) ; UPDATE_SIZE(atoi(buffer)) ; FGets(fh, buffer, MAXSTRING) ; if (cp = strchr(buffer, '\n')) *cp = '\0' ; if (cp = strchr(buffer, ':')) cp = strchr(buffer, '/') + 1 ; UPDATE_COMMAND(cp ? cp : buffer) ; Close(fh) ; return TRUE ; } /* This is for me to clean up things with; status is TRUE if we changed env:... */ void CleanUp(int status) { if (RexxSysBase) CloseLibrary((struct Library *) RexxSysBase) ; }