home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / screen / shdwmstr.lha / source / config / screensaver.c < prev   
C/C++ Source or Header  |  1992-01-06  |  9KB  |  325 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 screensaver ; output= screensaver.o input= screensaver.c
  12.  * % build prefs.c ; output= prefs.o input= prefs.c
  13.  * % blink prefs.o+screensaver.o lib lib:amiga.lib+lib:lcr.lib to screensaver SC SD ; output= screensaver input= screensaver.o prefs.o
  14.  * % copy screensaver //
  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 = 70 ;            /* 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 = "shadowmaster" ;    /* is the default prefs file */
  43. char *errname = "screensaver" ;        /* 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. /* The two values I write to the preferences file, plus values for undo */
  51. #define MAXSTRING 200
  52. static int seconds = 120, old_seconds = 120;
  53. static char command[MAXSTRING], old_command[MAXSTRING] = "" ;
  54.  
  55. /* Things I need to save my state */
  56. static struct Gadget *gad_seconds, *gad_command ;
  57. static int undo_seconds = FALSE, undo_command = FALSE ;
  58. struct RxsLib *RexxSysBase = NULL ;
  59.  
  60. #define UPDATE_SECONDS(value) do { old_seconds = seconds; seconds = value; \
  61.     undo_seconds = TRUE; if (window) GT_SetGadgetAttrs(gad_seconds, window, \
  62.     NULL, GTIN_Number, seconds, TAG_DONE, 0); } while (0)
  63. #define UPDATE_COMMAND(value) do { strcpy(old_command, command); \
  64.     strcpy(command, value); undo_command = TRUE; if (window) \
  65.     GT_SetGadgetAttrs(gad_command, window, NULL, GTST_String, \
  66.     command, TAG_DONE, 0); } while(0)
  67.  
  68. int LoadFile(char *) ;
  69.  
  70. /* Functions that do the gadgets. Return TRUE to exit, FALSE otherwise */
  71. static int
  72. select(struct Gadget *g, UWORD code) {
  73.     struct FileRequester    *my_req = NULL ;
  74.  
  75.     if (!(my_req = AllocAslRequestTags(ASL_FileRequest,
  76.             ASL_TopEdge, 11, ASL_LeftEdge, 0, ASL_Window, window,
  77.             ASL_Dir, "shadowmaster:savers",
  78.             ASL_FrontPen, 1, ASL_BackPen, 0,
  79.             ASL_Hail, "Select Module", TAG_DONE, 0)))
  80.         return FALSE ;
  81.  
  82.     SetPointer(window, BusyPointerData, 16, 16, -6, 0) ;
  83.     if (RequestFile(my_req)) {
  84.         UPDATE_COMMAND(my_req->rf_File) ;
  85.         undo_seconds = FALSE ;
  86.         }
  87.     ClearPointer(window) ;
  88.     FreeAslRequest(my_req) ;
  89.  
  90.     return FALSE ;
  91.     }
  92.  
  93. static int
  94. config(struct Gadget *g, UWORD code) {
  95.     char config[2 * MAXSTRING], tempfile[MAXSTRING] ;
  96.     BPTR out ;
  97.     char *cp ;
  98.  
  99.     /* Build strings we need to run */
  100.     sprintf(tempfile, "t:sm.%ld", FindTask(NULL)) ;
  101.     if (!(out = Open(tempfile, MODE_READWRITE))) return FALSE ;
  102.     strcpy(command, ((struct StringInfo *) gad_command->SpecialInfo)->Buffer) ;
  103.     sprintf(config, "shadowmaster:config/%s", command) ;
  104.  
  105.     /* Run the command (with a busy pointer) */
  106.     SetPointer(window, BusyPointerData, 16, 16, -6, 0) ;
  107.     if (SystemTags(config, SYS_Output, out, TAG_DONE, 0)) {
  108.         sprintf(config, "No config available for\n%s", command) ;
  109.         dowbmessage(config) ;
  110.         }
  111.     else {
  112.         /* Check the output */
  113.         Seek(out, 0, OFFSET_BEGINNING) ;
  114.         if (FGets(out, config, MAXSTRING)) {
  115.             if (cp = strchr(config, '\n')) *cp = '\0' ;
  116.             UPDATE_COMMAND(config) ;
  117.             undo_seconds = FALSE ;
  118.             }
  119.         }
  120.  
  121.     /* Now clean up */
  122.     ClearPointer(window) ;
  123.     Close(out) ;
  124.     DeleteFile(tempfile) ;
  125.     return FALSE ;
  126.     }
  127.  
  128. static char *
  129. RexxIt(char *com, struct MsgPort *port, int flags) {
  130.     struct RexxMsg *msg ;
  131.     struct MsgPort *out ;
  132.     char *result = NULL ;
  133.  
  134.     if (!(msg = CreateRexxMsg(port, NULL, NULL))) return NULL ;
  135.     msg->rm_Action = RXCOMM | flags ;
  136.     msg->rm_Args[0] = com ;
  137.     if (!FillRexxMsg(msg, 1, 0)) dowbmessage("Internal error: REXX") ;
  138.     else {
  139.         Forbid() ;
  140.         if (out = FindPort("SHADOWMASTER")) PutMsg(out, (struct Message *) msg) ;
  141.         Permit() ;
  142.         if (!out) dowbmessage("ShadowMaster is not running!") ;
  143.         else 
  144.             for (;;) {
  145.                 WaitPort(port) ;
  146.                 msg = (struct RexxMsg *) GetMsg(port) ;
  147.                 if (msg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG)
  148.                     break ;
  149.                 msg->rm_Result1 = 10 ;
  150.                 msg->rm_Result2 = 10 ;
  151.                 ReplyMsg((struct Message *) msg) ;
  152.                 }
  153.             
  154.         if (msg->rm_Result1 == 0) result = (char *) msg->rm_Result2 ;
  155.         ClearRexxMsg(msg, 1) ;
  156.         }
  157.  
  158.     DeleteRexxMsg(msg) ;
  159.     return result ;
  160.     }
  161.  
  162. static int
  163. test(struct Gadget *g, UWORD code) {
  164.     struct MsgPort *myport ;
  165.     char buffer[2 * MAXSTRING], *old ;
  166.  
  167.     if (!RexxSysBase
  168.     && !(RexxSysBase = (struct RxsLib *) OpenLibrary("rexxsyslib.library", 0))) {
  169.         dowbmessage("Can't open rexx.library; test not possible.") ;
  170.         return FALSE ;
  171.         }
  172.     if (!(myport = CreateMsgPort())) {
  173.         dowbmessage("Can't create rexx port; test not possible.") ;
  174.         return FALSE ;
  175.         }
  176.  
  177.     strcpy(command, ((struct StringInfo *) gad_command->SpecialInfo)->Buffer) ;
  178.     sprintf(buffer, "command shadowmaster:savers/%s", command) ;
  179.     old = RexxIt(buffer, myport, RXFF_RESULT) ;
  180.     if (old) {            /* It worked */
  181.         RexxIt("blank", myport, 0) ;
  182.         sprintf(buffer, "command %s", old) ;
  183.         DeleteArgstring(old) ;
  184.         RexxIt(buffer, myport, 0) ;
  185.         }
  186.     
  187.     /* Send rexx messages to twiddle the command and blank the thing... */
  188.     DeleteMsgPort(myport) ;
  189.     return FALSE ;
  190.     }
  191.  
  192. static int
  193. Seconds(struct Gadget *g, UWORD code) {
  194.  
  195.     UPDATE_SECONDS(((struct StringInfo *) g->SpecialInfo)->LongInt) ;
  196.     undo_command = FALSE ;
  197.     return FALSE ;
  198.     }
  199.  
  200. static int
  201. Command(struct Gadget *g, UWORD code) {
  202.  
  203.     UPDATE_COMMAND(((struct StringInfo *) g->SpecialInfo)->Buffer) ;
  204.     undo_seconds = FALSE ;
  205.     return FALSE ;
  206.     }
  207.  
  208. /* Undos the last action */
  209. int
  210. Undo(void) {
  211.     int save_seconds ;
  212.     char save_command[MAXSTRING] ;
  213.  
  214.     if (undo_seconds) {
  215.         save_seconds = old_seconds ;
  216.         UPDATE_SECONDS(save_seconds) ;
  217.         }
  218.     if (undo_command) {
  219.         strcpy(save_command, old_command) ;
  220.         UPDATE_COMMAND(save_command) ;
  221.         }
  222.     return FALSE ;
  223.     }
  224.  
  225. /* Resets the edit data to default values */
  226. int
  227. Defaults(void) {
  228.  
  229.     UPDATE_COMMAND("black") ;
  230.     UPDATE_SECONDS(300) ;
  231.     return FALSE ;
  232.     }
  233.  
  234. /* Build the edit gadgets, return TRUE if all, FALSE otherwise */
  235. int
  236. UserGadgets(struct Gadget *gad, struct NewGadget *ng) {
  237.  
  238.     /* Bottom row: select */
  239.     ng->ng_TopEdge -= ng->ng_Height + 10 ;
  240.     ng->ng_LeftEdge = 13 ;
  241.     ng->ng_GadgetText = "Select" ;
  242.     ng->ng_UserData = &select ;
  243.     if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL)))
  244.         return FALSE ;
  245.  
  246.     /* Bottom row: config */
  247.     ng->ng_LeftEdge = (windowwidth - ng->ng_Width) / 2 ;
  248.     ng->ng_GadgetText = "Config" ;
  249.     ng->ng_UserData = &config ;
  250.     if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL)))
  251.         return FALSE ;
  252.     
  253.     /* Bottom row: test */
  254.     ng->ng_LeftEdge = windowwidth - 87 ;
  255.     ng->ng_GadgetText = "Test" ;
  256.     ng->ng_UserData = &test ;
  257.     if (!(gad = CreateGadgetA(BUTTON_KIND, gad, ng, NULL)))
  258.         return FALSE ;
  259.  
  260.     /* Middle row: seconds gadget */
  261.     ng->ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT ;
  262.     ng->ng_TopEdge -= ng->ng_Height + 3 ;
  263.     ng->ng_LeftEdge = 80 ;
  264.     ng->ng_GadgetText = "Seconds" ;
  265.     ng->ng_UserData = &Seconds ;
  266.     if (!(gad_seconds = gad = CreateGadget(INTEGER_KIND, gad, ng,
  267.         GTIN_Number, seconds, TAG_DONE, 0)))
  268.         return FALSE ;
  269.  
  270.     /* Top row: Command gadget */
  271.     ng->ng_TopEdge -= ng->ng_Height + 3 ;
  272.     ng->ng_LeftEdge = 80 ;
  273.     ng->ng_Width = windowwidth - 100 ;
  274.     ng->ng_GadgetText = "Command" ;
  275.     ng->ng_UserData = &Command ;
  276.     if (!(gad_command = gad = CreateGadget(STRING_KIND, gad, ng,
  277.         GTST_String, command, GTST_MaxChars, MAXSTRING - 1, TAG_DONE, 0)))
  278.         return FALSE ;
  279.  
  280.     undo_seconds = undo_command = FALSE ;
  281.     return TRUE;
  282.     }
  283.  
  284. /* This saves the preferences data to the named file. Returns FALSE if open fails */
  285. int
  286. SaveFile(char *file) {
  287.     BPTR fh ;
  288.  
  289.     if (!(fh = Open(file, MODE_NEWFILE))) return FALSE ;
  290.     if (window) {
  291.         strcpy(command,
  292.             ((struct StringInfo *) gad_command->SpecialInfo)->Buffer) ;
  293.         seconds = ((struct StringInfo *) gad_seconds->SpecialInfo)->LongInt ;
  294.         }
  295.     FPrintf(fh, "%ld\nshadowmaster:savers/%s\n", seconds, command) ;
  296.     Close(fh) ;
  297.     return TRUE ;
  298.     }
  299.  
  300. /* This loads the named file into the editor. Returns FALSE if the open fails */
  301. int
  302. LoadFile(char *file) {
  303.     BPTR fh ;
  304.     char *cp, buffer[MAXSTRING] ;
  305.  
  306.     if (!(fh = Open(file, MODE_OLDFILE))) return FALSE ;
  307.     FGets(fh, buffer, MAXSTRING) ;
  308.     UPDATE_SECONDS(atoi(buffer)) ;
  309.     FGets(fh, buffer, MAXSTRING) ;
  310.     if (cp = strchr(buffer, '\n')) *cp = '\0' ;
  311.     if ((cp = strchr(buffer, ':')) && (cp = strchr(buffer, '/')))
  312.         cp += 1 ;
  313.     UPDATE_COMMAND(cp ? cp : buffer) ;
  314.     Close(fh) ;
  315.  
  316.     return TRUE ;
  317.     }
  318.  
  319. /* This is for me to clean up things with; status is TRUE if we changed env:... */
  320. void
  321. CleanUp(int status) {
  322.  
  323.     if (RexxSysBase) CloseLibrary((struct Library *) RexxSysBase) ;
  324.     }
  325.