home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d564 / mscalendar.lha / MSCalendar / src.lzh / Src / cal.c next >
C/C++ Source or Header  |  1991-06-07  |  26KB  |  872 lines

  1. /* MSCalendar ! A little FreeWare-Utility from Markus Stipp
  2.    (c) Copyright 1991 by Markus Stipp, All Rights reserved.
  3.  
  4.    $Revision: 1.10 $
  5.  
  6.    $Author: mstipp $
  7.    $Date: 91/06/07 13:33:36 $
  8.  
  9.    $Log:    cal.c,v $
  10.  * Revision 1.10  91/06/07  13:33:36  mstipp
  11.  *       Bug with -f fixed (seems to work now)
  12.  *       Now uses RawKeyConvert() for Keys
  13.  * 
  14.  * Revision 1.9  91/05/30  18:03:11  mstipp
  15.  *       V1.08 always switched to current date if Clockwindow was open
  16.  *
  17.  
  18. */
  19.  
  20. /*---------------------------------------------------------------------*/
  21. /* Prototypes / Structures / Variables etc.                            */
  22. /*---------------------------------------------------------------------*/
  23.  
  24. #include "cal.h"
  25.  
  26. void Today(void);
  27. void PrintClock(void);
  28. void PrintCal(int month, int year);
  29. void InitWindow(void);
  30. void DrawLine(int x1, int y1, int x2, int y2);
  31. void HandleKeys(USHORT code,USHORT qual,APTR address);
  32. void Iconify(void);
  33. void UnIconify(void);
  34. int  DOW(int day, int month, int year);
  35. void CleanUp(int error, char* Message);
  36. TM   *GetTime(void);
  37. int  atoi(char *string);
  38. int  strlen(char *string);
  39. void exit(int error);
  40. void InitMain(void);
  41. void GetVals(void);
  42. void CheckVals(void);
  43. void DoMain(void);
  44.  
  45. static IBASE   *IntuitionBase = NULL;
  46. static GFXBASE *GfxBase = NULL;
  47. struct Library *IconBase = NULL;
  48. struct ConsoleDevice *ConsoleDevice = NULL;
  49. struct IOStdReq ioreq;
  50.  
  51. CAL     cal;
  52. TM      *tp;
  53. MSGP    *timeport;
  54. TR      tr;
  55. BYTE    BHeight;
  56. UWORD   FHeight,FWidth,FWidth2,BLine,BLine2;
  57. BOOL    gadget,winactive,tdevice,current = FALSE;
  58. TF      *FontBuf;
  59. SCR     scrbuf;
  60.  
  61. #ifdef GERMAN
  62. char   *monthname[] =
  63.   {
  64.     "Januar   ","Februar  ","März     ","April    ","Mai      ",
  65.     "Juni     ","Juli     ","August   ","September","Oktober  ",
  66.     "November ","Dezember "
  67.   };
  68. #else
  69. char   *monthname[] =
  70.   {
  71.     "January  ","February ","March    ","April    ","May      ",
  72.     "June     ","July     ","August   ","September","October  ",
  73.     "November ","December "
  74.   };
  75. #endif
  76.  
  77. USHORT daytab[] =
  78.   {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  79.  
  80.  
  81. /*---------------------------------------------------------------------*/
  82. /* The main Programs !                                                 */
  83. /*---------------------------------------------------------------------*/
  84.  
  85. /*---------------------------------------------------------------------*/
  86. /* If started from WB                                                  */
  87. /*---------------------------------------------------------------------*/
  88.  
  89. int wbmain(struct WBStartup *wbs)
  90. {
  91.  
  92. /* Variables */
  93.  
  94.  struct DiskObject *dobj;
  95.  char **toolsarray;
  96.  char *s;
  97.  int val;
  98.  BPTR olddir;
  99.  
  100.  InitMain();
  101.  
  102.  IconBase = OpenLibrary("icon.library",33);
  103.  if(IconBase == NULL)
  104.     CleanUp(RETURN_FAIL,"Can't open Icon.Library");
  105.  
  106.  olddir = CurrentDir(wbs->sm_ArgList->wa_Lock);
  107.  if(dobj= (struct DiskObject *) GetDiskObject(wbs->sm_ArgList->wa_Name));
  108.  {
  109.     toolsarray = (char **)dobj->do_ToolTypes;
  110.     if(s=(char *)FindToolType(toolsarray,"FLAGS"))
  111.     {
  112.        if(MatchToolValue(s,"BEEP"))
  113.           cal.Beep = TRUE;
  114.        if(MatchToolValue(s,"FRONT"))
  115.           cal.Front = TRUE;
  116.        if(MatchToolValue(s,"ICONIFY"))
  117.           cal.Iconify = TRUE;
  118.     }
  119.     if(s=(char *)FindToolType(toolsarray,"XPOS"))
  120.     {
  121.        val = atoi(s);
  122.        cal.xpos = val;
  123.     }
  124.     if(s=(char *)FindToolType(toolsarray,"YPOS"))
  125.     {
  126.        val = atoi(s);
  127.        cal.ypos = val;
  128.     }
  129.     if(s=(char *)FindToolType(toolsarray,"IXPOS"))
  130.     {
  131.        val = atoi(s);
  132.        cal.ixpos = val;
  133.     }
  134.     if(s=(char *)FindToolType(toolsarray,"IYPOS"))
  135.     {
  136.        val = atoi(s);
  137.        cal.iypos = val;
  138.     }
  139.     FreeDiskObject(dobj);
  140.  
  141.  }
  142.  CurrentDir(olddir);
  143.  
  144.  CloseLibrary(IconBase);
  145.  
  146.  DoMain();
  147.  CleanUp(0,NULL);
  148.  
  149. } /* wbmain */
  150.  
  151. /*---------------------------------------------------------------------*/
  152. /* If started from CLI                                                 */
  153. /*---------------------------------------------------------------------*/
  154.  
  155. int main(int ac, char **av)
  156. {
  157.  
  158.  /* Variables */
  159.  
  160.  char   *ptr;
  161.  int    i;
  162.  LONG   val;
  163.  
  164.  InitMain();
  165.  
  166. /***** Parse the given arguments *****/
  167.  
  168.  for(i = 1; i < ac; ++i)
  169.  {
  170.     ptr = av[i];
  171.     val = atoi(ptr+2);
  172.     if(*ptr != '-')
  173.        goto def;
  174.  
  175.     switch (ptr[1])
  176.     {
  177.        case 'x':
  178.           cal.xpos = val;
  179.           break;
  180.        case 'y':
  181.           cal.ypos = val;
  182.           break;
  183.        case 'u':
  184.           cal.ixpos = val;
  185.           break;
  186.        case 'v':
  187.           cal.iypos = val;
  188.           break;
  189.        case 'i':
  190.           cal.Iconify = TRUE;
  191.           break;
  192.        case 'b':
  193.           cal.Beep = TRUE;
  194.           break;
  195.        case 'f':
  196.           cal.Front = TRUE;
  197.           break;
  198.        default:   def:
  199. #ifdef GERMAN
  200.           printf("\nMSCalendar V%d.%02d GERMAN, " __DATE__ "\n",RELEASE,REVISION);
  201.           printf("(c)Copyright 1991 by Markus Stipp, All Rights Reserved\n\n");
  202.           printf("  Usage: %s [-Option] [-Option] [...]\n\n",av[0]);
  203.           printf("    -x###    X-Position vom Kalender (default 0)\n");
  204.           printf("    -y###    Y-Position vom Kalender (default 0)\n");
  205.           printf("    -u###    X-Position vom kleinen Fenster (default 0)\n");
  206.           printf("    -v###    Y-Position vom kleinen Fenster (default 0)\n");
  207.           printf("    -b       Bei vollen Stunden blitzen\n");
  208.           printf("    -f       Kleines Fenster immer im Vordergrund\n");
  209.           printf("    -i       Mit kleinem Fenster starten\n\n");
  210. #else
  211.           printf("\nMSCalendar V%d.%02d, " __DATE__ "\n",RELEASE,REVISION);
  212.           printf("(c)Copyright 1991 by Markus Stipp, All Rights Reserved\n\n");
  213.           printf("  Usage: %s [-option] [-option] [...]\n\n",av[0]);
  214.           printf("    -x###    X-Position of the Calendar (default 0)\n");
  215.           printf("    -y###    Y-Position of the Calendar (default 0)\n");
  216.           printf("    -u###    X-Position of the iconified Window (default 0)\n");
  217.           printf("    -v###    Y-Position of the iconified Window (default 0)\n");
  218.           printf("    -b       Beep at full hours\n");
  219.           printf("    -f       Put the iconified window always to front\n");
  220.           printf("    -i       Start with iconified Window\n\n");
  221. #endif
  222.           CleanUp(0,NULL);
  223.           break;
  224.     } /* switch */
  225.  }    /* for    */
  226.  
  227.  DoMain();
  228.  
  229. }           /* main */
  230.  
  231. /*---------------------------------------------------------------------*/
  232. /* Open Libraries etc.                                                 */
  233. /*---------------------------------------------------------------------*/
  234.  
  235. void InitMain(void)
  236. {
  237.  
  238.  cal.Iconify = cal.Beep = cal.Front = FALSE;  /* Default for startup */
  239.  
  240. /***** Open Libraries *****/
  241.  
  242.  IntuitionBase = (IBASE *)   OpenLibrary("intuition.library",33);
  243.  GfxBase       = (GFXBASE *) OpenLibrary("graphics.library",33);
  244.    if (GfxBase == NULL || IntuitionBase == NULL)
  245.        CleanUp(RETURN_FAIL,"Can't open Graphics- or Intuition.Library");
  246.  
  247. /***** Create a MessagePort for the Timer.Device *****/
  248.  
  249.  timeport = CreatePort(NULL,0);
  250.    if(timeport == NULL)
  251.       CleanUp(RETURN_FAIL,"Can't create Port");
  252.  
  253. /***** Open the Timer.Device *****/
  254.  
  255.  if(OpenDevice("timer.device",UNIT_MICROHZ,(IOR *) &tr,0L))
  256.     CleanUp(RETURN_FAIL,"Can't open Timer.Device");
  257.   tdevice = TRUE;
  258.  
  259. /***** Open Console Device for RawKeyConvert() *****/
  260.  
  261.  if(OpenDevice("console.device",-1L,(IOR *) &ioreq,0L))
  262.     CleanUp(RETURN_FAIL,"Can't open Console.Device");
  263.  ConsoleDevice = (struct ConsoleDevice *)ioreq.io_Device;
  264.  
  265.  cal.xpos = cal.ypos = cal.ixpos = cal.iypos = 0;
  266.  
  267. } /* InitMain */
  268.  
  269. /*---------------------------------------------------------------------*/
  270. /* Get the Screen's data and set some Variables.                       */
  271. /*---------------------------------------------------------------------*/
  272.  
  273. void GetVals(void)
  274. {
  275.  Delay(10); /* If someone changes the Font, we must wait a bit */
  276.  
  277.  Forbid();
  278.  if(!(GetScreenData(&scrbuf,sizeof(SCR),WBENCHSCREEN,NULL)))
  279.     CleanUp (RETURN_FAIL,"Can't get ScreenData");
  280.  Permit();
  281.  
  282.  FontBuf = (TF *) OpenFont(scrbuf.Font);
  283.  
  284.  BHeight        = scrbuf.BarHeight+1;
  285.  FHeight        = GfxBase->DefaultFont->tf_YSize;
  286.  FWidth         = GfxBase->DefaultFont->tf_XSize;
  287.  FWidth2        = FontBuf->tf_XSize;
  288.  BLine          = FontBuf->tf_Baseline;
  289.  BLine2         = FHeight - GfxBase->DefaultFont->tf_Baseline;
  290.  
  291.  cal.height     = BHeight + 1 + 10*(FHeight+4);
  292.  cal.width      = WEEKDAYLENGTH * FWidth + 14;
  293.  cal.iheight    = BHeight-1;
  294.  cal.iwidth     = 37*FWidth2+86;
  295.  
  296.  boxdata[2]=boxdata[4]=2*FWidth+6;
  297.  boxdata[5]=boxdata[7]=FHeight+2;
  298.  
  299.  if(cal.height > scrbuf.Height || cal.width  > scrbuf.Width)
  300.     CleanUp(RETURN_FAIL,"Window too big. Too big Font ?");
  301.  
  302.  if(FontBuf->tf_Flags & FPF_PROPORTIONAL)
  303.     cal.iwidth = 50;
  304.  else
  305.  {
  306.     if(cal.iwidth > scrbuf.Width)
  307.        CleanUp(RETURN_FAIL,"Iconified Window too big !");
  308.  }
  309.  
  310.  todayswitch.LeftEdge = cal.width/2+1;
  311.  todayswitch.TopEdge  = BHeight + 8*(FHeight +4);
  312.  todayswitch.Width    = cal.width - (cal.width/2)-5;
  313.  todayswitch.Height   = FHeight +3;
  314.  
  315.  CheckVals();
  316.  
  317. } /* GetVals */
  318.  
  319. /*---------------------------------------------------------------------*/
  320. /* Are the Values correct ?                                            */
  321. /*---------------------------------------------------------------------*/
  322.  
  323. void CheckVals(void)
  324. {
  325.  
  326.  if(cal.xpos + cal.width > scrbuf.Width)
  327.     cal.xpos = scrbuf.Width - cal.width;
  328.  
  329.  if(cal.ypos + cal.height > scrbuf.Height)
  330.     cal.ypos = scrbuf.Height - cal.height;
  331.  
  332.  if(cal.ixpos + cal.iwidth > scrbuf.Width)
  333.     cal.ixpos = scrbuf.Width - cal.iwidth;
  334.  
  335.  if(cal.iypos + cal.iheight > scrbuf.Height)
  336.     cal.iypos = scrbuf.Height - cal.iheight;
  337.  
  338. }
  339.  
  340. /*---------------------------------------------------------------------*/
  341. /* The really main part. Message-Handling etc.                         */
  342. /*---------------------------------------------------------------------*/
  343.  
  344. void DoMain(void)
  345. {
  346.  
  347.  BOOL   done = FALSE;
  348.  ULONG  class,signal,isig,tsig;
  349.  USHORT code,qual;
  350.  IMSG   *message;
  351.  MSG    *tmsg;
  352.  APTR   *address;
  353.  
  354. /***** Open the Window, now *****/
  355.  
  356.   Today();
  357.  
  358.   if(cal.Iconify)
  359.      Iconify();
  360.   else
  361.      UnIconify();
  362.  
  363. /***** Go to sleep and wait for a Message for me *****/
  364.  
  365. /* Set Values for the Timer.Device first */
  366.  
  367.  tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  368.  tr.tr_node.io_Message.mn_Node.ln_Pri = 0;
  369.  tr.tr_node.io_Message.mn_Node.ln_Name = NULL;
  370.  tr.tr_node.io_Message.mn_ReplyPort = timeport;
  371.  tr.tr_node.io_Command = TR_ADDREQUEST;
  372.  tr.tr_time.tv_secs = 0;
  373.  tr.tr_time.tv_micro = 500;
  374.  
  375.  SendIO((IOR *) &tr);
  376.  
  377.  isig = 1 << cal.calwin->UserPort->mp_SigBit;
  378.  tsig = 1 << timeport->mp_SigBit;
  379.  
  380.  while (done == FALSE)
  381.  {
  382.     signal = Wait( isig | tsig );
  383.  
  384.     if(signal & tsig)  /* If Timer-Signal */
  385.     {
  386.        while(tmsg = (MSG *) GetMsg(timeport));
  387.        {
  388.           if((cal.Front && cal.Iconify && !(cal.rp->Layer == cal.rp->Layer->LayerInfo->top_layer)))
  389.           {
  390.              WindowToFront(cal.calwin);
  391.              RefreshWindowFrame(cal.calwin);
  392.           }
  393.           PrintClock();
  394.           tr.tr_node.io_Command = TR_GETSYSTIME;
  395.           DoIO((IOR *) &tr);
  396.  
  397.           tr.tr_node.io_Command = TR_ADDREQUEST;
  398.           tr.tr_time.tv_secs = 0;
  399.           tr.tr_time.tv_micro = 1000000-tr.tr_time.tv_micro+2;
  400.           SendIO((IOR *) &tr);
  401.        }
  402.     }
  403.  
  404.     if(signal & isig)  /* If Intuition-Signal */
  405.     {
  406.        while(message = (IMSG *) GetMsg(cal.calwin->UserPort))
  407.        {
  408.           class = message->Class;
  409.           code  = message->Code;
  410.           qual  = message->Qualifier;
  411.           address = message->IAddress;
  412.  
  413.           ReplyMsg((MSG *) message);
  414.  
  415.           switch (class)
  416.           {
  417.            case CLOSEWINDOW:
  418.               AbortIO((IOR *)&tr);
  419.               WaitIO((IOR *)&tr);
  420.               done = TRUE;
  421.               break;
  422.            case RAWKEY:
  423.               ModifyIDCMP(cal.calwin,cal.calwin->IDCMPFlags & ~RAWKEY);
  424.               HandleKeys(code,qual,address);
  425.               ModifyIDCMP(cal.calwin,cal.calwin->IDCMPFlags | RAWKEY);
  426.               break;
  427.            case MOUSEBUTTONS:
  428.               switch(code)
  429.               {
  430.                case MENUUP:
  431.                  if(cal.Iconify)
  432.                     UnIconify();
  433.                  else
  434.                     Iconify();
  435.                  break;
  436.                case SELECTUP:
  437.                  gadget = FALSE;
  438.                  break;
  439.               }
  440.               break;
  441.            case ACTIVEWINDOW:
  442.               winactive = TRUE;
  443.               PrintClock();
  444.               break;
  445.            case INACTIVEWINDOW:
  446.               winactive = FALSE;
  447.               PrintClock();
  448.               break;
  449.            case GADGETDOWN:
  450.               gadget = TRUE;
  451.               break;
  452.            case GADGETUP:
  453.               Today();
  454.               PrintCal(cal.cald.m,cal.cald.y);
  455.               gadget = FALSE;
  456.               break;
  457.            default:
  458.               break;
  459.  
  460.           } /* switch          */
  461.        }    /* while (message) */
  462.     }       /* if (signal)     */
  463.  }          /* while (done)    */
  464.  
  465.  CleanUp(0,NULL);
  466.  
  467. } /* DoMain */
  468.  
  469. /*---------------------------------------------------------------------*/
  470. /* Close the Cal-Window and open the iconified One                     */
  471. /*---------------------------------------------------------------------*/
  472.  
  473. void Iconify(void)
  474. {
  475.   int winwi;
  476.  
  477.   GetVals();
  478.  
  479.   calwin_data.LeftEdge    = cal.ixpos;
  480.   calwin_data.TopEdge     = cal.iypos;
  481.   calwin_data.Width       = cal.iwidth;
  482.   calwin_data.Height      = cal.iheight;
  483.   calwin_data.Flags      &= ~(ACTIVATE);
  484.   calwin_data.IDCMPFlags &= ~RAWKEY;
  485.   calwin_data.IDCMPFlags |= (ACTIVEWINDOW|INACTIVEWINDOW);
  486.  
  487.   winactive = FALSE;
  488.  
  489.   cal.Iconify = TRUE;
  490.  
  491.   if(cal.calwin)
  492.   {
  493.      cal.xpos = cal.calwin->LeftEdge;
  494.      cal.ypos = cal.calwin->TopEdge;
  495.      CloseWindow(cal.calwin);
  496.   }
  497.  
  498.   cal.calwin = (WIN *) OpenWindow(&calwin_data);
  499.                if(cal.calwin == NULL)
  500.                   CleanUp(RETURN_FAIL,"Can't open Window");
  501.  
  502.   cal.rp = cal.calwin->RPort;                /* Set the RastPort */
  503.  
  504.   if(FontBuf->tf_Flags & FPF_PROPORTIONAL)
  505.   {
  506.      SetFont(cal.rp,FontBuf);
  507.  
  508. #ifdef GERMAN
  509.      winwi = (86+TextLength(cal.rp," Chip: 000 Fast: 0000  Zeit:00:00:00 ",37));
  510. #else
  511.      winwi = (86+TextLength(cal.rp," Chip: 000 Fast: 0000  Time:00:00:00 ",37));
  512. #endif
  513.  
  514.      if(winwi > scrbuf.Width)
  515.         CleanUp(RETURN_FAIL,"Iconified Window too big !");
  516.      if((winwi + cal.calwin->LeftEdge) > scrbuf.Width)
  517.         MoveWindow(cal.calwin,scrbuf.Width - (winwi + cal.calwin->LeftEdge),0);
  518.      SizeWindow(cal.calwin,winwi - cal.calwin->Width,0);
  519.   }
  520.   SetFont(cal.rp,GfxBase->DefaultFont);
  521.  
  522.   PrintClock();
  523.  
  524. }
  525.  
  526. /*---------------------------------------------------------------------*/
  527. /* Close the iconified Window and open the Cal-Window                  */
  528. /*---------------------------------------------------------------------*/
  529.  
  530. void UnIconify(void)
  531. {
  532.  
  533.   GetVals();
  534.  
  535.   calwin_data.LeftEdge    = cal.xpos;
  536.   calwin_data.TopEdge     = cal.ypos;
  537.   calwin_data.Width       = cal.width;
  538.   calwin_data.Height      = cal.height;
  539.   calwin_data.Flags      |= (ACTIVATE);
  540.   calwin_data.IDCMPFlags |= RAWKEY;
  541.   calwin_data.IDCMPFlags &= ~(ACTIVEWINDOW|INACTIVEWINDOW);
  542.   winactive = TRUE;
  543.  
  544.   cal.Iconify = FALSE;
  545.  
  546.   if(cal.calwin)
  547.   {
  548.      cal.ixpos = cal.calwin->LeftEdge;
  549.      cal.iypos  = cal.calwin->TopEdge;
  550.      CloseWindow(cal.calwin);
  551.   }
  552.  
  553.   cal.calwin = (WIN *) OpenWindow(&calwin_data);
  554.                if (cal.calwin == NULL)
  555.                    CleanUp(RETURN_FAIL,"Can't open Window");
  556.  
  557.   cal.rp = cal.calwin->RPort;                /* Set the RastPort */
  558.  
  559.   InitWindow();
  560. }
  561.  
  562. /*---------------------------------------------------------------------*/
  563. /* This Procedure draws the Window-Background                          */
  564. /*---------------------------------------------------------------------*/
  565.  
  566. void InitWindow(void)
  567. {
  568.   SetFont(cal.rp,GfxBase->DefaultFont);
  569.  
  570.   SetBPen(cal.rp,1);
  571.   SetAPen(cal.rp,1);
  572.   RectFill(cal.rp,cal.calwin->BorderLeft,BHeight,cal.calwin->Width - (cal.calwin->BorderRight+1),BHeight + 10* (FHeight +4) - cal.calwin->BorderBottom);
  573.   SetAPen(cal.rp,0);
  574.   DrawLine(cal.calwin->BorderLeft,BHeight + (FHeight +4)-1,cal.calwin->Width-(cal.calwin->BorderRight+1), BHeight + (FHeight +4)-1);
  575.   DrawLine(cal.calwin->BorderLeft,BHeight + 2*(FHeight +4)-1,cal.calwin->Width-(cal.calwin->BorderRight+1), BHeight + 2*(FHeight +4)-1);
  576.   DrawLine(cal.calwin->BorderLeft,BHeight + 8*(FHeight +4)-1,cal.calwin->Width-(cal.calwin->BorderRight+1), BHeight + 8*(FHeight +4)-1);
  577.   DrawLine(cal.calwin->BorderLeft,BHeight + 9*(FHeight +4)-1,cal.calwin->Width-(cal.calwin->BorderRight+1), BHeight + 9*(FHeight +4)-1);
  578.   DrawLine(cal.calwin->Width/2,BHeight + 8*(FHeight +4)-2,cal.calwin->Width/2, BHeight + 10*(FHeight +4) -2);
  579.  
  580.   Move(cal.rp,cal.calwin->BorderLeft+4,BHeight + 2*(FHeight+4) - BLine2-2);
  581.   Text(cal.rp,WEEKDAYS,WEEKDAYLENGTH);
  582.  
  583.   PrintCal(cal.cald.m,cal.cald.y);
  584.   PrintClock();
  585. }
  586.  
  587. /*---------------------------------------------------------------------*/
  588. /* This Procedure prints out the Calendar-entries. It takes the month  */
  589. /* and the year as arguments.                                          */
  590. /* month: 0-11                                                         */
  591. /* year : 1901-2099                                                    */
  592. /*---------------------------------------------------------------------*/
  593.  
  594. void PrintCal(int month, int year)
  595. {
  596.   char  buffer[5];
  597.   int leap,i,j;
  598.   int weekday = DOW(1,month,year);
  599.  
  600.   SetAPen(cal.rp,1);
  601.   RectFill(cal.rp,cal.calwin->BorderLeft,BHeight + 2*(FHeight+4),cal.calwin->Width - (cal.calwin->BorderRight+1),BHeight + 8*(FHeight+4)-2);
  602.   SetAPen(cal.rp,2);
  603.   Move(cal.rp,50,BHeight+(FHeight+4)-BLine2-2);
  604.   Text(cal.rp,monthname[month],9);
  605.   sprintf(buffer,"%d",year);
  606.   Move(cal.rp,30+calwin_data.Width/2,BHeight+(FHeight+4)-BLine2-2);
  607.   Text(cal.rp,buffer,strlen(buffer));
  608.  
  609.   leap = year%4 == 0 && year%100 !=0 || year%400 == 0;
  610.   if(leap == 1)
  611.      daytab[1] = 29;
  612.  
  613.   if(year == tp->tm_year+1900 && month == tp->tm_mon)
  614.      current = TRUE;
  615.   else
  616.      current = FALSE;
  617.  
  618.   for(i = 1, j = 3; i <= daytab[month]; i++)
  619.   {
  620.     if(weekday == 7)
  621.     {
  622.        weekday = 0;
  623.        j++;
  624.     }
  625.     sprintf(buffer,"%2d",i);
  626.     if(weekday == 5)
  627.        SetAPen(cal.rp,0);
  628.     if(weekday == 6)
  629.        SetAPen(cal.rp,3);
  630.     Move(cal.rp,cal.calwin->BorderLeft+8+weekday*(4*FWidth), BHeight+j*(FHeight+4)-BLine2-2);
  631.     Text(cal.rp,buffer,2);
  632.     if(tp->tm_mday == i && current)
  633.        DrawBorder(cal.rp,&dayborder,7+weekday*(4*FWidth),BHeight+(j-1)*(FHeight+4));
  634.     weekday++;
  635.     SetAPen(cal.rp,2);
  636.   }
  637.   daytab[1] = 28;
  638. }
  639.  
  640. /*---------------------------------------------------------------------*/
  641. /* This Procedure prints the Clock and the free Memory                 */
  642. /*---------------------------------------------------------------------*/
  643.  
  644. void PrintClock(void)
  645. {
  646.   ULONG  Chip,Fast;
  647.   char buffer[37];
  648.   TF  *oldfont;
  649.  
  650.   Chip = (AvailMem(MEMF_CHIP)/1024);
  651.   Fast = (AvailMem(MEMF_FAST)/1024);
  652.  
  653.   tp = GetTime();
  654.   if(tp->tm_sec == 0 && tp->tm_min == 0 && cal.Beep)
  655.      DisplayBeep(cal.calwin->WScreen);
  656.  
  657.   if((cal.cald.d != tp->tm_mday || cal.cald.m != tp->tm_mon || cal.cald.y != tp->tm_year+1900) && current)
  658.   {
  659.      cal.cald.d = tp->tm_mday;
  660.      cal.cald.m = tp->tm_mon;
  661.      cal.cald.y = tp->tm_year+1900;
  662.      if(!cal.Iconify)
  663.         PrintCal(cal.cald.m,cal.cald.y);
  664.   }
  665.  
  666.  
  667.   if(cal.Iconify)
  668.   {
  669.      oldfont = cal.calwin->RPort->Font;
  670.      SetAPen(cal.rp,1);
  671.      if(winactive)
  672.         SetBPen(cal.rp,3);
  673.      else
  674.         SetBPen(cal.rp,0);
  675.  
  676.      SetFont(cal.rp,FontBuf);
  677.  
  678. #ifdef GERMAN
  679.      sprintf(buffer," Chip:%4d Fast:%5d  Zeit:%2d:%02d:%02d ",Chip,Fast,tp->tm_hour,tp->tm_min,tp->tm_sec);
  680. #else
  681.      sprintf(buffer," Chip:%4d Fast:%5d  Time:%2d:%02d:%02d ",Chip,Fast,tp->tm_hour,tp->tm_min,tp->tm_sec);
  682. #endif
  683.  
  684.      Move(cal.rp,30,BLine+1);
  685.      Text(cal.rp,buffer,37);
  686.      SetFont(cal.rp,oldfont);
  687.   }
  688.   else
  689.   {
  690.      SetAPen(cal.rp,0);
  691.  
  692.      sprintf(buffer,"%02d:%02d:%02d",tp->tm_hour, tp->tm_min, tp->tm_sec);
  693.      Move(cal.rp,(calwin_data.Width/2-8*FWidth)/2,BHeight+9*(FHeight+4)-BLine2-2);
  694.      Text(cal.rp,buffer,8);
  695.  
  696.      if(!gadget)
  697.      {
  698.         sprintf(buffer,"%02d-%02d-%04d",tp->tm_mday,tp->tm_mon+1,tp->tm_year+1900);
  699.         Move(cal.rp,(calwin_data.Width/2-10*FWidth)/2+calwin_data.Width/2,BHeight+9*(FHeight+4)-BLine2-2);
  700.         Text(cal.rp,buffer,10);
  701.      }
  702.  
  703.      sprintf(buffer,"Chip: %5d",Chip);
  704.      Move(cal.rp,10,BHeight+10*(FHeight+4)-BLine2-2);
  705.      Text(cal.rp,buffer,11);
  706.  
  707.      sprintf(buffer,"Fast: %5d",Fast);
  708.      Move(cal.rp,calwin_data.Width/2+10,BHeight+10*(FHeight+4)-BLine2-2);
  709.      Text(cal.rp,buffer,11);
  710.   } /* ifelse Iconify */
  711.  
  712. }
  713.  
  714. /*---------------------------------------------------------------------*/
  715. /* This Procedure draws a Line with the given coords                   */
  716. /*---------------------------------------------------------------------*/
  717.  
  718. void DrawLine(int x1, int y1, int x2, int y2)
  719. {
  720.   Move(cal.rp, x1,y1);
  721.   Draw(cal.rp, x2,y2);
  722. }
  723.  
  724. /*---------------------------------------------------------------------*/
  725. /* This Function gets the current date.                                */
  726. /*---------------------------------------------------------------------*/
  727.  
  728. TM *GetTime(void)
  729. {
  730.   time_t t = time(NULL);
  731.  
  732.   return (localtime(&t));
  733. }
  734.  
  735. /*---------------------------------------------------------------------*/
  736. /* This Function returns the weekday of the given date.                */
  737. /* d : 1-31                                                            */
  738. /* m : 0-11                                                            */
  739. /* y : 1901-2099 (other years return wrong values)                     */
  740. /* return : 0-6 (0=monday 1=tuesday ...)                               */
  741. /*---------------------------------------------------------------------*/
  742.  
  743. int DOW( int d, int m, int y )
  744. {
  745.    return (( 3*y - (7*(y+((m+1)+9)/12))/4 + (23*(m+1))/9 + d + 1 ) % 7);
  746. }
  747.  
  748. /*---------------------------------------------------------------------*/
  749. /* This Procedure makes the Key-Handling. It takes the Key and the     */
  750. /* Qualifier pressed and changes the Calendar-Input                    */
  751. /*---------------------------------------------------------------------*/
  752.  
  753. void HandleKeys(USHORT code,USHORT qual,APTR address)
  754. {
  755.  
  756.   UBYTE buffer[1];
  757.   int numchars;
  758.   static struct InputEvent ievent = {NULL,IECLASS_RAWKEY,0,0,0};
  759.  
  760.   switch (code)
  761.   {
  762.      case RIGHT:
  763.         if(qual == SHIFT || qual == SHIFTR)
  764.            cal.cald.m += 3;
  765.         else
  766.            cal.cald.m += 1;
  767.         if(cal.cald.m >= 12)
  768.         {
  769.            cal.cald.m -= 12;
  770.            cal.cald.y++;
  771.            if(cal.cald.y >= 2100)
  772.               cal.cald.y -= 200;
  773.            if(cal.cald.y <= 1900)
  774.               cal.cald.y++;
  775.         }
  776.         PrintCal(cal.cald.m, cal.cald.y);
  777.         break;
  778.      case LEFT:
  779.         if(qual == SHIFT || qual == SHIFTR)
  780.            cal.cald.m -= 3;
  781.         else
  782.            cal.cald.m -= 1;
  783.         if(cal.cald.m <= -1)
  784.         {
  785.            cal.cald.m += 12;
  786.            cal.cald.y--;
  787.            if(cal.cald.y <= 1900)
  788.               cal.cald.y += 200;
  789.            if(cal.cald.y >= 2100)
  790.               cal.cald.y--;
  791.         }
  792.         PrintCal(cal.cald.m, cal.cald.y);
  793.         break;
  794.      case UP:
  795.         if(qual == SHIFT || qual == SHIFTR)
  796.            cal.cald.y += 10;
  797.         else
  798.            cal.cald.y += 1;
  799.         if(cal.cald.y >= 2100)
  800.            cal.cald.y -= 200;
  801.         if(cal.cald.y <= 1900)
  802.            cal.cald.y++;
  803.         PrintCal(cal.cald.m, cal.cald.y);
  804.         break;
  805.      case DOWN:
  806.         if(qual == SHIFT || qual == SHIFTR)
  807.            cal.cald.y -= 10;
  808.         else
  809.            cal.cald.y -= 1;
  810.         if(cal.cald.y <= 1900)
  811.            cal.cald.y += 200;
  812.         if(cal.cald.y >= 2100)
  813.            cal.cald.y--;
  814.         PrintCal(cal.cald.m, cal.cald.y);
  815.         break;
  816.      default:
  817.         ievent.ie_Code = code;
  818.         ievent.ie_Qualifier = qual;
  819.         ievent.ie_position.ie_addr = *((APTR*) address);
  820.         numchars = RawKeyConvert(&ievent,buffer,1,0L);
  821.         if (numchars == 1)
  822.         {
  823.           switch(buffer[0])
  824.           {
  825.             case 'i':
  826.                Iconify();
  827.                break;
  828.             case 't':
  829.                Today();
  830.                PrintCal(cal.cald.m,cal.cald.y);
  831.                break;
  832.             default:
  833.                break;
  834.           }
  835.         }
  836.         break;
  837.   }
  838. }
  839.  
  840. /*---------------------------------------------------------------------*/
  841. /* This Procedure switches the Calendar to Today                       */
  842. /*---------------------------------------------------------------------*/
  843.  
  844. void Today(void)
  845. {
  846.   tp = GetTime();
  847.   cal.cald.d   = tp->tm_mday;
  848.   cal.cald.m   = tp->tm_mon;
  849.   cal.cald.y   = tp->tm_year+1900;
  850.   current = TRUE;
  851. }
  852.  
  853. /*---------------------------------------------------------------------*/
  854. /* This Function cleans all up. It takes an Errorcode which will be    */
  855. /* returned to the  CLI                                                */
  856. /*---------------------------------------------------------------------*/
  857.  
  858. void CleanUp(int error, char *Message)
  859. {
  860.   if(cal.calwin)    CloseWindow(cal.calwin);
  861.   if(GfxBase)       CloseLibrary((struct Library *)GfxBase);
  862.   if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  863.   if(timeport)      DeletePort(timeport);
  864.   if(tdevice)       CloseDevice((IOR *) &tr);
  865.   if(ConsoleDevice) CloseDevice((IOR *) &ioreq);
  866.  
  867.   if(Message)       printf("MSCal: %s\n",Message);
  868.   exit(error);
  869. }
  870.  
  871.  
  872.