home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / commodities / nag / nag.c < prev    next >
C/C++ Source or Header  |  1993-04-02  |  48KB  |  1,644 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <exec/types.h>
  6. #include <exec/memory.h>
  7. #include <devices/timer.h>
  8. #include <dos/dos.h>
  9. #include <intuition/intuition.h>
  10. #include <intuition/gadgetclass.h>
  11. #include <intuition/screens.h>
  12. #include <exec/libraries.h>
  13. #include <exec/lists.h>
  14. #include <exec/nodes.h>
  15. #include <exec/memory.h>
  16. #include <libraries/commodities.h>
  17. #include <libraries/gadtools.h>
  18. #include <graphics/gfxbase.h>
  19. #include <graphics/text.h>
  20. #include <clib/exec_protos.h>
  21. #include <clib/dos_protos.h>
  22. #include <clib/graphics_protos.h>
  23. #include <clib/intuition_protos.h>
  24. #include <clib/gadtools_protos.h>
  25. #include <clib/alib_protos.h>
  26. #include <clib/commodities_protos.h>
  27.  
  28. extern char __months[];
  29. extern struct Library *IntuitionBase;
  30. extern struct Library *CxBase;
  31. extern struct Library *GadToolsBase;
  32. extern struct Library *IconBase;
  33. extern struct GfxBase *GfxBase;
  34.  
  35. static UBYTE *VersTag = "$VER: Nag 1.14  (4/2/93)";
  36.  
  37.  
  38. long __stack = 4000;
  39. char *__procname = "Nag";
  40. long __priority = 0;
  41. long __BackGroundIO = 0;
  42.  
  43.  
  44. void main(int, char **);
  45. void nag_error(UBYTE *);
  46. ULONG Open_Window(void);
  47. void AddEventNode(struct List *, UBYTE *, ULONG);
  48. void GetEventNode(struct List *, ULONG, UBYTE *);
  49. ULONG FindEventNode(struct List *list, UBYTE *name);
  50. void ChangeEventNode(struct List *, ULONG, UBYTE *);
  51. void DeleteEventNode(struct List *, ULONG);
  52. void SortEventList(struct List *);
  53. void SaveEventList(struct List *);
  54. void check_times(int, struct List *);
  55. //void print_mem_list(int);
  56. void Close_Window(void);
  57. LONG ProcessMsg(void);
  58. ULONG getnum(char **);
  59. void parse_mes_times(struct List *);
  60. void subtaskcode(void);    
  61. void Abort_TimerIO(ULONG);
  62. void get_sys_time(ULONG *);
  63. void calc_date(ULONG *);
  64. ULONG calc_tsec(ULONG *);
  65. ULONG set_timer_request(ULONG);
  66.  
  67. struct eNode {
  68.    struct Node e_Node;        /* System Node structure */
  69.    UBYTE  e_Data[132];         /* Node-specific data */
  70.    ULONG  e_time;
  71.    ULONG  e_ltime;
  72.    UBYTE  *e_msg;
  73. };
  74.  
  75. LONG signum[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  76. ULONG sig[] = {0,0,0,0,0,0,0,0,0,0},nos;
  77. struct Task *maintask = NULL, *subtask = NULL;
  78. UBYTE subtaskname[] = "Nag task";
  79.  
  80. struct Remember *rememberkey = NULL;
  81. struct timerequest *TimerIO;
  82. struct MsgPort *TimerMP,*broker_mp;
  83. struct Message *TimerMSG;
  84. struct Screen *screen;
  85. struct Window *win;
  86. struct Menu *menstr;
  87. struct Gadget *glist,*gad[6];
  88. struct List *el = NULL;
  89. UBYTE *font_name;
  90. ULONG font_name_size;
  91. struct TextAttr screen_font;
  92. struct TextFont *opened_font;
  93. APTR *vi;
  94.  
  95. CxObj *broker, *filter, *sender, *translate;
  96. ULONG cxsigflag;
  97.  
  98. char buf[132],title[81];
  99. ULONG winsigflag;
  100. char pts[] = "UMTWHFSAP0123456789/: ?";
  101. char dt[] = "#2/#3/#1", tt[] = "#5:#6M", dows[] = "UMTWHFS",ddc;
  102. UBYTE *hotkey;
  103. BOOL pup;
  104. LONG emn;
  105. struct eNode *mn;
  106. ULONG sleep;
  107.  
  108. struct EasyStruct myES = {
  109.    sizeof(struct EasyStruct),
  110.    0,
  111.    "Nag 1.14",
  112.    NULL,
  113.    "OK|Nag in %ld min"
  114. }, about = {
  115.    sizeof(struct EasyStruct),
  116.    0,
  117.    "Nag 1.14",
  118.    "Nag version 1.14\n(c)1993 by David Walthour",
  119.    "OK"
  120. };
  121.  
  122. struct NewBroker newbroker = {
  123.     NB_VERSION,   /* nb_Version - Version of the NewBroker structure */
  124.     "Nag",       /* nb_Name - Name Commodities uses to identify this commodity */
  125.     "Nag v1.14",  /* nb_Title - Title of commodity that appears in CXExchange */
  126.     "A reminder utility",  /* nb_Descr - Description of the commodity */
  127.     NBU_UNIQUE|NBU_NOTIFY, /* nb_Unique - Tells CX not to launch another commodity with same name */
  128.     COF_SHOW_HIDE, /* nb_Flags - Tells CX if this commodity has a window */
  129.     0,            /* nb_Pri - This commodity's priority */
  130.     0,            /* nb_Port - MsgPort CX talks to */
  131.     0             /* nb_ReservedChannel - reserved for later use */
  132. };
  133.  
  134. #define EVT_HOTKEY 1L
  135.  
  136. void main(int argc, char **argv)
  137. {
  138.    int i;
  139.    ULONG et;
  140.    CxMsg *msg;
  141.    char *b,*p,ets[11];
  142.    BPTR f;
  143.    UBYTE **ttypes;
  144.  
  145.    nos = sizeof(sig)/sizeof(ULONG);
  146.  
  147.    el = AllocRemember(&rememberkey,sizeof(struct List), MEMF_CLEAR);
  148.    if (el!=NULL) {
  149.       NewList(el);
  150.          
  151.       f = Open("ENV:nag.ml",MODE_OLDFILE);
  152.       if (f==NULL) {
  153.          f = Open("ENV:nag.ml",MODE_NEWFILE);
  154.       }
  155.       if (f!=NULL) {
  156.          while(1) {
  157.             b = FGets(f,buf,131);
  158.             if (b==NULL) break;
  159.             if ((buf[0]=='#')||(buf[0]==';')||(buf[0]==0)||(buf[0]=='\n')) continue;
  160.             buf[strlen(buf)-1]=0;
  161.             if (buf[0]=='@') {
  162.                i = 1;
  163.                while(buf[i]!='@') {
  164.                   ets[i-1] = buf[i];
  165.                   i++;
  166.                }
  167.                ets[i-1] = 0;
  168.                et = strtoul(ets,NULL,10);
  169.                p = &buf[i+1];
  170.             }
  171.             else {
  172.                et = 0;
  173.                p = buf;
  174.             }
  175.             if (*p==NULL) continue;
  176.             AddEventNode(el,p,et);
  177.          }
  178.          
  179.          Close(f);
  180.  
  181. //         print_mem_list(0);
  182.  
  183.          if (broker_mp = CreateMsgPort()) {
  184.             newbroker.nb_Port = broker_mp;
  185.             cxsigflag = 1L << broker_mp->mp_SigBit;
  186.             ttypes = ArgArrayInit(argc,argv);
  187.             newbroker.nb_Pri = (BYTE)ArgInt(ttypes, "CX_PRIORITY", 0);
  188.             sleep = (ULONG)ArgInt(ttypes, "NAG_LATER_DELAY", 5);
  189.             hotkey = ArgString(ttypes, "CX_POPKEY", "control alt n");
  190.             if (strcmp(strupr(ArgString(ttypes, "CX_POPUP", "YES")),"YES")==0) {
  191.                pup = TRUE;
  192.             }
  193.             else {
  194.                pup = FALSE;
  195.             }
  196.             if (strcmp(strupr(ArgString(ttypes, "DATE_FORMAT", "MONTH_FIRST")),"DAY_FIRST")==0) {
  197.                dt[1] = '3';
  198.                dt[4] = '2';
  199.             }
  200.             else {
  201.                dt[1] = '2';
  202.                dt[4] = '3';
  203.             }
  204.             if (strcmp(strupr(ArgString(ttypes, "DATE_DIVIDER", "SLASH")),"DOT")==0) {
  205.                dt[2] = dt[5] = pts[19] = ddc = '.';
  206.             }
  207.             else if (strcmp(strupr(ArgString(ttypes, "DATE_DIVIDER", "SLASH")),"DASH")==0) {
  208.                dt[2] = dt[5] = pts[19] = ddc = '-';
  209.             }
  210.             else {
  211.                dt[2] = dt[5] = pts[19] = ddc = '/';
  212.             }
  213.  
  214.             mn=NULL;
  215.             check_times(0,el);
  216.             parse_mes_times(el);
  217.  
  218.             if (broker = CxBroker(&newbroker, NULL)) {
  219.                if (filter = CxFilter(hotkey)) {
  220.                   AttachCxObj(broker, filter);
  221.                   if (sender = CxSender(broker_mp, EVT_HOTKEY)) {
  222.                      AttachCxObj(filter,sender);
  223.                      if (translate = CxTranslate(NULL)) {
  224.                         AttachCxObj(filter,translate);
  225.                         if (!CxObjError(filter)) {
  226.                            ActivateCxObj(broker, 1L);
  227.                            
  228.                            for (i=0; i<nos; i++) {
  229.                               signum[i] = AllocSignal(-1);
  230.                               if (signum[i]==-1) break;
  231.                            }
  232.                            if (i!=nos) {
  233.                               for (i=0; i<nos; i++) {
  234.                                  if (signum[i]==-1) FreeSignal(signum[i]);
  235.                               }
  236.                               nag_error("signal allocation error");
  237.                            }
  238.                            else {
  239.                               for (i=0; i<nos; i++) {
  240.                                  sig[i] = 1L << signum[i];
  241.                               }
  242.                               maintask = FindTask(NULL);
  243.                            
  244.                               subtask = CreateTask(subtaskname,0L,subtaskcode,2000);
  245.                               if(subtask) {
  246.                                  ActivateCxObj(broker, 1L);
  247.                                  if (ProcessMsg()>=0) {
  248.                                     Signal(subtask,sig[0]);
  249.                                     Wait(sig[1]);
  250.                                  }
  251.                                  Forbid();
  252.                                  DeleteTask(subtask);
  253.                                  Permit();
  254.                   
  255.                               }
  256.                               else {
  257.                                  nag_error("subtask creation error");
  258.                               }
  259.                               for (i=0; i<nos; i++) {
  260.                                  FreeSignal(signum[i]);
  261.                               }
  262.                            }
  263.                         }
  264.                         else {
  265.                            nag_error("AttachCxObj error");
  266.                         }
  267.                      }
  268.                      else {
  269.                         nag_error("CxTranslate error");
  270.                      }
  271.                   }
  272.                   else {
  273.                      nag_error("CxSender error");
  274.                   }
  275.                }
  276.                else {
  277.                   nag_error("CxFilter error");
  278.                }
  279.                DeleteCxObjAll(broker);
  280.                while(msg = (CxMsg *)GetMsg(broker_mp)) {
  281.                   ReplyMsg((struct Message *)msg);
  282.                }
  283.             }
  284.             DeletePort(broker_mp);
  285.          }
  286.          else {
  287.             nag_error("broker_mp error");
  288.          }
  289.          ArgArrayDone();
  290.       }
  291.       else {
  292.          nag_error("nag.ml file error");
  293.       }
  294. //      print_mem_list(1);
  295.       FreeRemember(&rememberkey,TRUE);
  296.       CacheClearU();
  297.    }
  298.    else {
  299.       nag_error("list memory allocation");
  300.    }
  301. }
  302.  
  303. void nag_error(UBYTE *s)
  304. {
  305.    static struct EasyStruct errorES = {
  306.       sizeof(struct EasyStruct),
  307.       0,
  308.       "Nag 1.14",
  309.       "Nag Error: %s",
  310.       "OK"
  311.    };
  312.    
  313.    EasyRequest(NULL,&errorES,NULL,s);
  314. }
  315.  
  316. #define ENODE_ID   100       /* The type of "NameNode" */
  317.  
  318. void AddEventNode(struct List *list, UBYTE *name, ULONG etime)
  319. {
  320.    struct eNode *namenode;
  321.    UBYTE *p,*p1;
  322.  
  323.    if (( namenode = AllocRemember(&rememberkey,sizeof(struct eNode),MEMF_CLEAR) )!=0) {
  324.       strcpy(namenode->e_Data,name);
  325.       namenode->e_Node.ln_Name = namenode->e_Data;
  326.       namenode->e_Node.ln_Type = ENODE_ID;
  327.       namenode->e_Node.ln_Pri  = 0;
  328.       p1 = namenode->e_Data;
  329.       p = strchr(p1,32);
  330.       if (p!=NULL) {
  331.          while(*p==32) p++;
  332.          p1 = strchr(p,32);
  333.          if (p1!=NULL) {
  334.             while(*p1==32) p1++;
  335.             namenode->e_msg = p1;
  336.          }
  337.          else {
  338.             namenode->e_msg = NULL;
  339.          }
  340.       }
  341.       else {
  342.          namenode->e_msg = NULL;
  343.       }
  344.       namenode->e_time = etime;
  345.       namenode->e_ltime = 0;
  346.       AddTail((struct List *)list,(struct Node *)namenode);
  347.    }
  348.    else {
  349.       nag_error("event memory allocation error");
  350.    }
  351. }
  352.  
  353. void GetEventNode(struct List *list, ULONG nn, UBYTE *name)
  354. {
  355.    struct eNode *worknode;
  356.    
  357.    worknode = (struct eNode *)(list->lh_Head);
  358.    while (nn>0) {
  359.       worknode = (struct eNode *)(worknode->e_Node.ln_Succ);
  360.       nn--;
  361.    }
  362.    strcpy(name,worknode->e_Data);
  363. }
  364.  
  365. ULONG FindEventNode(struct List *list, UBYTE *name)
  366. {
  367.    ULONG nn;
  368.    struct eNode *worknode;
  369.    
  370.    worknode = (struct eNode *)(list->lh_Head);
  371.    nn = 0;
  372.    while (strcmp(worknode->e_Data,name)) {
  373.       worknode = (struct eNode *)(worknode->e_Node.ln_Succ);
  374.       nn++;
  375.    }
  376.    return nn;
  377. }
  378.  
  379. void ChangeEventNode(struct List *list, ULONG nn, UBYTE *name)
  380. {
  381.    struct eNode *worknode;
  382.    UBYTE *p,*p1;
  383.    
  384.    worknode = (struct eNode *)(list->lh_Head);
  385.    while (nn>0) {
  386.       worknode = (struct eNode *)(worknode->e_Node.ln_Succ);
  387.       nn--;
  388.    }
  389.    strcpy(worknode->e_Data,name);
  390.    p1 = worknode->e_Data;
  391.    p = strchr(p1,32);
  392.    if (p!=NULL) {
  393.       while(*p==32) p++;
  394.       p1 = strchr(p,32);
  395.       if (p1!=NULL) {
  396.          while(*p1==32) p1++;
  397.          worknode->e_msg = p1;
  398.       }
  399.       else {
  400.          worknode->e_msg = NULL;
  401.       }
  402.    }
  403.    else {
  404.       worknode->e_msg = NULL;
  405.    }
  406.    worknode->e_ltime = 0;
  407. }
  408.  
  409. void DeleteEventNode(struct List *list, ULONG nn)
  410. {
  411.    struct eNode *worknode;
  412.  
  413.    worknode = (struct eNode *)(list->lh_Head);
  414.    while (nn>0) {
  415.       worknode = (struct eNode *)(worknode->e_Node.ln_Succ);
  416.       nn--;
  417.    }
  418.    Remove(worknode);
  419. }
  420.  
  421. void SortEventList(struct List *list)
  422. {
  423.    struct eNode *n1,*n2;
  424.    ULONG st[9],t1,t2,temp;
  425.    UBYTE *p,*p1;
  426.  
  427.    get_sys_time(st);
  428.    
  429.    n1 = (struct eNode *)(list->lh_Head);
  430.    while(n2 = (struct eNode *)(n1->e_Node.ln_Succ)) {
  431.       while(n2->e_Node.ln_Succ) {
  432.          t1 = n1->e_time;
  433.          t2 = n2->e_time;
  434.          if (((t2<t1)&&(t2>st[0]))||((t1<st[0])&&(t2>st[0]))) {
  435.             strcpy(buf,n2->e_Data);
  436.             strcpy(n2->e_Data,n1->e_Data);
  437.             strcpy(n1->e_Data,buf);
  438.             p1 = n1->e_Data;
  439.             p = strchr(p1,32);
  440.             if (p!=NULL) {
  441.                while(*p==32) p++;
  442.                p1 = strchr(p,32);
  443.                if (p1!=NULL) {
  444.                   while(*p1==32) p1++;
  445.                   n1->e_msg = p1;
  446.                }
  447.                else {
  448.                   n1->e_msg = NULL;
  449.                }
  450.             }
  451.             else {
  452.                n1->e_msg = NULL;
  453.             }
  454.             p1 = n2->e_Data;
  455.             p = strchr(p1,32);
  456.             if (p!=NULL) {
  457.                while(*p==32) p++;
  458.                p1 = strchr(p,32);
  459.                if (p1!=NULL) {
  460.                   while(*p1==32) p1++;
  461.                   n2->e_msg = p1;
  462.                }
  463.                else {
  464.                   n2->e_msg = NULL;
  465.                }
  466.             }
  467.             else {
  468.                n2->e_msg = NULL;
  469.             }
  470.             n1->e_time = t2;
  471.             n2->e_time = t1;
  472.             temp = n1->e_ltime;
  473.             n1->e_ltime = n2->e_ltime;
  474.             n2->e_ltime = temp;
  475.          }
  476.          n2 = (struct eNode *)(n2->e_Node.ln_Succ);
  477.       }
  478.       n1 = (struct eNode *)(n1->e_Node.ln_Succ);
  479.    }
  480. }
  481.  
  482. void SaveEventList(struct List *list)
  483. {
  484.    BPTR f;
  485.    struct eNode *wn,*nn;
  486.    
  487.    f = Open("ENVARC:nag.ml",MODE_NEWFILE);
  488.    if (f!=NULL) {
  489.       wn = (struct eNode *)(list->lh_Head); /* First node */
  490.       while (nn = (struct eNode *)(wn->e_Node.ln_Succ)) {
  491.          buf[0] = '@';
  492.          stcul_d(&buf[1],wn->e_time);
  493.          strcat(buf,"@");
  494.          strcat(buf,wn->e_Data);
  495.          strcat(buf,"\n");
  496.          FPuts(f,buf);
  497.          wn = nn;
  498.       }
  499.       Close(f);
  500.       f = Open("ENV:nag.ml",MODE_NEWFILE);
  501.       if (f!=NULL) {
  502.          wn = (struct eNode *)(list->lh_Head); /* First node */
  503.          while (nn = (struct eNode *)(wn->e_Node.ln_Succ)) {
  504.             buf[0] = '@';
  505.             stcul_d(&buf[1],wn->e_time);
  506.             strcat(buf,"@");
  507.             strcat(buf,wn->e_Data);
  508.             strcat(buf,"\n");
  509.             FPuts(f,buf);
  510.             wn = nn;
  511.          }
  512.          Close(f);
  513.       }
  514.    }
  515. }
  516.  
  517. void check_times(int typ,struct List *list)
  518. {
  519.    struct eNode *wn,*nn;
  520.    ULONG st[9];
  521.    LONG r;
  522.    static struct EasyStruct ctES = {
  523.       sizeof(struct EasyStruct),
  524.       0,
  525.       "Nag 1.14",
  526.       "This message occurred while Nag was inactive:\n\n%s",
  527.       "OK"
  528.    };
  529.                 
  530.    get_sys_time(st);
  531.    
  532.    wn = (struct eNode *)(list->lh_Head); /* First node */
  533.    while (nn = (struct eNode *)(wn->e_Node.ln_Succ)) {
  534.       if ((typ==1)&&(mn==wn)) {
  535.          wn = nn;
  536.          continue;
  537.       }
  538.       if (((wn->e_time)!=0)&&((wn->e_time)<st[0])) {
  539.          strcpy(buf,wn->e_msg);
  540.          if (typ==1) {
  541.             myES.es_TextFormat = buf;
  542.             DisplayBeep(NULL);
  543.             r = EasyRequest(NULL, &myES, NULL, sleep);
  544.             if (r==0) {
  545.                wn->e_ltime = wn->e_time;
  546.             }
  547.             else {
  548.                wn->e_ltime = 0;
  549.             }
  550.          }
  551.          else {
  552.             DisplayBeep(NULL);
  553.             EasyRequest(NULL, &ctES, NULL, buf);
  554.          }
  555.       }
  556.       wn = nn;
  557.    }
  558. }
  559.  
  560. /*
  561. void print_mem_list(int t)
  562. {
  563.    int i,jj,ii;
  564.    UBYTE cc;
  565.    struct Remember *rp;
  566.    FILE *f;
  567.  
  568.    rp = rememberkey;
  569.    
  570.    if (t==0) {
  571.       f = fopen("dh0:t/nag.mem.start","w");
  572.    }
  573.    else {
  574.       f = fopen("dh0:t/nag.mem.end","w");
  575.    }
  576.    
  577.    do {
  578.       fprintf(f,"%d %08X\n",rp->RememberSize,rp->Memory);
  579.       for (ii=0; ii<rp->RememberSize; ii+=16) {
  580.          for (jj=0; jj<16; jj++) {
  581.             i = ii+jj;
  582.             if (i>=rp->RememberSize) {
  583.                fprintf(f,"   ");
  584.                continue;
  585.             }
  586.             cc = *((rp->Memory)+i);
  587.             fprintf(f,"%02X ",cc);
  588.          }
  589.          fprintf(f,"  ");
  590.          for (jj=0; jj<16; jj++) {
  591.             i = ii+jj;
  592.             if (i>=rp->RememberSize) {
  593.                fprintf(f," ");
  594.                continue;
  595.             }
  596.             cc = *((rp->Memory)+i);
  597.             if (isprint(cc)) {
  598.                fprintf(f,"%c",cc);
  599.             }
  600.             else {
  601.                fprintf(f,".");
  602.             }
  603.          }
  604.          fprintf(f,"\n");
  605.       }
  606.       fprintf(f,"\n");
  607.       rp = rp->NextRemember;
  608.    } while(rp);
  609.    
  610.    fclose(f);
  611. }
  612. */
  613.  
  614. ULONG Open_Window(void)
  615. {
  616.    ULONG i,WIDTH=396,HEIGHT=122,fw,fh,NLI,le,te;
  617.    struct Gadget *g;
  618.    
  619.    static struct NewMenu mymenu[] = {
  620.       { NM_TITLE, "Project",   0, 0, 0, 0 },
  621.       { NM_ITEM,  "About",    "A",0, 0, 0 },
  622.       { NM_ITEM,  NM_BARLABEL, 0, 0, 0, 0 },
  623.       { NM_ITEM,  "Hide",     "H",0, 0, 0 },
  624.       { NM_ITEM,  "Quit",     "Q",0, 0, 0 },
  625.       { NM_END,   NULL,        0, 0, 0, 0 }
  626.    };
  627.  
  628.    static struct NewGadget ng[6];
  629.    static struct TextExtent fext;
  630.  
  631.    screen = NULL;
  632.    vi = NULL;
  633.    glist = NULL;
  634.    win = NULL;
  635.    menstr = NULL;
  636.    
  637.    if ((screen = LockPubScreen(NULL)) != NULL) {
  638.       te = screen->WBorTop + screen->Font->ta_YSize + 1;
  639.       le = screen->WBorLeft;
  640.       font_name_size = 1 + strlen(screen->Font->ta_Name);
  641.       if ((font_name = AllocMem(font_name_size,MEMF_CLEAR)) != NULL) {
  642.          strcpy(font_name,screen->Font->ta_Name);
  643.          screen_font.ta_Name  = font_name;
  644.          screen_font.ta_YSize = screen->Font->ta_YSize;
  645.          screen_font.ta_Style = screen->Font->ta_Style;
  646.          screen_font.ta_Flags = screen->Font->ta_Flags;
  647.          if ((opened_font = OpenFont(&screen_font)) != NULL) {
  648.             FontExtent(opened_font,&fext);
  649.             fw = fext.te_Width;
  650.             fh = fext.te_Height;
  651.             if ((vi=GetVisualInfo(screen,TAG_END)) != NULL) {
  652.                g = CreateContext(&glist);
  653.                
  654.                for (i=0; i<6; i++) {
  655.                   ng[i].ng_TextAttr = &screen_font;
  656.                   ng[i].ng_VisualInfo = vi;
  657.                   ng[i].ng_Flags = 0;
  658.                   ng[i].ng_GadgetID = i;
  659.                }
  660.                
  661.                NLI = 16;
  662.                while (1) {
  663.                   HEIGHT = 27+(NLI+2)*fh;
  664.                   if ((HEIGHT<=160)||(NLI==2)) break; else NLI--;
  665.                }
  666.                
  667.                if ((3*(4*fw+20)+40)>WIDTH) {
  668.                   WIDTH = 3*(4*fw+20)+36;
  669.                }
  670.                
  671.                if (WIDTH>((screen->Width)-20)) {
  672.                   WIDTH = (screen->Width)-20;
  673.                }
  674.                
  675.                while ((WIDTH%6)!=0) WIDTH++;
  676.          
  677.                
  678.                ng[0].ng_TopEdge    = (HEIGHT-(fh + 9)) + te;
  679.                ng[0].ng_Width      = strlen("Hide")*fw + 20;
  680.                ng[0].ng_LeftEdge   = le + WIDTH/4 - (ng[0].ng_Width)/2;
  681.                ng[0].ng_Height     = fh + 5;
  682.                ng[0].ng_GadgetText = "Hide";
  683.  
  684.                ng[1].ng_TopEdge    = (HEIGHT-(fh + 9)) + te;
  685.                ng[1].ng_Width      = strlen("Quit")*fw + 20;
  686.                ng[1].ng_LeftEdge   = le + (3*WIDTH)/4 - (ng[1].ng_Width)/2;
  687.                ng[1].ng_Height     = fh + 5;
  688.                ng[1].ng_GadgetText = "Quit";
  689.       
  690.                ng[2].ng_LeftEdge   = le + 6;
  691.                ng[2].ng_TopEdge    = (HEIGHT-2*(fh + 9)) + te;
  692.                ng[2].ng_Width      = strlen("New")*fw + 20;
  693.                ng[2].ng_Height     = fh + 5;
  694.                ng[2].ng_GadgetText = "New";
  695.       
  696.                ng[3].ng_LeftEdge   = le + 12 + ng[2].ng_Width;
  697.                ng[3].ng_TopEdge    = (HEIGHT-2*(fh + 9)) + te;
  698.                ng[3].ng_Width      = strlen("Del")*fw + 20;
  699.                ng[3].ng_Height     = fh + 5;
  700.                ng[3].ng_GadgetText = "Del";
  701.       
  702.                ng[4].ng_LeftEdge   = le + 18 + ng[2].ng_Width + ng[3].ng_Width;
  703.                ng[4].ng_TopEdge    = (HEIGHT-2*(fh + 9)) + te + (fh + 1);
  704.                ng[4].ng_Width      = WIDTH-ng[4].ng_LeftEdge-2;
  705.                ng[4].ng_Height     = fh + 6;
  706.                ng[4].ng_GadgetText = "";
  707.                
  708.                ng[5].ng_LeftEdge   = ng[4].ng_LeftEdge;
  709.                ng[5].ng_TopEdge    = 4 + te;
  710.                ng[5].ng_Width      = WIDTH-ng[5].ng_LeftEdge-2;
  711.                ng[5].ng_Height     = NLI*fh+4+ng[4].ng_Height-2;
  712.                ng[5].ng_GadgetText = "Events:";
  713.                ng[5].ng_Flags      = PLACETEXT_LEFT;
  714.  
  715.                gad[0] = g = CreateGadget(BUTTON_KIND,g,&ng[0],TAG_END);
  716.                gad[1] = g = CreateGadget(BUTTON_KIND,g,&ng[1],TAG_END);
  717.                gad[2] = g = CreateGadget(BUTTON_KIND,g,&ng[2],TAG_END);
  718.                gad[3] = g = CreateGadget(BUTTON_KIND,g,&ng[3],
  719.                              GA_Disabled,       TRUE,
  720.                              TAG_END);
  721.                gad[4] = g = CreateGadget(STRING_KIND,g,&ng[4],
  722.                              GTST_MaxChars,     128,
  723.                              GA_Disabled,       TRUE,
  724.                              TAG_END);
  725.                gad[5] = g = CreateGadget(LISTVIEW_KIND,g,&ng[5],
  726.                              GTLV_Labels,       el,
  727.                              GTLV_ShowSelected, g,
  728.                              TAG_END);
  729.  
  730.                if (g!=NULL) {
  731.                   strcpy(title,"Nag 1.14: Hot Key = <");
  732.                   strcat(title,hotkey);
  733.                   strcat(title,">");
  734.                   win = OpenWindowTags(NULL,
  735.                      WA_Title,       title,
  736.                      WA_Gadgets,     glist,
  737.                      WA_Left,        100,
  738.                      WA_Top,         60,
  739.                      WA_InnerWidth,  WIDTH,
  740.                      WA_InnerHeight, HEIGHT,
  741.                      WA_PubScreen,   screen,
  742.                      WA_AutoAdjust,  TRUE,
  743.                      WA_DragBar,     TRUE,
  744.                      WA_DepthGadget, TRUE,
  745.                      WA_Activate,    TRUE,
  746.                      WA_CloseGadget, TRUE,
  747.                      WA_IDCMP,       IDCMP_CLOSEWINDOW   | IDCMP_MENUPICK     |
  748.                                      IDCMP_REFRESHWINDOW | IDCMP_ACTIVEWINDOW |
  749.                                      BUTTONIDCMP         | LISTVIEWIDCMP      | 
  750.                                      STRINGIDCMP,
  751.                      WA_PubScreen,   screen,
  752.                      TAG_END);
  753.                   if (win!=NULL) {
  754.                      if (NULL!=(menstr=CreateMenus(mymenu, TAG_END))) {
  755.                         if (LayoutMenus(menstr,vi,TAG_END)) {
  756.                            if (SetMenuStrip(win,menstr)) {
  757.                               GT_RefreshWindow(win,NULL);
  758.                               return (unsigned)(1L << win->UserPort->mp_SigBit);
  759.                            }
  760.                            FreeMenus(menstr);
  761.                         }
  762.                      }
  763.                      CloseWindow(win);
  764.                   }
  765.                   else {
  766.                      nag_error("can't open window");
  767.                   }
  768.                }
  769.                else {
  770.                   nag_error("can't create gadgets");
  771.                }
  772.                FreeGadgets(glist);
  773.                FreeVisualInfo(vi);
  774.             }
  775.             else {
  776.                nag_error("can't get visual info");
  777.             }
  778.             CloseFont(opened_font);
  779.          }
  780.          else {
  781.             nag_error("can't open font");
  782.          }
  783.          FreeMem(font_name, font_name_size);
  784.       }
  785.       else {
  786.          nag_error("font memory allocation error");
  787.       }
  788.       UnlockPubScreen(NULL,screen);
  789.    }
  790.    else {
  791.       nag_error("can't Lock public screen");
  792.    }
  793.    return 0L;
  794. }
  795.  
  796. void Close_Window(void)
  797. {
  798.    FreeMenus(menstr);
  799.    CloseWindow(win);
  800.    FreeGadgets(glist);
  801.    FreeVisualInfo(vi);
  802.    CloseFont(opened_font);
  803.    FreeMem(font_name, font_name_size);
  804.    UnlockPubScreen(NULL,screen);
  805. }
  806.  
  807. LONG ProcessMsg(void)
  808. {
  809.    CxMsg *msg;
  810.    ULONG sigrcvd, msgid, msgtype;
  811.    LONG returnvalue = 1L;
  812.    BOOL paused = FALSE;
  813.    struct IntuiMessage *message;
  814.    ULONG class;
  815.    USHORT code;
  816.    UWORD mennum,itnum;
  817.    struct MenuItem *item;
  818.    struct Gadget *g;
  819.    UBYTE *p;
  820.    WORD bufpos;
  821.    static UBYTE buf1[132],buf2[132];
  822.    LONG r;
  823.    
  824.  
  825.    if (pup==TRUE) {
  826.       winsigflag = Open_Window();
  827.    }
  828.    else {
  829.       winsigflag = 0;
  830.    }
  831.    emn = -1;
  832.  
  833.    while (returnvalue) {
  834.       
  835.       /* wait for something to happen */
  836.       sigrcvd = Wait(cxsigflag|winsigflag|sig[8]|sig[1]);
  837.  
  838.       /* process any messages */
  839.  
  840.       if (sigrcvd & sig[1]) {
  841.          if (winsigflag!=0) {
  842.             Close_Window();
  843.             winsigflag = 0;
  844.          }
  845.          nag_error("subtask failed");
  846.          returnvalue = -1;
  847.          break;
  848.       }
  849.       if (sigrcvd & sig[8]) {
  850.          DisplayBeep(NULL);
  851.          r = EasyRequest(NULL, &myES, NULL, sleep);
  852.          if (r==0) {
  853.             mn->e_ltime = mn->e_time;
  854.          }
  855.          else {
  856.             mn->e_ltime = 0;
  857.          }
  858.          check_times(1,el);
  859.          if (winsigflag!=0) {
  860.             if (emn==-2) {
  861.                strcpy(buf1,((struct StringInfo *)gad[4]->SpecialInfo)->Buffer);
  862.                bufpos = ((struct StringInfo *)gad[4]->SpecialInfo)->BufferPos;
  863.             }
  864.             else if (emn>=0) {
  865.                GetEventNode(el,emn,buf2);
  866.                strcpy(buf1,((struct StringInfo *)gad[4]->SpecialInfo)->Buffer);
  867.                bufpos = ((struct StringInfo *)gad[4]->SpecialInfo)->BufferPos;
  868.             }
  869.             GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,~0,TAG_END);
  870.             parse_mes_times(el);
  871.             GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,el,TAG_END);
  872.             if (emn==-2) {
  873.                GT_SetGadgetAttrs(gad[4],win,NULL,GTST_String,buf1,TAG_END);
  874.                ((struct StringInfo *)gad[4]->SpecialInfo)->BufferPos = bufpos;
  875.                ActivateGadget(gad[4],win,NULL);
  876.             }
  877.             else if (emn>=0) {
  878.                emn = FindEventNode(el,buf2);
  879.                GT_SetGadgetAttrs(gad[4],win,NULL,GTST_String,buf1,TAG_END);
  880.                ((struct StringInfo *)gad[4]->SpecialInfo)->BufferPos = bufpos;
  881.                ActivateGadget(gad[4],win,NULL);
  882.             }
  883.          }
  884.          else {
  885.             parse_mes_times(el);
  886.          }
  887.          Signal(subtask,sig[9]);
  888.       }
  889.       if (sigrcvd & cxsigflag) {
  890.          while(msg = (CxMsg *)GetMsg(broker_mp)) {
  891.             /* Extract necessary information from the CxMessage and return it */
  892.             msgid = CxMsgID(msg);
  893.             msgtype = CxMsgType(msg);
  894.             ReplyMsg((struct Message *)msg);
  895.             switch(msgtype) {
  896.                case CXM_IEVENT: {
  897.                   switch(msgid) {
  898.                      case EVT_HOTKEY: {
  899.                         if (paused==TRUE) break;
  900.                         if (winsigflag==0) {
  901.                            winsigflag = Open_Window();
  902.                            emn = -1;
  903.                         }
  904.                         else {
  905.                            WindowToFront(win);
  906.                         }
  907.                         break;
  908.                      }
  909.                      default: {
  910.                         break;
  911.                      }
  912.                   }
  913.                   break;
  914.                }
  915.                case CXM_COMMAND: {
  916.                   switch(msgid) {
  917.                      case CXCMD_DISABLE: {
  918.                         if (paused==FALSE) {
  919.                            Signal(subtask,sig[2]);
  920.                            Wait(sig[3]);
  921.                         }
  922.                         paused = TRUE;
  923.                         ActivateCxObj(broker, 0L);
  924.                         if (winsigflag!=0) {
  925.                            Close_Window();
  926.                            winsigflag = 0;
  927.                         }
  928.                         break;
  929.                      }
  930.                      case CXCMD_ENABLE: {
  931.                         if (paused==TRUE) {
  932.                            Signal(subtask,sig[4]);
  933.                            Wait(sig[5]);
  934.                         }
  935.                         paused = FALSE;
  936.                         ActivateCxObj(broker, 1L);
  937.                         break;
  938.                      }
  939.                      case CXCMD_KILL: {
  940.                         if (winsigflag!=0) {
  941.                            Close_Window();
  942.                            winsigflag = 0;
  943.                         }
  944.                         returnvalue = 0L;
  945.                         break;
  946.                      }
  947.                      case CXCMD_APPEAR: 
  948.                      case CXCMD_UNIQUE: {
  949.                         if (paused==TRUE) break;
  950.                         if (winsigflag==0) {
  951.                            winsigflag = Open_Window();
  952.                            emn = -1;
  953.                         }
  954.                         else {
  955.                            WindowToFront(win);
  956.                         }
  957.                         break;
  958.                      }
  959.                      case CXCMD_DISAPPEAR: {
  960.                         if (winsigflag!=0) {
  961.                            Close_Window();
  962.                            winsigflag = 0;
  963.                         }
  964.                         break;
  965.                      }
  966.                   }
  967.                   break;
  968.                }
  969.                default: {
  970.                   break;
  971.                }
  972.             }
  973.          }
  974.       }
  975.       if (sigrcvd & winsigflag) {
  976.          while (NULL != (message = GT_GetIMsg(win->UserPort))) {
  977.             class  = message->Class;
  978.             code   = message->Code;
  979.             switch (class) {
  980.                case IDCMP_CLOSEWINDOW: {
  981.                   winsigflag = 0;
  982.                   break;
  983.                }
  984.                case IDCMP_MENUPICK: {
  985.                   while ((code != MENUNULL) && (winsigflag != 0)) {
  986.                      item = ItemAddress(menstr,code);
  987.                      mennum = MENUNUM(code);
  988.                      itnum = ITEMNUM(code);
  989.                      if (mennum==0) {
  990.                         switch(itnum) {
  991.                            case 0: {
  992.                               EasyRequest(NULL,&about,NULL);
  993.                               break;
  994.                            }
  995.                            case 2: {
  996.                               winsigflag = 0;
  997.                               break;
  998.                            }
  999.                            case 3: {
  1000.                               winsigflag = 0;
  1001.                               returnvalue = 0L;
  1002.                               break;
  1003.                            }
  1004.                            default: {
  1005.                               break;
  1006.                            }
  1007.                         }
  1008.                      }
  1009.                      code = item->NextSelect;
  1010.                   }
  1011.                   break;
  1012.                }
  1013.                case IDCMP_GADGETUP: {
  1014.                   g = (struct Gadget *)message->IAddress;
  1015.                   switch(g->GadgetID) {
  1016.                      case 0: {
  1017.                         winsigflag = 0;
  1018.                         break;
  1019.                      }
  1020.                      case 1: {
  1021.                         winsigflag = 0;
  1022.                         returnvalue = 0L;
  1023.                         break;
  1024.                      }
  1025.                      case 2: {
  1026.                         if (emn!=-2) {
  1027.                            emn = -2;
  1028.                            GT_SetGadgetAttrs(gad[3],win,NULL,GA_Disabled,FALSE,TAG_END);
  1029.                            GT_SetGadgetAttrs(gad[4],win,NULL,
  1030.                                  GA_Disabled, FALSE,
  1031.                                  GTST_String, NULL,
  1032.                                  TAG_END);
  1033.                         }
  1034.                         ActivateGadget(gad[4],win,NULL);
  1035.                         break;
  1036.                      }
  1037.                      case 3: delete: {
  1038.                         if (emn!=-2) {
  1039.                            GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,~0,TAG_END);
  1040.                            DeleteEventNode(el,emn);
  1041.                            parse_mes_times(el);
  1042.                            GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,el,TAG_END);
  1043.                            Signal(subtask,sig[6]);
  1044.                            Wait(sig[7]);
  1045.                         }
  1046.                         emn = -1;
  1047.                         GT_SetGadgetAttrs(gad[3],win,NULL,GA_Disabled,TRUE,TAG_END);
  1048.                         GT_SetGadgetAttrs(gad[4],win,NULL,
  1049.                               GA_Disabled, TRUE,
  1050.                               GTST_String, NULL,
  1051.                               TAG_END);
  1052.                         break;
  1053.                      }
  1054.                      case 4: {
  1055.                         if (*(((struct StringInfo *)g->SpecialInfo)->Buffer)==NULL) {
  1056.                            goto delete;
  1057.                         }
  1058.                         else if (emn==-2) {
  1059.                            GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,~0,TAG_END);
  1060.                            AddEventNode(el,((struct StringInfo *)g->SpecialInfo)->Buffer,0);
  1061.                            parse_mes_times(el);
  1062.                            GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,el,TAG_END);
  1063.                         }
  1064.                         else {
  1065.                            GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,~0,TAG_END);
  1066.                            ChangeEventNode(el,emn,((struct StringInfo *)g->SpecialInfo)->Buffer);
  1067.                            parse_mes_times(el);
  1068.                            GT_SetGadgetAttrs(gad[5],win,NULL,GTLV_Labels,el,TAG_END);
  1069.                         }
  1070.                         emn = -1;
  1071.                         GT_SetGadgetAttrs(gad[3],win,NULL,GA_Disabled,TRUE,TAG_END);
  1072.                         GT_SetGadgetAttrs(gad[4],win,NULL,
  1073.                               GA_Disabled, TRUE,
  1074.                               GTST_String, NULL,
  1075.                               TAG_END);
  1076.                         Signal(subtask,sig[6]);
  1077.                         Wait(sig[7]);
  1078.                         break;
  1079.                      }
  1080.                      case 5: {
  1081.                         emn = code;
  1082.                         GetEventNode(el,emn,buf1);
  1083.                         GT_SetGadgetAttrs(gad[3],win,NULL,GA_Disabled,FALSE,TAG_END);
  1084.                         GT_SetGadgetAttrs(gad[4],win,NULL,
  1085.                                         GA_Disabled,FALSE,
  1086.                                         GTST_String, buf1,
  1087.                                         TAG_END);
  1088.                         p = ((struct StringInfo *)gad[4]->SpecialInfo)->Buffer;
  1089.                         if (((*p)=='#')||((*p)=='*')) {
  1090.                            p++;
  1091.                            strcpy(buf,p);
  1092.                            GT_SetGadgetAttrs(gad[4],win,NULL,GTST_String,buf,TAG_END);
  1093.                         }
  1094.                         ActivateGadget(gad[4],win,NULL);
  1095.                         break;
  1096.                      }
  1097.                      default: {
  1098.                         break;
  1099.                      }
  1100.                   }
  1101.                }
  1102.                case IDCMP_REFRESHWINDOW: {
  1103.                   GT_BeginRefresh(win);
  1104.                   GT_EndRefresh(win,TRUE);
  1105.                   break;
  1106.                }
  1107.                case IDCMP_ACTIVEWINDOW: {
  1108.                   if (emn!=-1) {
  1109.                      ActivateGadget(gad[4],win,NULL);
  1110.                   }
  1111.                   break;
  1112.                }
  1113.                default: {
  1114.                   break;
  1115.                }
  1116.             }
  1117.             GT_ReplyIMsg(message);
  1118.          }
  1119.          if (winsigflag==0) {
  1120.             Close_Window();
  1121.          }
  1122.       }
  1123.    }
  1124.    return returnvalue;
  1125. }
  1126.  
  1127. ULONG getnum(char **p)
  1128. {
  1129.    int c;
  1130.    ULONG n;
  1131.    char *s,temp[132];
  1132.  
  1133.    s = temp;
  1134.    while (1) {
  1135.       c = **p;
  1136.       if (isdigit(c)==0) break;
  1137.       *s = **p;
  1138.       s++;
  1139.       (*p)++;
  1140.    }
  1141.    *s = NULL;
  1142.    n = strtoul(temp,NULL,10);
  1143.    return n;
  1144. }
  1145.  
  1146. void parse_mes_times(struct List *list)
  1147. {
  1148.    int j,jj,c,flag,s,ms,ly;
  1149.    char *p,*p1;
  1150.    ULONG t[9],st[9],n,qflag;
  1151.    struct eNode *wn, *nn;
  1152.    
  1153.    get_sys_time(st);
  1154.    
  1155.    qflag = 0;
  1156.    
  1157.    wn = (struct eNode *)(list->lh_Head); /* First node */
  1158.    while (nn = (struct eNode *)(wn->e_Node.ln_Succ)) {
  1159.       for (j=0; j<9; j++) t[j]=0;
  1160.       if ((wn->e_ltime)!=0) {
  1161.          t[0] = wn->e_ltime;
  1162.          if ((t[0]+sleep*60)>(st[0]+1)) {
  1163.             t[0] += sleep*60;
  1164.             goto error;
  1165.          }
  1166.          else {
  1167.             t[0] = wn->e_ltime = 0;
  1168.          }
  1169.       }
  1170.       p = wn->e_Node.ln_Name;
  1171.       if ((*p==NULL)||(*p=='*')||(*p=='#')) {
  1172.          wn->e_time = 0;
  1173.          wn = nn;
  1174.          continue;
  1175.       }
  1176.       flag = 0;
  1177.       while (p<(wn->e_msg)) {
  1178.          c = *p;
  1179.          if (strchr(pts,toupper(c))==NULL) {
  1180.             flag = 1;
  1181.          }
  1182.          p++;
  1183.       }
  1184.       if (flag==1) {
  1185.          t[0] = 0;
  1186.          goto error;
  1187.       }
  1188.       p = wn->e_Node.ln_Name;
  1189.       while(*p==' ') p++;
  1190.       for (j=0; j<strlen(tt); j++) {
  1191.          if (*p==0) {
  1192.             flag = 1;
  1193.             break;
  1194.          }
  1195.          if (tt[j]==':') {
  1196.             if (*p!=tt[j]) flag=1;
  1197.             p++;
  1198.          }
  1199.          if (tt[j]=='#') {
  1200.             c = *p;
  1201.             if (isdigit(c)) {
  1202.                n = getnum(&p);
  1203.                j++;
  1204.                jj = tt[j]-48;
  1205.                t[jj] = n;
  1206.             }
  1207.             else {
  1208.                flag=1;
  1209.                p++;
  1210.                j++;
  1211.             }
  1212.          }
  1213.          if (tt[j]=='M') {
  1214.             if (((toupper((int)*p)=='A')||(toupper((int)*p)=='P'))&&(toupper((int)*(p+1))=='M')) {
  1215.                if ((t[5]<1)||(t[5]>12)) flag=1;
  1216.                t[5] = t[5]%12;
  1217.                if (toupper((int)*p)=='P') t[5]+=12;
  1218.                p += 2;
  1219.             }
  1220.          }
  1221.       }
  1222.       if (*p==' ') {
  1223.          while(*p==' ') p++;
  1224.       }
  1225.       else {
  1226.          flag=1;
  1227.       }
  1228.       if (flag==1) {
  1229.          t[0] = 0;
  1230.          goto error;
  1231.       }
  1232.       c = *p;
  1233.       if ((isdigit(c))||(c=='?')) {
  1234.          for (j=0; j<strlen(dt); j++) {
  1235.             if (*p==0) {
  1236.                flag = 1;
  1237.                break;
  1238.             }
  1239.             if (dt[j]==ddc) {
  1240.                if (*p!=dt[j]) flag=1;
  1241.                p++;
  1242.             }
  1243.             if (dt[j]=='#') {
  1244.                c = *p;
  1245.                if (isdigit(c)) {
  1246.                   n = getnum(&p);
  1247.                   j++;
  1248.                   jj = dt[j]-48;
  1249.                   if ((jj==2)||(jj==3)) n--;
  1250.                   t[jj] = n;
  1251.                }
  1252.                else if (c=='?') {
  1253.                   p++;
  1254.                   j++;
  1255.                   jj = dt[j]-48;
  1256.                   if ((jj==2)||(jj==3)) t[jj]=0;
  1257.                   else t[jj] = st[jj];
  1258.                   qflag += 1<<(jj-1);
  1259.                }
  1260.                else {
  1261.                   flag=1;
  1262.                   p++;
  1263.                   j++;
  1264.                }
  1265.             }
  1266.          }
  1267.          if (t[1]<100) {
  1268.             t[1]+=1900;
  1269.             if (t[1]<1978) t[1] += 100;
  1270.          }
  1271.       }
  1272.       else {
  1273.          ms = -1;
  1274.          while((strchr(dows,toupper((int)*p)))!=NULL) {
  1275.             c = *p;
  1276.             s = ((7+strlen(dows)-strlen(strchr(dows,toupper(c))))-st[4])%7;
  1277.             if (s==0) {
  1278.                if (t[5]<st[5]) {
  1279.                   s = 7;
  1280.                }
  1281.                else if (t[5]==st[5]) {
  1282.                   if (t[6]<st[6]) {
  1283.                      s = 7;
  1284.                   }
  1285.                   else if (t[6]==st[6]) {
  1286.                      if (t[7]<st[7]) {
  1287.                         s = 7;
  1288.                      }
  1289.                   }
  1290.                }
  1291.             }
  1292.             if ((ms==-1)||(s<ms)) ms = s;
  1293.             p++;
  1294.          }
  1295.          if ((*p!=' ')||(ms==-1)) flag=1;
  1296.          t[1] = st[1];
  1297.          t[2] = st[2];
  1298.          t[3] = st[3]+ms;
  1299.          ly = 0;
  1300.          if (((t[1]%4)==2)&&(t[2]==1)) ly = 1;
  1301.          if (t[3]>=(__months[t[2]]+ly)) {
  1302.             t[3] -= (__months[t[2]]+ly);
  1303.             t[2] += 1;
  1304.             if (t[2]>11) {
  1305.                t[2] = 0;
  1306.                t[1] += 1;
  1307.             }
  1308.          }
  1309.       }
  1310.       if (flag==1) {
  1311.          t[0] = 0;
  1312.          goto error;
  1313.       }
  1314.       t[4] = t[7] = t[8] = 0;
  1315.       if (qflag) {
  1316.          if (calc_tsec(t)==0) {
  1317.             t[0] = 0;
  1318.             goto error;
  1319.          }
  1320.          while(calc_tsec(t)<st[0]) {
  1321.             switch (qflag) {
  1322.                case 1: {
  1323.                   t[1]++;
  1324.                   break;
  1325.                }
  1326.                case 2: {
  1327.                   t[2]++;
  1328.                   ly = 0;
  1329.                   if (((t[1]%4)==2)&&(t[2]==1)) ly = 1;
  1330.                   if (t[3]>=(__months[t[2]]+ly)) t[2]++;
  1331.                   if (t[2]>11) flag=1;
  1332.                   break;
  1333.                }
  1334.                case 3: {
  1335.                   t[2]++;
  1336.                   ly = 0;
  1337.                   if (((t[1]%4)==2)&&(t[2]==1)) ly = 1;
  1338.                   if (t[3]>=(__months[t[2]]+ly)) t[2]++;
  1339.                   if (t[2]>11) {
  1340.                      t[2] = 0;
  1341.                      t[1]++;
  1342.                   }
  1343.                   break;
  1344.                }
  1345.                case 4: {
  1346.                   t[3]++;
  1347.                   ly = 0;
  1348.                   if (((t[1]%4)==2)&&(t[2]==1)) ly = 1;
  1349.                   if (t[3]>=(__months[t[2]]+ly)) flag=1;
  1350.                   break;
  1351.                }
  1352.                case 5: {
  1353.                   t[3]++;
  1354.                   ly = 0;
  1355.                   if (((t[1]%4)==2)&&(t[2]==1)) ly = 1;
  1356.                   if (t[3]>=(__months[t[2]]+ly)) {
  1357.                      t[3] = 0;
  1358.                      t[1]++;
  1359.                   }
  1360.                   break;
  1361.                }
  1362.                case 6: {
  1363.                   t[3]++;
  1364.                   ly = 0;
  1365.                   if (((t[1]%4)==2)&&(t[2]==1)) ly = 1;
  1366.                   if (t[3]>=(__months[t[2]]+ly)) {
  1367.                      t[3] = 0;
  1368.                      t[2]++;
  1369.                      if (t[2]>11) flag=1;
  1370.                   }
  1371.                   break;
  1372.                }
  1373.                case 7: {
  1374.                   t[3]++;
  1375.                   ly = 0;
  1376.                   if (((t[1]%4)==2)&&(t[2]==1)) ly = 1;
  1377.                   if (t[3]>=(__months[t[2]]+ly)) {
  1378.                      t[3] = 0;
  1379.                      t[2]++;
  1380.                      if (t[2]>11) {
  1381.                         t[2] = 0;
  1382.                         t[1]++;
  1383.                      }
  1384.                   }
  1385.                   break;
  1386.                }
  1387.                default: {
  1388.                   flag=1;
  1389.                   break;
  1390.                }
  1391.             }
  1392.             if (flag==1) {
  1393.                t[0] = 1;
  1394.                goto error;
  1395.             }
  1396.          }
  1397.       }
  1398.       t[0] = calc_tsec(t);
  1399.       
  1400. error:
  1401.       if (t[0]<=(st[0]+1)) {
  1402.          if (t[0]==0) {
  1403.             strcpy(buf,"#");
  1404.          }
  1405.          else {
  1406.             strcpy(buf,"*");
  1407.          }
  1408.          strcat(buf,wn->e_Data);
  1409.          strcpy(wn->e_Data,buf);
  1410.          p1 = wn->e_Data;
  1411.          p = strchr(p1,32);
  1412.          if (p!=NULL) {
  1413.             while(*p==32) p++;
  1414.             p1 = strchr(p,32);
  1415.             if (p1!=NULL) {
  1416.                while(*p1==32) p1++;
  1417.                wn->e_msg = p1;
  1418.             }
  1419.             else {
  1420.                wn->e_msg = NULL;
  1421.             }
  1422.          }
  1423.          else {
  1424.             wn->e_msg = NULL;
  1425.          }
  1426.          wn->e_time = 0;
  1427.       }
  1428.       else {
  1429.          wn->e_time = t[0];
  1430.       }
  1431.       wn=nn;
  1432.    }
  1433.    SortEventList(el);
  1434.    SaveEventList(el);
  1435. }
  1436.  
  1437. void subtaskcode(void)
  1438. {
  1439.    BOOL notdone = TRUE;
  1440.    ULONG error,maskt,td,mtd;
  1441.    ULONG sigrcvd,ssigrcvd;
  1442.    ULONG st[9];
  1443.    struct eNode *wn, *nn;
  1444.  
  1445.    if (TimerMP = CreatePort(0,0)) {
  1446.       if (TimerIO = (struct timerequest *) CreateExtIO(TimerMP,sizeof(struct timerequest)) ) {
  1447.          if (!(error=OpenDevice( TIMERNAME, UNIT_VBLANK,(struct IORequest *) TimerIO, 0L))) {
  1448.  
  1449.             while(notdone) {
  1450.                get_sys_time(st);
  1451.                
  1452.                mn = NULL;
  1453.                mtd = 0;
  1454.                wn = (struct eNode *)(el->lh_Head); /* First node */
  1455.                while (nn = (struct eNode *)(wn->e_Node.ln_Succ)) {
  1456.                   if ((wn->e_time)>=st[0]) {
  1457.                      td = (wn->e_time)-st[0];
  1458.                   }
  1459.                   else {
  1460.                      td = 0;
  1461.                   }
  1462.                   if (((mn==NULL)||(td<mtd))&&(td!=0)) {
  1463.                      mtd = td;
  1464.                      mn = wn;
  1465.                   }
  1466.                   wn=nn;
  1467.                }
  1468.                if (mn!=NULL) {
  1469.                   strcpy(buf,mn->e_msg);
  1470.                   myES.es_TextFormat = buf;
  1471.                   maskt = set_timer_request(mtd);
  1472.                   sigrcvd = Wait(maskt|sig[0]|sig[2]|sig[6]);
  1473.                }
  1474.                else {
  1475.                   sigrcvd = Wait(sig[0]|sig[2]|sig[6]);
  1476.                }
  1477.                
  1478.                if (sigrcvd & maskt) {
  1479.                   TimerMSG=GetMsg(TimerMP);
  1480.                   Signal(maintask,sig[8]);
  1481.                   Wait(sig[9]);
  1482.                }
  1483.                if (sigrcvd & sig[0]) {
  1484.                   if (mn!=NULL) {
  1485.                      Abort_TimerIO(maskt);
  1486.                   }
  1487.                   notdone = FALSE;
  1488.                }
  1489.                if (sigrcvd & sig[2]) {
  1490.                   if (mn!=NULL) {
  1491.                      Abort_TimerIO(maskt);
  1492.                   }
  1493.                   Signal(maintask,sig[3]);
  1494.                   ssigrcvd = Wait(sig[0]|sig[4]);
  1495.                   if (ssigrcvd & sig[4]) {
  1496.                      Signal(maintask,sig[5]);
  1497.                   }
  1498.                   else if (ssigrcvd & sig[0]) {
  1499.                      notdone = FALSE;
  1500.                   }
  1501.                }
  1502.                if (sigrcvd & sig[6]) {
  1503.                   if (mn!=NULL) {
  1504.                      Abort_TimerIO(maskt);
  1505.                   }
  1506.                   Signal(maintask,sig[7]);
  1507.                }
  1508.             }
  1509.  
  1510.             CloseDevice((struct IORequest *) TimerIO);
  1511.          }
  1512.          DeleteExtIO((struct IORequest *) TimerIO);
  1513.       }
  1514.       DeletePort(TimerMP);
  1515.    }
  1516.    Signal(maintask,sig[1]);
  1517.    Wait(0L);
  1518. }
  1519.  
  1520. void get_sys_time(ULONG *t)
  1521. {
  1522.    struct timerequest *TimerIO;
  1523.    struct MsgPort *TimerMP;
  1524.  
  1525.    LONG error;
  1526.  
  1527.    if (TimerMP = CreatePort(0,0)) {
  1528.       if (TimerIO = (struct timerequest *)CreateExtIO(TimerMP,sizeof(struct timerequest)) ) {
  1529.          if (!(error=OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerIO,0L))) {
  1530.  
  1531.             TimerIO->tr_node.io_Command = TR_GETSYSTIME;
  1532.             DoIO((struct IORequest *) TimerIO);
  1533.  
  1534.             t[8] = TimerIO->tr_time.tv_micro;
  1535.             t[0] = TimerIO->tr_time.tv_secs;
  1536.  
  1537.             calc_date(t);
  1538.  
  1539.             CloseDevice((struct IORequest *) TimerIO);
  1540.          }
  1541.          DeleteExtIO((struct IORequest *)TimerIO);
  1542.       }
  1543.       DeletePort(TimerMP);
  1544.    }
  1545. }
  1546.  
  1547. void calc_date(ULONG *t)
  1548. {
  1549.    int i;
  1550.    ULONG ly,dim;
  1551.    
  1552.    t[7] = t[0];
  1553.    t[6] = t[7]/60;
  1554.    t[5] = t[6]/60;
  1555.    t[3] = t[5]/24;
  1556.    t[7] = t[7]%60;
  1557.    t[6] = t[6]%60;
  1558.    t[5] = t[5]%24;
  1559.    t[4] = t[3]%7;
  1560.    
  1561.    t[1] = 0;
  1562.    while (t[3]>365) {
  1563.       if (t[1]%4==2) ly = 1; else ly = 0;
  1564.       t[3] -= 365+ly;
  1565.       t[1]++;
  1566.    }
  1567.    if ((t[3]==365)&&((t[1]%4)!=2)) {
  1568.       t[3] -= 365;
  1569.       t[1]++;
  1570.    }
  1571.    if (t[1]%4==2) ly = 1; else ly = 0;
  1572.    
  1573.    for (i=0; i<12; i++) {
  1574.       dim = __months[i];
  1575.       if (i==1) dim+=ly;
  1576.       if (t[3]<dim) break;
  1577.       t[3] -= dim;
  1578.    }
  1579.    t[2] = i;
  1580.    t[1] += 1978;
  1581. }
  1582.  
  1583. ULONG calc_tsec(ULONG *t)
  1584. {
  1585.    int i;
  1586.    ULONG yr,mo,dy,hr,mn,sc,lyd;
  1587.    
  1588.    
  1589.    yr = t[1] - 1978;
  1590.    mo = t[2];
  1591.    dy = t[3];
  1592.    hr = t[5];
  1593.    mn = t[6];
  1594.    sc = t[7];
  1595.  
  1596.    if ((yr<0)||(mo<0)||(dy<0)||(hr<0)||(mn<0)||(sc<0)) return 0;
  1597.    if ((mo>11)||(dy>30)||(hr>23)||(mn>59)||(sc>59)) return 0;
  1598.    
  1599.    if (((yr%4)==2)&&(mo==1)) lyd = 1; else lyd = 0;
  1600.    
  1601.    if (dy>=(__months[mo]+lyd)) return 0;   
  1602.    
  1603.    for (i=0; i<yr; i++) {
  1604.       dy += 365;
  1605.       if ((i%4)==2) dy += 1;
  1606.    }
  1607.    
  1608.    for (i=0; i<mo; i++) {
  1609.       dy += __months[i];
  1610.       if ((i==1)&&((yr%4)==2)) dy++;
  1611.    }
  1612.    
  1613.    return (dy*86400 + hr*3600 + mn*60 + sc);
  1614. }
  1615.  
  1616. ULONG set_timer_request(ULONG sec)
  1617. {
  1618.    TimerIO->tr_node.io_Command = TR_ADDREQUEST;
  1619.    TimerIO->tr_time.tv_secs   = sec;
  1620.    TimerIO->tr_time.tv_micro  = 0;
  1621.    TimerIO->tr_node.io_Message.mn_ReplyPort = TimerMP;
  1622.    SendIO((struct IORequest *)TimerIO);
  1623.    return (ULONG) (1L << (TimerIO->tr_node.io_Message.mn_ReplyPort->mp_SigBit));
  1624. }
  1625.  
  1626. void Abort_TimerIO(ULONG maskt)
  1627. {
  1628.    ULONG signals;
  1629.    
  1630.    AbortIO(TimerIO);
  1631.    WaitIO(TimerIO);
  1632.    while(1) {
  1633.       signals = SetSignal(0,0);
  1634.       if (signals & maskt) {
  1635.          SetSignal(0,maskt);
  1636.       }
  1637.       else {
  1638.          break;
  1639.       }
  1640.    }
  1641. }
  1642.  
  1643.  
  1644.