home *** CD-ROM | disk | FTP | other *** search
/ C/C++ User's Journal & Wi…eveloper's Journal Tools / C-C__Users_Journal_and_Windows_Developers_Journal_Tools_1997.iso / smxdemo / windemo / ddemo.c next >
Encoding:
C/C++ Source or Header  |  1993-07-12  |  30.7 KB  |  1,057 lines

  1. /*
  2. * DDEMO.C                                                  Version 2.1
  3. *
  4. * DOSdemo module. Contains code to demonstrate use of smx with MS-DOS,
  5. *                 or equivalents.     
  6. *
  7. * Copyright (c) 1990-1993 Micro Digital Associates, Inc. 
  8. *               All Rights Reserved.
  9. *
  10. * Author: Ralph Moore
  11. * Adapted for smxWindows Demo by David Moore
  12. *
  13. ***********************************************************************/
  14.  
  15. #include    "ddemo.h"
  16. #include    <stdio.h>
  17. #include    <string.h>
  18. #include    <stdlib.h>
  19.  
  20. #define MSG_LEN  25
  21. #define Ctrl_D    4
  22. #define Tab       9
  23.  
  24.  
  25. #if __cplusplus
  26.  extern "C" {
  27.  void    win_init(...);
  28.  void    welcome(...);
  29.  void    disk_demo_main(...);
  30.  void    win_task_init(...);
  31.  void    win_task_main(...);
  32.  void    slice_init(...);
  33.  void    ts_control_main(...);
  34.  void    slice_a_main(...);
  35.  void    slice_b_main(...);
  36.  void    slice_c_main(...);
  37.  void    sleeper_main(...);
  38.  void    msg_init(...);
  39.  void    msg_task_main(...);
  40.  void    msg_a_task_main(...);
  41.  void    msg_b_task_main(...);
  42.  void    msg_c_task_main(...);
  43.  void    msg_d_task_main(...);
  44.  void    msg_e_task_main(...);
  45.  void    clear_msg_wins_main(...); 
  46.  void    suspender_main(...);
  47.  void    opcon_main(...);
  48.  void    democon_main(...);
  49.  void    errgen_main(...);
  50.  void    swap_screen(...);
  51.  }
  52. #else
  53.  void    win_init(void);
  54.  void    welcome(void);
  55.  void    disk_demo_main(void);
  56.  void    win_task_init(void);
  57.  void    win_task_main(void);
  58.  void    slice_init(void);
  59.  void    ts_control_main(void);
  60.  void    slice_a_main(void);
  61.  void    slice_b_main(void);
  62.  void    slice_c_main(void);
  63.  void    sleeper_main(void);
  64.  void    msg_init(void);
  65.  void    msg_task_main(void);
  66.  void    msg_a_task_main(void);
  67.  void    msg_b_task_main(void);
  68.  void    msg_c_task_main(void);
  69.  void    msg_d_task_main(void);
  70.  void    msg_e_task_main(void);
  71.  void    clear_msg_wins_main(void); 
  72.  void    suspender_main(void);
  73.  void    opcon_main(void);
  74.  void    democon_main(void);
  75.  void    errgen_main(void);
  76.  void    swap_screen(void);
  77. #endif
  78.  
  79. char     buffer[10];         /* output buffer */ 
  80. long     near disk_reads;    /* disk read counter */
  81. byte     near fbuf[10000];   /* file buffer */
  82.  
  83. int      welcome_win;      /* opening window */
  84.  
  85. /* windows for window manipulation demo */
  86. int      win_intro_win;   /* to display introductory message */
  87. int      status_win;      /* handle of status window */
  88. int      windows[5];      /* array of window handles */
  89.  
  90. /* windows for time slicing demo */
  91. int      ts_intro_win;   /* to display introductory message */
  92. int      ts_win_a;
  93. int      ts_win_b;
  94. int      ts_win_c;
  95.  
  96. /* windows for message sending demo */
  97. int      msg_intro_win;
  98. int      msg_source_win;
  99. int      msg_win_a;
  100. int      msg_win_b;
  101. int      msg_win_c;
  102. int      msg_win_d;
  103. int      msg_win_e;
  104.  
  105. PXCB_PTR democon_pipe;
  106. extern PXCB_PTR  Wn_KbdPipe;
  107. extern SCB_PTR   Wn_SingleSem;
  108.  
  109. TCB_PTR  near disk_demo;
  110. TCB_PTR  near win_task;
  111.  
  112. TCB_PTR  near ts_control;
  113. TCB_PTR  near slice_a;
  114. TCB_PTR  near slice_b;
  115. TCB_PTR  near slice_c;
  116.  
  117. TCB_PTR  near msg_task;
  118. TCB_PTR  near msg_a_task;
  119. TCB_PTR  near msg_b_task;
  120. TCB_PTR  near msg_c_task;
  121. TCB_PTR  near msg_d_task;
  122. TCB_PTR  near msg_e_task;
  123. TCB_PTR  near clear_msg_wins_task;
  124.  
  125. TCB_PTR  near sleeper;
  126. TCB_PTR  near suspender;
  127. TCB_PTR  near errgen;
  128. TCB_PTR  opcon;
  129. TCB_PTR  democon;
  130.  
  131. XCB_PTR  free_msgs;
  132. XCB_PTR  msg_a_xchg;
  133. XCB_PTR  msg_b_xchg;
  134. XCB_PTR  msg_c_xchg;
  135. XCB_PTR  msg_d_xchg;
  136. XCB_PTR  msg_e_xchg;
  137.  
  138. int      msg_delay = 18;   /* length of pause (ticks) between each send of message */
  139.  
  140.  
  141. void _cdecl    demo_init()
  142. {
  143.    MCB_PTR  democon_buf;   /* buffer to hold characters sent to democon_pipe */
  144.  
  145.    win_init();   /* initialize system for using smxWindows */
  146.    Wn_RawDisplay (22, 0, "Hit Esc to quit.", WN_BCKBLK | WN_FGNYEL);
  147.    Wn_RawDisplay (22, 49, "^D = Done (go on to next demo)", WN_BCKBLK | WN_FGNBLU |WN_INTEN);
  148.    democon_pipe = create_cx(PIPE);
  149.    democon_buf = create_nmsg(NULL, 20);
  150.    put_msg(democon_buf, 80, democon_pipe);
  151.    BUILD_HT(democon_pipe, "democon_pipe");
  152.  
  153.    opcon = create_task(opcon_main, NORM, 0);
  154.    BUILD_HT(opcon, "opcon");
  155.    start(opcon);
  156.  
  157.    democon = create_task(democon_main, NORM, 0);
  158.    BUILD_HT(democon, "democon");
  159.    BUILD_HT(Wn_SingleSem, "Wn_SingleSem");
  160.  
  161.    errgen = create_task(errgen_main, HI, 0);
  162.  
  163.    BUILD_HT(errgen, "errgen");
  164.    BUILD_HT((VOID_PTR)keep_time, "keep_time");
  165.  
  166.    start(democon);
  167. }
  168.  
  169. void _cdecl    win_init()    /* performs initialization specific to smxWindows */
  170.    {
  171.    MCB_PTR  Wn_KbdPipeBuffer;
  172.  
  173.    Wn_Init();
  174.    Wn_KbdPipe = create_cx(PIPE);
  175.    Wn_KbdPipeBuffer = create_nmsg(NULL, 80);
  176.    put_msg(Wn_KbdPipeBuffer, 80, Wn_KbdPipe);
  177.    BUILD_HT(Wn_KbdPipe, "Wn_KbdPipe");
  178.    }
  179.  
  180.  
  181. void _cdecl    opcon_main(void)
  182. {
  183.    char  key;
  184.  
  185.    while(key = (char)pget_char(op_pipe, INF))
  186.       {
  187.       if(key == Esc)
  188.          {
  189.          Wn_Exit();
  190.          start(exitx);
  191.          }
  192.       else if(key == Ctrl_S)
  193.          {
  194.          swap_screen();
  195.          kbd_pipe = op_pipe;
  196.          }
  197.       else
  198.          pput_char(key, democon_pipe, INF);  /* pass key on to democon */
  199.       }
  200. }
  201.  
  202.  
  203. /********* Demo Control *********/
  204. /*~D*/
  205.  
  206. void _cdecl    democon_main(void)
  207.    {
  208.    int   i;
  209.    char  key;
  210.  
  211.    unlock();
  212.  
  213.    /* display welcome window */
  214.    welcome();
  215.  
  216.    /* start first action */
  217.    win_task_init();
  218.  
  219.    while(key = (char)pget_char(democon_pipe, INF))
  220.    {
  221.    if (key == Ctrl_D)     /* if Ctrl D, go on to next demo (action) */
  222.       {
  223.       test (Wn_SingleSem, INF);   /* wait until current smxWindows call finishes */
  224.       signal (Wn_SingleSem);      /* nec. since test resets sem counter */
  225. //      count (2, ticks, INF);      /* allows windows functions to execute return statement */
  226.  
  227.       if (win_task)     /* if win_task exists */
  228.          {
  229.          /* delete windows demo task */
  230.          LOCK();
  231.          if (delete_task(win_task)) win_task = NULL;
  232.          unlock();
  233.  
  234.          /* delete windows (if they exist) */
  235.          for (i = 4; i >= 0; i--)
  236.             {
  237.             if (windows[i])
  238.                {
  239.                Wn_Delete (windows[i]);
  240.                windows[i] = 0;
  241.                }
  242.             }
  243.          if (status_win)     Wn_Delete (status_win);
  244.          if (win_intro_win)  Wn_Delete (win_intro_win);
  245.          status_win = 0;
  246.          win_intro_win = 0;      
  247.  
  248.          /* start time slicing demo */   
  249.          slice_init();   
  250.          }
  251.       else if (ts_control)   /* if time slice tasks exist */
  252.          {
  253.          /* delete all time slicing tasks: */
  254.          LOCK();
  255.          if (delete_task(ts_control))  ts_control = NULL;
  256.          if (delete_task(slice_a))     slice_a = NULL;
  257.          if (delete_task(slice_b))     slice_b = NULL;
  258.          if (delete_task(slice_c))     slice_c = NULL;
  259.          unlock();
  260.  
  261.          /* delete windows (if they exist) */
  262.          if (ts_win_c)      Wn_Delete (ts_win_c);
  263.          if (ts_win_b)      Wn_Delete (ts_win_b);
  264.          if (ts_win_a)      Wn_Delete (ts_win_a);
  265.          if (ts_intro_win)  Wn_Delete (ts_intro_win);
  266.          ts_win_c = 0;
  267.          ts_win_b = 0;
  268.          ts_win_a = 0;
  269.          ts_intro_win = 0;
  270.  
  271.          /* start the message sending demo */        
  272.          msg_init();
  273.          }
  274.       else if (msg_task)   /* if message sending tasks exist */
  275.          {
  276.          /* delete all message sending tasks */
  277.          LOCK();
  278.          if (delete_task(msg_task))             msg_task = NULL;
  279.          if (delete_task(msg_a_task))           msg_a_task = NULL;
  280.          if (delete_task(msg_b_task))           msg_b_task = NULL;
  281.          if (delete_task(msg_c_task))           msg_c_task = NULL;
  282.          if (delete_task(msg_d_task))           msg_d_task = NULL;
  283.          if (delete_task(msg_e_task))           msg_e_task = NULL;
  284.          if (delete_task(clear_msg_wins_task))  clear_msg_wins_task = NULL;
  285.          unlock();
  286.  
  287.          /* delete windows (if they exist) */
  288.          if (msg_source_win)  Wn_Delete (msg_source_win);
  289.          if (msg_win_a)       Wn_Delete (msg_win_a);
  290.          if (msg_win_b)       Wn_Delete (msg_win_b);
  291.          if (msg_win_c)       Wn_Delete (msg_win_c);
  292.          if (msg_win_d)       Wn_Delete (msg_win_d);
  293.          if (msg_win_e)       Wn_Delete (msg_win_e);
  294.          if (msg_intro_win)   Wn_Delete (msg_intro_win);
  295.          msg_source_win = 0;
  296.          msg_win_a = 0;
  297.          msg_win_b = 0;
  298.          msg_win_c = 0;
  299.          msg_win_d = 0;
  300.          msg_win_e = 0;
  301.          msg_intro_win = 0;
  302.  
  303.          /* start windows demo task again */
  304.          win_task_init();
  305.          }
  306.       }
  307.    else if (key == Tab)
  308.       {
  309.       /* put code to select next task and highlight selected task's window */
  310.       }
  311.    else if (msg_task)
  312.       pput_char(key, Wn_KbdPipe, INF);  /* pass key on to windows functions */
  313.    }  
  314.    }
  315.  
  316.  
  317. void _cdecl    welcome(void)
  318.    {
  319.    UCHAR  color;
  320.  
  321.    Wn_BorderAtt = 0;
  322.    Wn_BorderAtt = WN_BCKBLK | WN_FGNWHT | WN_INTEN;
  323.    welcome_win = Wn_Create (2, 26, 3, 27, 1, 0, 0, 0);
  324.    Wn_Display (welcome_win, 1, 2, "Welcome to the smx Demo", WN_BCKBLK | WN_FGNWHT);
  325.    for (color = 0x09; color <= 0x0F; color++)
  326.       {
  327.       count(9, ticks, INF);
  328.       Wn_SetAttr (welcome_win, 1, 1, 25, (UCHAR)((UCHAR)WN_BCKBLK | color));
  329.       }
  330.    count(36, ticks, INF);
  331.    Wn_Delete (welcome_win);
  332.    }
  333.  
  334. /********* smxWindows Demo *********/
  335. /*~W*/
  336.  
  337. void _cdecl    win_task_init(void)
  338.    {
  339.    win_task = create_task(win_task_main, LO, 0);
  340.    BUILD_HT(win_task, "win_task");
  341.    start(win_task);
  342.    }
  343.  
  344.  
  345. void _cdecl    win_task_main(void)
  346.    {
  347.    int  i;               /* index into array */
  348.    UCHAR  status_bord = WN_BCKBLK | WN_FGNWHT | WN_INTEN;
  349.    UCHAR  status_text = WN_BCKBLK | WN_FGNMAG | WN_INTEN;
  350.    UCHAR  status_text_dim = WN_BCKBLK | WN_FGNMAG;
  351.    char   *status_str;
  352.  
  353.    unlock();
  354.  
  355.    /* Display an introductory window */
  356.  
  357.    LOCK();
  358.    Wn_BorderAtt = 0;
  359.    Wn_BorderAtt = WN_BCKBLK | WN_FGNBRN;
  360.    win_intro_win = Wn_Create (0, 24, 3, 33, 1, 0, 0, 0);
  361.    Wn_Display (win_intro_win, 1, 2, "Here's What smxWindows Can Do", WN_BCKBLK | WN_FGNGRN);
  362.    Wn_BorderAtt = 0;
  363.    unlock();
  364.  
  365.    count(36, ticks, INF);
  366.  
  367.    LOCK();
  368.    Wn_BorderAtt = status_bord;
  369.    status_win = Wn_Create (4, 56, 8, 17, 2, 1, 0, "Status Window");
  370.    Wn_Display (status_win, 4, 0, ">               <", status_text);
  371.    unlock();
  372.  
  373.    while(TRUE)
  374.       {
  375.       LOCK();
  376.       Wn_BorderAtt = 0;                          /* clear the attributes */
  377.       Wn_BorderAtt = WN_BCKBLK | WN_FGNYEL;      /* set new attributes */
  378.       Wn_Display (status_win, 4, 1, " Wn_Create(A)  ", status_text);
  379.       windows[0] = Wn_Create (9, 20, 10, 32, 1, 0, "A", 0);
  380.       unlock();
  381.  
  382.       count(18, ticks, INF);
  383.       Wn_BorderAtt = 0;
  384.       Wn_BorderAtt = WN_BCKBLK | WN_FGNRED | WN_INTEN;
  385.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  386.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  387.       count(18, ticks, INF);
  388.       
  389.       LOCK();
  390.       Wn_Display (status_win, 4, 1, " Wn_Create(B)  ", status_text);
  391.       windows[1] = Wn_Create (8, 17, 10, 32, 1, 0, "B", 0);
  392.       unlock();
  393.  
  394.       count(18, ticks, INF);
  395.       Wn_BorderAtt = 0;
  396.       Wn_BorderAtt = WN_BCKBLK | WN_FGNMAG | WN_INTEN;
  397.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  398.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  399.       count(18, ticks, INF);
  400.       
  401.       LOCK();
  402.       Wn_Display (status_win, 4, 1, " Wn_Create(C)  ", status_text);
  403.       windows[2] = Wn_Create (7, 14, 10, 32, 1, 0, "C", 0);
  404.       unlock();
  405.  
  406.       count(18, ticks, INF);
  407.       Wn_BorderAtt = 0;
  408.       Wn_BorderAtt = WN_BCKBLK | WN_FGNWHT | WN_INTEN;
  409.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  410.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  411.       count(18, ticks, INF);
  412.       
  413.       LOCK();
  414.       Wn_Display (status_win, 4, 1, " Wn_Create(D)  ", status_text);
  415.       windows[3] = Wn_Create (6, 11, 10, 32, 1, 0, "D", 0);
  416.       unlock();
  417.  
  418.       count(18, ticks, INF);
  419.       Wn_BorderAtt = 0;
  420.       Wn_BorderAtt = WN_BCKBLK | WN_FGNBLU | WN_INTEN;
  421.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  422.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  423.       count(18, ticks, INF);
  424.       
  425.       LOCK();
  426.       Wn_Display (status_win, 4, 1, " Wn_Create(E)  ", status_text);
  427.       windows[4] = Wn_Create (5, 8, 10, 32, 1, 0, "E", 0);
  428.       unlock();
  429.  
  430.       for (i = 3; i >= 0; i--)
  431.          {
  432.          count(36, ticks, INF);
  433.          Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  434.          Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  435.          count(18, ticks, INF);
  436.          switch (i)
  437.             {
  438.             case 0 : status_str = " Wn_Top(A)     "; break;
  439.             case 1 : status_str = " Wn_Top(B)     "; break;
  440.             case 2 : status_str = " Wn_Top(C)     "; break;
  441.             case 3 : status_str = " Wn_Top(D)     ";
  442.             }
  443.          Wn_Display (status_win, 4, 1, status_str, status_text);
  444.          Wn_Top(windows[i]);
  445.          }
  446.  
  447.       count(36, ticks, INF);
  448.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  449.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  450.       count(18, ticks, INF);
  451.       Wn_Display (status_win, 4, 1, " Wn_Top(E)     ", status_text);
  452.       Wn_Top(windows[4]);
  453.  
  454.       count(36, ticks, INF);
  455.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  456.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  457.       count(18, ticks, INF);
  458.       Wn_Display (status_win, 4, 1, " Wn_Bottom(E)  ", status_text);
  459.       Wn_Bottom(windows[4]);
  460.       Wn_Bottom(status_win);
  461.       Wn_Bottom(win_intro_win);
  462.  
  463.       for (i = 0; i < 4; i++)
  464.          {
  465.          count(18, ticks, INF);
  466.          Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  467.          Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  468.          count(18, ticks, INF);
  469.          Wn_Display (status_win, 4, 1, " Wn_Pop(E)     ", status_text);
  470.          Wn_Pop(windows[4]);
  471.          }
  472.  
  473.       for (i = 0; i < 4; i++)
  474.          {
  475.          count(18, ticks, INF);
  476.          Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  477.          Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  478.          count(18, ticks, INF);
  479.          Wn_Display (status_win, 4, 1, " Wn_Push(E)    ", status_text);
  480.          Wn_Push(windows[4]);
  481.          }
  482.  
  483.       count(36, ticks, INF);
  484.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  485.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  486.       count(18, ticks, INF);
  487.       Wn_Display (status_win, 4, 1, " Wn_Delete(C)  ", status_text);
  488.       Wn_Delete(windows[2]);
  489.  
  490.       count(36, ticks, INF);
  491.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  492.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  493.       count(18, ticks, INF);
  494.       Wn_Display (status_win, 4, 1, " Wn_Delete(A)  ", status_text);
  495.       Wn_Delete(windows[0]);
  496.  
  497.       count(54, ticks, INF);
  498.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  499.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  500.       count(18, ticks, INF);
  501.       Wn_Display (status_win, 4, 1, " Wn_Delete(E)  ", status_text);
  502.       Wn_Delete(windows[4]);
  503.  
  504.       count(18, ticks, INF);
  505.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  506.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  507.       count(18, ticks, INF);
  508.       Wn_Display (status_win, 4, 1, " Wn_Delete(B)  ", status_text);
  509.       Wn_Delete(windows[1]);
  510.  
  511.       count(18, ticks, INF);
  512.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  513.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  514.       count(18, ticks, INF);
  515.       Wn_Display (status_win, 4, 1, " Wn_Delete(D)  ", status_text);
  516.       Wn_Delete(windows[3]);
  517.  
  518.       count(36, ticks, INF);
  519.       Wn_SetAttr(status_win, 4, 1, 15, status_text_dim);
  520.       Wn_Scroll (status_win, 1, 1, 4, 15, 0, 1);
  521.       Wn_Display (status_win, 4, 1, " start again   ", status_text);
  522.       count(18, ticks, INF);
  523.       }
  524.    }
  525.  
  526.  
  527.  
  528. /******* Time Slicing Demo ********/
  529. /*~T*/
  530.  
  531. void     slice_init()
  532.    {
  533.  
  534.    ts_control = create_task(ts_control_main, HI_SLICE, 0);
  535.    slice_a = create_task(slice_a_main, LO_SLICE, 0);
  536.    slice_b = create_task(slice_b_main, LO_SLICE, 0);
  537.    slice_c = create_task(slice_c_main, LO_SLICE, 0);
  538.  
  539.    BUILD_HT(ts_control,"ts_control");
  540.    BUILD_HT(slice_a,"slice_a");
  541.    BUILD_HT(slice_b,"slice_b");
  542.    BUILD_HT(slice_c,"slice_c");
  543.  
  544.    /* Display an introductory window */
  545.    Wn_BorderAtt = 0;
  546.    Wn_BorderAtt = WN_BCKBLU | WN_FGNWHT | WN_INTEN;
  547.    ts_intro_win = Wn_Create (2, 26, 3, 27, 1, 0, 0, 0);
  548.    Wn_Display (ts_intro_win, 1, 2, "smx can do time slicing", WN_BCKBLU | WN_FGNYEL);
  549.  
  550.    /* create slice windows */
  551.    Wn_BorderAtt = 0;
  552.    Wn_BorderAtt = WN_BCKBLK | WN_FGNBLU;
  553.    ts_win_c = Wn_Create (8, 15, 6, 14, 1, 0, "slice_c", 0);
  554.    Wn_BorderAtt = 0;
  555.    Wn_BorderAtt = WN_BCKBLK | WN_FGNGRN;
  556.    ts_win_b = Wn_Create (10, 18, 6, 14, 1, 0, "slice_b", 0);
  557.    Wn_BorderAtt = 0;
  558.    Wn_BorderAtt = WN_BCKBLK | WN_FGNRED;
  559.    ts_win_a = Wn_Create (12, 21, 6, 14, 1, 0, "slice_a", 0);
  560.  
  561.    start(ts_control);
  562.    }
  563.  
  564.  
  565. void     ts_control_main()
  566.    {
  567.    int  slice_dur = 36;   /* time slice duration in ticks */
  568.  
  569.    start(slice_a);
  570.    start(slice_b);
  571.    start(slice_c);
  572.  
  573.    unlock();
  574.    while(TRUE)
  575.       {
  576.       count(slice_dur, ticks, INF);
  577.       bump_task(slice_a, slice_a->priority);
  578.       Wn_Top (ts_win_b);
  579.       count(slice_dur, ticks, INF);
  580.       bump_task(slice_b, slice_b->priority);
  581.       Wn_Top (ts_win_c);
  582.       count(slice_dur, ticks, INF);
  583.       bump_task(slice_c, slice_c->priority);
  584.       Wn_Top (ts_win_a);
  585.  
  586.       /* put front task at LO_SLICE level of rq at end of level: */
  587. //      bump_task((*(rq + LO_SLICE)).fl, (*(rq + LO_SLICE)).fl->priority);
  588.       }
  589.    }
  590.  
  591.  
  592. void     slice_a_main()
  593.    {
  594.    static long  counter = 0;
  595.    static char  buffer[12];
  596.  
  597.    unlock();
  598.    while(TRUE)
  599.       {
  600.       ltoa(++counter, buffer, 10);
  601.       Wn_Display (ts_win_a, 4, 1, buffer, WN_BCKBLK | WN_FGNRED | WN_INTEN);
  602.       #ifdef DEBUG   
  603.          while(pcticks)
  604.             {
  605.             pcticks--;  /* decrement before task switch due to
  606.                             time-slice */
  607.             (*tick)();
  608.             }
  609.       #endif
  610.       }
  611.    }
  612.  
  613. void     slice_b_main()
  614.    {
  615.    static long  counter = 0;
  616.    static char  buffer[12];
  617.  
  618.    unlock();
  619.    while(TRUE)
  620.       {
  621.       ltoa(++counter, buffer, 10);
  622.       Wn_Display (ts_win_b, 4, 1, buffer, WN_BCKBLK | WN_FGNGRN | WN_INTEN);
  623.       #ifdef DEBUG   
  624.          while(pcticks)
  625.             {
  626.             pcticks--;  /* decrement before task switch due to
  627.                             time-slice */
  628.             (*tick)();
  629.             }
  630.       #endif
  631.       }
  632.    }
  633.  
  634. void     slice_c_main()
  635.    {
  636.    static long  counter = 0;
  637.    static char  buffer[12];
  638.  
  639.    unlock();
  640.    while(TRUE)
  641.       {
  642.       ltoa(++counter, buffer, 10);
  643.       Wn_Display (ts_win_c, 4, 1, buffer, WN_BCKBLK | WN_FGNBLU | WN_INTEN);
  644.       #ifdef DEBUG   
  645.          while(pcticks)
  646.             {
  647.             pcticks--;  /* decrement before task switch due to
  648.                             time-slice */
  649.             (*tick)();
  650.             }
  651.       #endif
  652.       }
  653.    }
  654.  
  655.  
  656. /*********** Message Sending Demo **********/
  657. /*~M*/
  658.  
  659. void _cdecl    msg_init(void)
  660.    {
  661.   
  662.    msg_task = create_task(msg_task_main, LO, 0);
  663.    msg_a_task = create_task(msg_a_task_main, LO + 1, 0);
  664.    msg_b_task = create_task(msg_b_task_main, LO + 1, 0);
  665.    msg_c_task = create_task(msg_c_task_main, LO + 1, 0);
  666.    msg_d_task = create_task(msg_d_task_main, LO + 1, 0);
  667.    msg_e_task = create_task(msg_e_task_main, LO + 1, 0);
  668.    clear_msg_wins_task = create_task(clear_msg_wins_main, LO - 1, 0);
  669.  
  670.    BUILD_HT(msg_task,"msg_task");
  671.    BUILD_HT(msg_a_task,"msg_a_task");
  672.    BUILD_HT(msg_b_task,"msg_b_task");
  673.    BUILD_HT(msg_c_task,"msg_c_task");
  674.    BUILD_HT(msg_d_task,"msg_d_task");
  675.    BUILD_HT(msg_e_task,"msg_e_task");
  676.    BUILD_HT(clear_msg_wins_task,"clear_msg_wins_task");
  677.  
  678.    /* create free message pool if it doesn't already exist */
  679.    if (!free_msgs)
  680.       {
  681.       free_msgs = create_xchg(RXCHG, 0, 0); 
  682.       BUILD_HT(free_msgs, "free_msgs");
  683.       create_pool(free_msgs, 5, MSG_LEN + 1, &ndar);
  684.       }
  685.  
  686.    /* create message exchanges if they don't already exist.  only checks
  687.       one exchange -- basically, this just monitors whether or not this
  688.       (message sending) demo has been run */
  689.    if (!msg_a_xchg)
  690.       {
  691.       msg_a_xchg = create_xchg(NXCHG, 0, 0); 
  692.       msg_b_xchg = create_xchg(NXCHG, 0, 0); 
  693.       msg_c_xchg = create_xchg(NXCHG, 0, 0); 
  694.       msg_d_xchg = create_xchg(NXCHG, 0, 0); 
  695.       msg_e_xchg = create_xchg(NXCHG, 0, 0); 
  696.       BUILD_HT(msg_a_xchg, "msg_a_xchg");
  697.       BUILD_HT(msg_b_xchg, "msg_b_xchg");
  698.       BUILD_HT(msg_c_xchg, "msg_c_xchg");
  699.       BUILD_HT(msg_d_xchg, "msg_d_xchg");
  700.       BUILD_HT(msg_e_xchg, "msg_e_xchg");
  701.       }
  702.  
  703.    /* Display an introductory window */
  704.    Wn_BorderAtt = 0;
  705.    Wn_BorderAtt = WN_BCKRED | WN_FGNWHT | WN_INTEN;
  706.    msg_intro_win = Wn_Create (2, 26, 3, 27, 1, 0, 0, 0);
  707.    Wn_Display (msg_intro_win, 1, 2, "Intertask Communication", WN_BCKRED | WN_FGNWHT);
  708.  
  709.    /* create send/receive task windows */
  710.    Wn_BorderAtt = 0;
  711.    Wn_BorderAtt = WN_BCKBLK | WN_FGNBRN;
  712.    msg_win_e = Wn_Create (8, 12, 4, MSG_LEN + 2, 1, 0, "msg_e_task", 0);
  713.    
  714.    Wn_BorderAtt = 0;
  715.    Wn_BorderAtt = WN_BCKBLK | WN_FGNBLU | WN_INTEN;
  716.    msg_win_d = Wn_Create (10, 16, 4, MSG_LEN + 2, 1, 0, "msg_d_task", 0);
  717.  
  718.    Wn_BorderAtt = 0;
  719.    Wn_BorderAtt = WN_BCKBLK | WN_FGNRED | WN_INTEN;
  720.    msg_win_c = Wn_Create (12, 20, 4, MSG_LEN + 2, 1, 0, "msg_c_task", 0);
  721.  
  722.    Wn_BorderAtt = 0;
  723.    Wn_BorderAtt = WN_BCKBLK | WN_FGNMAG;
  724.    msg_win_b = Wn_Create (14, 24, 4, MSG_LEN + 2, 1, 0, "msg_b_task", 0);
  725.  
  726.    Wn_BorderAtt = 0;
  727.    Wn_BorderAtt = WN_BCKBLK | WN_FGNGRN;
  728.    msg_win_a = Wn_Create (16, 28, 4, MSG_LEN + 2, 1, 0, "msg_a_task", 0);
  729.  
  730.    Wn_BorderAtt = 0;
  731.    Wn_BorderAtt = WN_BCKWHT | WN_FGNMAG;
  732.    msg_source_win = Wn_Create(8, 52, 5, MSG_LEN + 2, 1, 1, "msg_task", 
  733.       "Enter a Message to Send");
  734.  
  735.    start(msg_a_task);
  736.    start(msg_b_task);
  737.    start(msg_c_task);
  738.    start(msg_d_task);
  739.    start(msg_e_task);
  740.    start(msg_task);
  741.    }
  742.  
  743.  
  744. void _cdecl    msg_task_main(void)
  745.    {
  746. static   char     msg[MSG_LEN + 1];
  747. static   char     *terminator;
  748.    int      char_ctr;   /* count of the number of characters in the string entered */
  749.    int      i;
  750.    MCB_PTR  message_handle;
  751.    char     *cp;
  752.    int      no_msgs_win;  /* displays warning: no more messages */
  753.    UCHAR    warn_att = WN_BCKRED | WN_FGNWHT | WN_INTEN;
  754.  
  755.    unlock();
  756.    no_msgs_win = 0;
  757.  
  758.    while(TRUE)
  759.       {
  760.       /* clears windows if no message entered after a certain amount of time */
  761.       start(clear_msg_wins_task);  
  762.  
  763.       char_ctr = Wn_KbdInput(msg_source_win, 1, 1, MSG_LEN, msg, WN_BCKMAG | WN_FGNWHT, 
  764.          WN_BCKWHT | WN_FGNMAG, terminator, INF);
  765.       while ((message_handle = receive (free_msgs, NO_WAIT)) == NULL)
  766.          {
  767.          /* if the warning window hasn't been created, do so */
  768.          if (!no_msgs_win)
  769.             {
  770.             Wn_BorderAtt = 0;
  771.             Wn_BorderAtt = warn_att;
  772.             no_msgs_win = Wn_Create(8, 52, 5, MSG_LEN + 2, 2, 0, 0, 0);
  773.             Wn_Display(no_msgs_win, 1, 10, "Hold On!!", warn_att);
  774.             Wn_Display(no_msgs_win, 2, 4, "Waiting for a Free", warn_att);
  775.             Wn_Display(no_msgs_win, 3, 7, "Message Block", warn_att);
  776.             }
  777.          #ifdef DEBUG   
  778.             while(pcticks)
  779.                {
  780.                pcticks--;
  781.                (*tick)();
  782.                }
  783.          #endif
  784.          }
  785.  
  786.       /* if the warning window was created, delete it */
  787.       if (no_msgs_win)
  788.          {
  789.          Wn_Delete(no_msgs_win);
  790.          no_msgs_win = 0;
  791.          }
  792.       /* Copy each character in the message entered into the block.
  793.          Start at first byte of message block. */
  794.       #if LARGE_DATA        
  795.       cp = message_handle->mp; 
  796.       #else
  797.       cp = (char *)FP_OFF(message_handle->mp);
  798.       #endif
  799.       for (i = 0; i < char_ctr; i++)
  800.          *cp++ = msg[i];
  801.  
  802.       /* write spaces to fill remaining spaces (to nicen screen display) */
  803.       for (; i < MSG_LEN; i++)
  804.          *cp++ = ' ';
  805.       *cp = '\0';  /* tack on the terminator */
  806.  
  807.       send(message_handle, msg_a_xchg);   
  808.       }
  809.    }
  810.  
  811.  
  812. void _cdecl    msg_a_task_main(void)
  813.    {
  814.    MCB_PTR  message_handle;
  815.    char     *cp;
  816.    int      i;
  817. static   char     message[MSG_LEN + 1];
  818.  
  819.    unlock();
  820.    while(TRUE)
  821.       {
  822.       message_handle = receive(msg_a_xchg, INF);
  823.  
  824.       Wn_Display(msg_source_win, 1, 1, "                         ", WN_BCKWHT | WN_FGNMAG);
  825.  
  826.       /* copy message to a string */
  827.       #if LARGE_DATA        
  828.       cp = message_handle->mp; 
  829.       #else
  830.       cp = (char *)FP_OFF(message_handle->mp);
  831.       #endif
  832.       for (i = 0; i <= MSG_LEN; i++)
  833.          message[i] = *cp++;
  834.  
  835.       Wn_Display (msg_win_a, 1, 1, message, WN_BCKBLK | WN_FGNGRN);
  836.  
  837.       count(msg_delay, ticks, INF);          /* delay */
  838.  
  839.       send(message_handle, msg_b_xchg);      /* send message to next task */
  840.       bump_task(msg_a_task, msg_a_task->priority);     /* bump this task to end of level */
  841.       }
  842.    }
  843.  
  844. void _cdecl    msg_b_task_main(void)
  845.    {
  846.    MCB_PTR  message_handle;
  847.    char     *cp;
  848.    int      i;
  849. static   char     message[MSG_LEN + 1];
  850.  
  851.    unlock();
  852.    while(TRUE)
  853.       {
  854.       message_handle = receive(msg_b_xchg, INF);
  855.  
  856.       /* copy message to a string */
  857.       #if LARGE_DATA        
  858.       cp = message_handle->mp; 
  859.       #else
  860.       cp = (char *)FP_OFF(message_handle->mp);
  861.       #endif
  862.       for (i = 0; i <= MSG_LEN; i++)
  863.          message[i] = *cp++;
  864.  
  865.       Wn_Display (msg_win_b, 1, 1, message, WN_BCKBLK | WN_FGNMAG);
  866.  
  867.       count(msg_delay, ticks, INF);    /* delay */
  868.  
  869.       send(message_handle, msg_c_xchg);      /* send message to next task */
  870.       bump_task(msg_b_task, msg_b_task->priority);     /* bump this task to end of level */
  871.       }
  872.    }
  873.  
  874. void _cdecl    msg_c_task_main(void)
  875.    {
  876.    MCB_PTR  message_handle;
  877.    char     *cp;
  878.    int      i;
  879. static   char     message[MSG_LEN + 1];
  880.  
  881.    unlock();
  882.    while(TRUE)
  883.       {
  884.       message_handle = receive(msg_c_xchg, INF);
  885.  
  886.       /* copy message to a string */
  887.       #if LARGE_DATA        
  888.       cp = message_handle->mp; 
  889.       #else
  890.       cp = (char *)FP_OFF(message_handle->mp);
  891.       #endif
  892.       for (i = 0; i <= MSG_LEN; i++)
  893.          message[i] = *cp++;
  894.  
  895.       Wn_Display (msg_win_c, 1, 1, message, WN_BCKBLK | WN_FGNRED | WN_INTEN);
  896.  
  897.       count(msg_delay, ticks, INF);       /* delay */
  898.  
  899.       send(message_handle, msg_d_xchg);      /* send message to next task */
  900.       bump_task(msg_c_task, msg_c_task->priority);     /* bump this task to end of level */
  901.       }
  902.    }
  903.  
  904. void _cdecl    msg_d_task_main(void)
  905.    {
  906.    MCB_PTR  message_handle;
  907.    char     *cp;
  908.    int      i;
  909. static   char     message[MSG_LEN + 1];
  910.  
  911.    unlock();
  912.    while(TRUE)
  913.       {
  914.       message_handle = receive(msg_d_xchg, INF);
  915.  
  916.       /* copy message to a string */
  917.       #if LARGE_DATA        
  918.       cp = message_handle->mp; 
  919.       #else
  920.       cp = (char *)FP_OFF(message_handle->mp);
  921.       #endif
  922.       for (i = 0; i <= MSG_LEN; i++)
  923.          message[i] = *cp++;
  924.  
  925.       Wn_Display (msg_win_d, 1, 1, message, WN_BCKBLK | WN_FGNBLU | WN_INTEN);
  926.  
  927.       count(msg_delay, ticks, INF);       /* delay */
  928.  
  929.       send(message_handle, msg_e_xchg);      /* send message to next task */
  930.       bump_task(msg_d_task, msg_d_task->priority);     /* bump this task to end of level */
  931.       }
  932.    }
  933.  
  934. void _cdecl    msg_e_task_main(void)
  935.    {
  936.    MCB_PTR  message_handle;
  937.    char     *cp;
  938.    int      i;
  939. static   char     message[MSG_LEN + 1];
  940.  
  941.    unlock();
  942.    while(TRUE)
  943.       {
  944.       message_handle = receive(msg_e_xchg, INF);
  945.  
  946.       /* copy message to a string */
  947.       #if LARGE_DATA        
  948.       cp = message_handle->mp; 
  949.       #else
  950.       cp = (char *)FP_OFF(message_handle->mp);
  951.       #endif
  952.       for (i = 0; i <= MSG_LEN; i++)
  953.          message[i] = *cp++;
  954.  
  955.       Wn_Display (msg_win_e, 1, 1, message, WN_BCKBLK | WN_FGNBRN);
  956.  
  957.       count(msg_delay, ticks, INF);          /* delay */
  958.  
  959.       send(message_handle, free_msgs);      /* send message back to free message xchg */
  960.       bump_task(msg_e_task, msg_e_task->priority);     /* bump this task to end of level */
  961.       }
  962.    }
  963.  
  964.  
  965. void _cdecl    clear_msg_wins_main(void)
  966.  
  967. /* This task is kind of clever.  It clears the windows if, after a specified
  968.    duration, the user doesn't enter a message to send.  The way it works:
  969.      - it is started by the message-getting task just before it waits for
  970.        a message to be entered
  971.      - this task has lower priority than the message-getting task, so when
  972.        that task is suspended (waiting for the message to be input), this
  973.        task will run.  (The receive tasks are all waiting on their exchanges
  974.        so they don't run.)
  975.      - if a message is input before the count in this task finishes, this
  976.        task is preempted and the message is sent (the windows are not
  977.        cleared).  Otherwise, this task clears the screen and then stops.
  978.      - this task is then restarted on every pass through the message-getting
  979.        task to start the counter all over again.  If this task is preempted,
  980.        it never gets a chance to resume because of its lower priority. */
  981.  
  982.    {
  983.    int  window;
  984.  
  985.    unlock();
  986.  
  987.    count(7 * msg_delay, ticks, INF);
  988.    for (window = msg_win_e; window <= msg_win_a; window++)
  989.       Wn_Display(window, 1, 1, "                         ", WN_BCKBLK);
  990.    }
  991.  
  992.  
  993. void _cdecl    sleeper_main()
  994. {
  995.    unlock();
  996.    while(sleep(get_stime() + 5))
  997.       {
  998.       test(in_clib, INF);
  999.       sprintf (buffer, "WAKEUP");
  1000.       signal(in_clib);
  1001.       wr_string(24,11,LIGHTCYAN,BLACK,!BLINK,buffer);
  1002.       }
  1003. }
  1004.  
  1005. void _cdecl    suspender_main()
  1006. {
  1007.    int  control = 0;
  1008.  
  1009.    unlock();
  1010.    while(count (36, ticks, INF))
  1011.       {
  1012.       if (control++ % 2 == 0)
  1013.          {
  1014.          wr_string(24,7,LIGHTBLUE,BLACK,!BLINK,"suspender");
  1015.          }
  1016.       else
  1017.          {
  1018.          wr_string(24,7,YELLOW,BLACK,!BLINK,"suspender");
  1019.          }
  1020.       }
  1021. }
  1022.  
  1023. void _cdecl    quit_demo()
  1024. {
  1025. }
  1026.  
  1027. /* error generator. The purpose of this task is to simulate errors
  1028.    to test the error system. */
  1029.  
  1030. void _cdecl errgen_main(void)
  1031. {
  1032.    while(count(10,ticks,INF))
  1033.       {
  1034.       start(0);
  1035.       stop(0,0);
  1036.       send(0,0);
  1037.       receive(0,0);
  1038.       create_task(0,0,0);
  1039.       signal(0);
  1040.       test(0,0);
  1041.       pput_char(0,0,0);
  1042.       pget_char(0,0);
  1043.       }
  1044. /* Must make sure returns from catastrophic errors are ok before
  1045.    putting the following improvement in 
  1046.  
  1047.    word  errno;
  1048.    errno = 0;
  1049.    while(count(5,ticks,INF))
  1050.       {
  1051.       errno++;
  1052.       if(errno == NUM_XERRORS) errno = 1;
  1053.       (*xesrt[errno])(errno);
  1054.       }
  1055. */
  1056. }
  1057.