home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / screen / shdwmstr.lha / source / config / guard.c < prev    next >
C/C++ Source or Header  |  1992-01-06  |  11KB  |  385 lines

  1. /*
  2.  * Prefs programming for setting up Shadow Master. Uses prefs.o as for
  3.  * startup code.
  4.  *
  5.  * Copyright (c) 1991, Mike Meyer
  6.  * All Rights Reserved
  7.  *
  8.  * See the file "ShadowMaster:Distribution"  for information on distribution.
  9.  *
  10.  * ===build instructions
  11.  * % lc guard ; output= guard.o input= guard.c
  12.  * % build prefs.c ; output= prefs.o input= prefs.c
  13.  * % blink prefs.o+guard.o lib lib:amiga.lib+lib:lcr.lib to guard SC SD ; output= guard input= guard.o prefs.o
  14.  * % copy guard //config
  15.  * ===endbuild
  16.  */
  17.  
  18. #include <string.h>
  19. #include <stdlib.h>
  20.  
  21. #include <exec/types.h>
  22. #include <dos/dos.h>
  23. #include <dos/dostags.h>
  24. #include <intuition/intuition.h>
  25. #include <libraries/gadtools.h>
  26. #include <libraries/asl.h>
  27. #include <utility/tagitem.h>
  28. #include <rexx/rxslib.h>
  29. #include <rexx/storage.h>
  30. #include <proto/exec.h>
  31. #include <proto/dos.h>
  32. #include <proto/gadtools.h>
  33. #include <proto/asl.h>
  34. #include <proto/intuition.h>
  35. #include <proto/rexxsys.h>
  36. #include <clib/alib_stdio_protos.h>
  37.  
  38. /* Values for feed to prefs.o */
  39. int windowheight = 82 ;            /* Height to open the window to */
  40. int windowwidth = 350 ;            /* Width to open the window to */
  41. char *basename = "shadowmaster" ;    /* env:basename/appname.prefs */
  42. char *appname = "guard" ;        /* is the default prefs file */
  43. char *errname = "guard" ;        /* error reports look like errname: text */
  44.  
  45. /* Values I get from prefs.o, either NULL or open */
  46. extern struct Window *window ;
  47. extern USHORT __far BusyPointerData[] ;
  48. extern void dowbmessage(char *) ;
  49.  
  50. /* Flags indicating which corners are guarded */
  51. #define TOP_LEFT    1
  52. #define TOP_RIGHT    2
  53. #define BOTTOM_LEFT    4
  54. #define BOTTOM_RIGHT    8
  55.  
  56. /* The two values I write to the preferences file, plus values for undo */
  57. #define MAXSTRING 200
  58. static int size = 5, old_size = 5, corners = TOP_LEFT, old_corners = TOP_LEFT ;
  59. static char command[MAXSTRING], old_command[MAXSTRING] = "" ;
  60.  
  61. /* Things I need to save my state */
  62. static struct Gadget *gad_size, *gad_command, *gad_topleft, *gad_topright,
  63.     *gad_bottomleft, *gad_bottomright ;
  64. static int undo_size = FALSE, undo_command = FALSE, undo_corners = FALSE ;
  65. struct RxsLib *RexxSysBase = NULL ;
  66.  
  67. #define UPDATE_SIZE(value) do { old_size = size; size = value; \
  68.     undo_size = TRUE; if (window) GT_SetGadgetAttrs(gad_size, window, \
  69.     NULL, GTIN_Number, size, TAG_DONE, 0); } while (0)
  70. #define UPDATE_CORNERS(value) do { old_corners = corners; corners = value; \
  71.     undo_corners = TRUE; if (window) { \
  72.     GT_SetGadgetAttrs(gad_topleft, window, NULL, GTCB_Checked, corners & TOP_LEFT, TAG_DONE, 0); \
  73.     GT_SetGadgetAttrs(gad_topright, window, NULL, GTCB_Checked, corners & TOP_RIGHT, TAG_DONE, 0); \
  74.     GT_SetGadgetAttrs(gad_bottomleft, window, NULL, GTCB_Checked, corners & BOTTOM_LEFT, TAG_DONE, 0); \
  75.     GT_SetGadgetAttrs(gad_bottomright, window, NULL, GTCB_Checked, corners & BOTTOM_RIGHT, TAG_DONE, 0); \
  76.     } } while (0)
  77. #define UPDATE_COMMAND(value) do { strcpy(old_command, command); \
  78.     strcpy(command, value); undo_command = TRUE; if (window) \
  79.     GT_SetGadgetAttrs(gad_command, window, NULL, GTST_String, \
  80.     command, TAG_DONE, 0); } while(0)
  81.  
  82. int LoadFile(char *) ;
  83.  
  84. /* Functions that do the gadgets. Return TRUE to exit, FALSE otherwise */
  85. static int
  86. select(struct Gadget *g, UWORD code) {
  87.     struct FileRequester    *my_req = NULL ;
  88.  
  89.     if (!(my_req = AllocAslRequestTags(ASL_FileRequest,
  90.             ASL_TopEdge, 11, ASL_LeftEdge, 0, ASL_Window, window,
  91.             ASL_Dir, "shadowmaster:savers",
  92.             ASL_FrontPen, 1, ASL_BackPen, 0,
  93.             ASL_Hail, "Select Module", TAG_DONE, 0)))
  94.         return FALSE ;
  95.  
  96.     SetPointer(window, BusyPointerData, 16, 16, -6, 0) ;
  97.     if (RequestFile(my_req)) {
  98.         UPDATE_COMMAND(my_req->rf_File) ;
  99.         undo_size = FALSE ;
  100.         }
  101.     ClearPointer(window) ;
  102.     FreeAslRequest(my_req) ;
  103.  
  104.     return FALSE ;
  105.     }
  106.  
  107. static int
  108. config(struct Gadget *g, UWORD code) {
  109.     char config[2 * MAXSTRING], tempfile[MAXSTRING] ;
  110.     BPTR out ;
  111.     char *cp ;
  112.  
  113.     /* Build strings we need to run */
  114.     sprintf(tempfile, "t:sm.%ld", FindTask(NULL)) ;
  115.     if (!(out = Open(tempfile, MODE_READWRITE))) return FALSE ;
  116.     strcpy(command, ((struct StringInfo *) gad_command->SpecialInfo)->Buffer) ;
  117.     sprintf(config, "shadowmaster:config/%s", command) ;
  118.  
  119.     /* Run the command (with a busy pointer) */
  120.     SetPointer(window, BusyPointerData, 16, 16, -6, 0) ;
  121.     if (SystemTags(config, SYS_Output, out, TAG_DONE, 0)) {
  122.         sprintf(config, "No config available for\n%s", command) ;
  123.         dowbmessage(config) ;
  124.         }
  125.     else {
  126.         /* Check the output */
  127.         Seek(out, 0, OFFSET_BEGINNING) ;
  128.         if (FGets(out, config, MAXSTRING)) {
  129.             if (cp = strchr(config, '\n')) *cp = '\0' ;
  130.             UPDATE_COMMAND(config) ;
  131.             undo_size = FALSE ;
  132.             }
  133.         }
  134.  
  135.     /* Now clean up */
  136.     ClearPointer(window) ;
  137.     Close(out) ;
  138.     DeleteFile(tempfile) ;
  139.     return FALSE ;
  140.     }
  141.  
  142. static char *
  143. RexxIt(char *com, struct MsgPort *port, int flags) {
  144.     struct RexxMsg *msg ;
  145.     struct MsgPort *out ;
  146.     char *result = NULL ;
  147.  
  148.     if (!(msg = CreateRexxMsg(port, NULL, NULL))) return NULL ;
  149.     msg->rm_Action = RXCOMM | flags ;
  150.     msg->rm_Args[0] = com ;
  151.     if (!FillRexxMsg(msg, 1, 0)) dowbmessage("Internal error: REXX") ;
  152.     else {
  153.         Forbid() ;
  154.         if (out = FindPort("SHADOWMASTER")) PutMsg(out, (struct Message *) msg) ;
  155.         Permit() ;
  156.         if (!out) dowbmessage("ShadowMaster is not running!") ;
  157.         else 
  158.             for (;;) {
  159.                 WaitPort(port) ;
  160.                 msg = (struct RexxMsg *) GetMsg(port) ;
  161.                 if (msg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG)
  162.                     break ;
  163.                 msg->rm_Result1 = 10 ;
  164.                 msg->rm_Result2 = 10 ;
  165.                 ReplyMsg((struct Message *) msg) ;
  166.                 }
  167.             
  168.         if (msg->rm_Result1 == 0) result = (char *) msg->rm_Result2 ;
  169.         ClearRexxMsg(msg, 1) ;
  170.         }
  171.  
  172.     DeleteRexxMsg(msg) ;
  173.     return result ;
  174.     }
  175.  
  176. static int
  177. test(struct Gadget *g, UWORD code) {
  178.     struct MsgPort *myport ;
  179.     char buffer[2 * MAXSTRING], *old ;
  180.  
  181.     if (!RexxSysBase
  182.     && !(RexxSysBase = (struct RxsLib *) OpenLibrary("rexxsyslib.library", 0))) {
  183.         dowbmessage("Can't open rexx.library; test not possible.") ;
  184.         return FALSE ;
  185.         }
  186.     if (!(myport = CreateMsgPort())) {
  187.         dowbmessage("Can't create rexx port; test not possible.") ;
  188.         return FALSE ;
  189.         }
  190.  
  191.     sprintf(buffer, "command shadowmaster:savers/%s", command) ;
  192.     old = RexxIt(buffer, myport, RXFF_RESULT) ;
  193.     if (old) {            /* It worked */
  194.         RexxIt("blank", myport, 0) ;
  195.         sprintf(buffer, "command %s", old) ;
  196.         DeleteArgstring(old) ;
  197.         RexxIt(buffer, myport, 0) ;
  198.         }
  199.     
  200.     /* Send rexx messages to twiddle the command and blank the thing... */
  201.     DeleteMsgPort(myport) ;
  202.     return FALSE ;
  203.     }
  204.  
  205. static int
  206. Size(struct Gadget *g, UWORD code) {
  207.  
  208.     UPDATE_SIZE(((struct StringInfo *) g->SpecialInfo)->LongInt) ;
  209.     undo_command = FALSE ;
  210.     return FALSE ;
  211.     }
  212.  
  213. static int
  214. Corners(struct Gadget *g, UWORD code){
  215.  
  216.     UPDATE_CORNERS((g->GadgetID) ^ corners) ;
  217.     return FALSE ;
  218.     }
  219.  
  220. static int
  221. Command(struct Gadget *g, UWORD code) {
  222.  
  223.     UPDATE_COMMAND(((struct StringInfo *) g->SpecialInfo)->Buffer) ;
  224.     undo_size = FALSE ;
  225.     return FALSE ;
  226.     }
  227.  
  228. /* Undos the last action */
  229. int
  230. Undo(void) {
  231.     int save_size, save_corners ;
  232.     char save_command[MAXSTRING] ;
  233.  
  234.     if (undo_size) {
  235.         save_size = old_size ;
  236.         UPDATE_SIZE(save_size) ;
  237.         }
  238.     if (undo_command) {
  239.         strcpy(save_command, old_command) ;
  240.         UPDATE_COMMAND(save_command) ;
  241.         }
  242.     if (undo_corners) {
  243.         save_corners = old_corners ;
  244.         UPDATE_CORNERS(save_corners) ;
  245.         }
  246.     return FALSE ;
  247.     }
  248.  
  249. /* Resets the edit data to default values */
  250. int
  251. Defaults(void) {
  252.  
  253.     UPDATE_COMMAND("black") ;
  254.     UPDATE_SIZE(5) ;
  255.     UPDATE_CORNERS(TOP_LEFT) ;
  256.     return FALSE ;
  257.     }
  258.  
  259. /* Build the edit gadgets, return TRUE if all, FALSE otherwise */
  260. int
  261. UserGadgets(struct Gadget *gad, struct NewGadget *ng) {
  262.  
  263.     /* Bottom row: select */
  264.     ng->ng_TopEdge -= ng->ng_Height + 10 ;
  265.     ng->ng_LeftEdge = 13 ;
  266.     ng->ng_GadgetText = "Select" ;
  267.     ng->ng_UserData = &select ;
  268.     if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL)))
  269.         return FALSE ;
  270.  
  271.     /* Bottom row: config */
  272.     ng->ng_LeftEdge = (windowwidth - ng->ng_Width) / 2 ;
  273.     ng->ng_GadgetText = "Config" ;
  274.     ng->ng_UserData = &config ;
  275.     if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL)))
  276.         return FALSE ;
  277.     
  278.     /* Bottom row: test */
  279.     ng->ng_LeftEdge = windowwidth - 87 ;
  280.     ng->ng_GadgetText = "Test" ;
  281.     ng->ng_UserData = &test ;
  282.     if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL)))
  283.         return FALSE ;
  284.  
  285.     /* Middle row: Command gadget */
  286.     ng->ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT ;
  287.     ng->ng_TopEdge -= ng->ng_Height + 3 ;
  288.     ng->ng_LeftEdge = 80 ;
  289.     ng->ng_Width = windowwidth - 100 ;
  290.     ng->ng_GadgetText = "Command" ;
  291.     ng->ng_UserData = &Command ;
  292.     if (!(gad_command = gad = CreateGadget(STRING_KIND, gad, ng,
  293.         GTST_String, command, GTST_MaxChars, MAXSTRING - 1, TAG_DONE, 0)))
  294.         return FALSE ;
  295.  
  296.     /* Top row: size gadget */
  297.     ng->ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT ;
  298.     ng->ng_TopEdge -= (ng->ng_Height / 2) + 15 ;
  299.     ng->ng_LeftEdge = 120 ;
  300.     ng->ng_GadgetText = "Size" ;
  301.     ng->ng_UserData = &Size ;
  302.     ng->ng_Width = 67 ;
  303.     if (!(gad_size = gad = CreateGadget(INTEGER_KIND, gad, ng,
  304.         GTIN_Number, size, TAG_DONE, 0)))
  305.         return FALSE ;
  306.  
  307.     /* Top row: corner gadgets */
  308.     ng->ng_TopEdge -= (ng->ng_Height / 2) ;
  309.     ng->ng_Flags = 0 ;
  310.     ng->ng_Width = 5 ;
  311.     ng->ng_Height = 5 ;
  312.     ng->ng_GadgetText = "" ;
  313.     ng->ng_UserData = &Corners ;
  314.     ng->ng_LeftEdge = 13 ;
  315.     ng->ng_GadgetID = TOP_LEFT ;
  316.     if (!(gad_topleft = gad = CreateGadget(CHECKBOX_KIND, gad, ng,
  317.         GTCB_Checked, corners & TOP_LEFT, TAG_DONE, 0)))
  318.         return FALSE ;
  319.  
  320.     ng->ng_LeftEdge = 39 ;
  321.     ng->ng_GadgetID = TOP_RIGHT ;
  322.     if (!(gad_topright = gad = CreateGadget(CHECKBOX_KIND, gad, ng,
  323.         GTCB_Checked, corners & TOP_RIGHT, TAG_DONE, 0)))
  324.         return FALSE ;
  325.  
  326.     ng->ng_TopEdge += 11 ;
  327.     ng->ng_GadgetID = BOTTOM_RIGHT ;
  328.     if (!(gad_bottomright = gad = CreateGadget(CHECKBOX_KIND, gad, ng,
  329.         GTCB_Checked, corners & BOTTOM_RIGHT, TAG_DONE, 0)))
  330.         return FALSE ;
  331.  
  332.     ng->ng_LeftEdge = 13 ;
  333.     ng->ng_GadgetID = BOTTOM_LEFT ;
  334.     if (!(gad_bottomleft = gad = CreateGadget(CHECKBOX_KIND, gad, ng,
  335.         GTCB_Checked, corners & BOTTOM_LEFT, TAG_DONE, 0)))
  336.         return FALSE ;
  337.  
  338.     undo_size = undo_command = undo_corners = FALSE ;
  339.     return TRUE;
  340.     }
  341.  
  342. /* This saves the preferences data to the named file. Returns FALSE if open fails */
  343. int
  344. SaveFile(char *file) {
  345.     BPTR fh ;
  346.  
  347.     if (!(fh = Open(file, MODE_NEWFILE))) return FALSE ;
  348.     if (window) {
  349.         strcpy(command,
  350.             ((struct StringInfo *) gad_command->SpecialInfo)->Buffer) ;
  351.         size = ((struct StringInfo *) gad_size->SpecialInfo)->LongInt ;
  352.         }
  353.     FPrintf(fh, "%ld\n%ld\nshadowmaster:savers/%s\n", corners, size, command) ;
  354.     Close(fh) ;
  355.     return TRUE ;
  356.     }
  357.  
  358. /* This loads the named file into the editor. Returns FALSE if the open fails */
  359. int
  360. LoadFile(char *file) {
  361.     BPTR fh ;
  362.     int tmp_corners ;
  363.     char *cp, buffer[MAXSTRING] ;
  364.  
  365.     if (!(fh = Open(file, MODE_OLDFILE))) return FALSE ;
  366.     FGets(fh, buffer, MAXSTRING) ;
  367.     tmp_corners = atoi(buffer) ;
  368.     UPDATE_CORNERS(tmp_corners ? tmp_corners : TOP_LEFT) ;
  369.     FGets(fh, buffer, MAXSTRING) ;
  370.     UPDATE_SIZE(atoi(buffer)) ;
  371.     FGets(fh, buffer, MAXSTRING) ;
  372.     if (cp = strchr(buffer, '\n')) *cp = '\0' ;
  373.     if (cp = strchr(buffer, ':')) cp = strchr(buffer, '/') + 1 ;
  374.     UPDATE_COMMAND(cp ? cp : buffer) ;
  375.     Close(fh) ;
  376.  
  377.     return TRUE ;
  378.     }
  379.  
  380. /* This is for me to clean up things with; status is TRUE if we changed env:... */
  381. void
  382. CleanUp(int status) {
  383.  
  384.     if (RexxSysBase) CloseLibrary((struct Library *) RexxSysBase) ;
  385.     }