home *** CD-ROM | disk | FTP | other *** search
/ Mega CD-ROM 1 / megacd_rom_1.zip / megacd_rom_1 / DESQVIEW / DVGLU101.ZIP / DEMO.C < prev    next >
C/C++ Source or Header  |  1988-08-13  |  40KB  |  1,185 lines

  1. /*
  2. **      DEMO.C - DESQview API demonstration program.
  3. **      IBM Personal Computer - DESQview C Interface Demo.
  4. **    Written for Borland Turbo C v1.5.
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <dir.h>
  9. #include <bios.h>
  10. #include <io.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13.  
  14. #include "tvapi.h"      /* types and function prototypes */
  15. #include "tvstream.h"
  16. #include "dvp.h"
  17. #include "tvui.h"
  18.  
  19. #if __TURBOC__ != 1 && __TURBOC__ != 0x0100
  20. unsigned _heaplen = 10240 ;  /* only need 10K heap */
  21. #endif
  22.  
  23. /*===============================================================*/
  24. /* global variables                                              */
  25. /*===============================================================*/
  26.  
  27. char old_title[24] ;
  28. int old_frattr ;
  29. int orig_rows,orig_cols ;
  30. int orig_row,orig_col ;
  31. int org_row, org_col ;
  32. int orig_lrows,orig_lcols ;
  33.  
  34. /*===============================================================*/
  35. /* write an integer out to the current task's main window as a   */
  36. /* decimal value                                                 */
  37. /*===============================================================*/
  38.  
  39. void write_int(int i)
  40. {
  41.    char s[8] ;
  42.  
  43.    itoa(i,s,10) ;
  44.    TVwin_swrite(NIL,s) ;
  45. }
  46.  
  47. /*===============================================================*/
  48. /* wait for a keystroke, ensuring that the physical cursor pos   */
  49. /* is updated first (the logical cursor may move without         */
  50. /* necessarily moving the physical cursor)                       */
  51. /*===============================================================*/
  52.  
  53. int get_key(void)
  54. {
  55.    TVwin_hcur(NIL) ;
  56.    return bioskey(0) ;
  57. }
  58.  
  59. /*===============================================================*/
  60. /* save as much of the current state as we can, to restore later */
  61. /*===============================================================*/
  62.  
  63. void save_state(void)
  64. {
  65.    TVqry_origin(NIL,&org_row,&org_col) ;
  66.    TVqry_position(NIL,&orig_row,&orig_col) ;
  67.    TVqry_size(NIL,&orig_rows,&orig_cols) ;
  68.    TVqry_lsize(NIL,&orig_lrows,&orig_lcols) ;
  69.    TVqry_title(NIL,old_title,sizeof(old_title)) ;
  70.    old_frattr = TVqry_frattr(NIL) ;
  71. }
  72.  
  73. /*===============================================================*/
  74.  
  75. void standard_window(void)
  76. {
  77.    TVwin_resize(NIL,13,66) ;
  78.    TVwin_move(NIL,7,5) ;
  79.    TVwin_cursor(NIL,0,0) ;
  80.    TVwin_origin(NIL,0,0) ;
  81.    TVwin_clear(NIL) ;
  82. }
  83.  
  84. /*===============================================================*/
  85.  
  86. void stream_test(void)
  87. {
  88.    int row, col ;
  89.    char buffer[10] ;
  90.    int i ;
  91.  
  92.    standard_window() ;
  93.    TVwin_title(NIL,"DV-GLUE v" DVGLUE_versionSTR) ;
  94.    TVwin_frattr(NIL,9) ;
  95.    TVwin_redraw(NIL) ;
  96.    TVwin_printf(NIL,"Window #%d, old name was %s, origin (%d,%d)\r\n", DVappnum(), old_title, org_row,org_col) ;
  97.    TVqry_cursor(NIL,&row,&col) ;
  98.    TVwin_printf(NIL,"Cursor position is (%d,%d)\r\n",row,col) ;
  99.    TVqry_position(NIL,&row,&col) ;
  100.    TVwin_printf(NIL,"Window is at (%d,%d) ",row,col) ;
  101.    TVqry_size(NIL,&row,&col) ;
  102.    TVwin_printf(NIL,"and is %dx%d",row,col) ;
  103.    TVqry_lsize(NIL,&row,&col) ;
  104.    TVwin_printf(NIL,"/%dx%d in physical/logical size\r\n",row,col) ;
  105.    TVwin_printf(NIL,"The current output attribute is %d\r\n",TVqry_attr(NIL)) ;
  106.    TVwin_printf(NIL,"The old frame attribute was %d\r\n",old_frattr) ;
  107.    TVwin_printf(NIL,"Control code processing is %s",TVqry_ctrl(NIL)?"on":"off") ;
  108.    TVwin_printf(NIL," and we are \r\n  %s when writing\r\n",TVqry_leave(NIL)?
  109.                                        "leaving attributes untouched":"changing attributes") ;
  110.    TVwin_printf(NIL,"Using %s attributes\r\n",TVqry_logattr(NIL)?"logical":"physical") ;
  111.    TVwin_hcur(NIL) ;
  112.    TVwin_atread(NIL,FALSE) ;
  113.    TVqry_cursor(NIL,&row,&col) ;
  114.    TVwin_cursor(NIL,0,0) ;
  115.    TVwin_nread(NIL,(void *)buffer,sizeof(buffer)) ;
  116.    TVwin_cursor(NIL,row,col) ;
  117.    TVwin_printf(NIL,"First method read '%s' from screen\n",buffer) ;
  118.    TVwin_cursor(NIL,0,0) ;
  119.    TVwin_read(NIL,(void *)buffer,sizeof(buffer)) ;
  120.    TVwin_gotoxy(NIL,col,row+1) ;
  121.    TVwin_printf(NIL,"Second method read '%s' from screen\n",buffer) ;
  122.  
  123.    TVwin_swrite(NIL,"\r\nPress a key to hide window, then another to unhide it....");
  124.    get_key() ;
  125.    TVwin_hide(NIL) ;
  126.    get_key() ;
  127.    TVwin_unhide(NIL) ;
  128.    TVwin_swrite(NIL,"\r\nPress a key to continue..." ) ;
  129.    get_key() ;
  130.  
  131. /* now scroll the visible portion of the virtual screen left until it is clear */
  132.    TVqry_size(NIL,&row,&col) ;
  133.    for (i = 0 ; i < col ; i++)
  134.       {
  135.       TVsleep(5) ;
  136.       TVwin_scroll(NIL,0,0,row,col,SCRL_LEFT) ;
  137.       }
  138. }
  139.  
  140. /*===============================================================*/
  141.  
  142. void timer_test(void)
  143. {
  144.    OBJECT k, t, w ;
  145.    int left, elapsed ;
  146.  
  147.    standard_window() ;
  148.    w = TVwin_new(NIL,5,46) ;
  149.    TVwin_clear(w) ;
  150.    TVposwin(w,NIL,PW_HCENTER|PW_VCENTER,0,0) ;
  151.    TVwin_cursor(w,0,0) ;
  152.    TVwin_origin(w,0,0) ;
  153.    TVwin_top(w) ;
  154.    TVwin_printf(w,"Press a few keys during the next ten seconds:"
  155.                   "\r\n(this doesn't work as expected)") ;
  156.    k = TVkbd_new() ;
  157.    TVkbd_write(k,"a",1,0) ;  /* make sure we allocate a buffer */
  158.    TVkbd_open(k,w) ;         /* before connecting to window */
  159.                              /* (to force one buffer per keystroke) */
  160.    TVkbd_setflags(k,KBD_ACTIVE) ;
  161.    t = TVtimer_new() ;
  162.    TVtimer_begin(t,1000) ;  /* 10 seconds */
  163.    while ((left = (int) TVtimer_len(t)) > 0)
  164.       {
  165.       elapsed = (int) TVtimer_elapsed(t) ;
  166.       TVwin_cursor(w,3,0) ;
  167.       TVwin_printf(w,"Time left: %2d.%02d  Buffers used: %d\r\n  Elapsed: %2d.%02d",
  168.                        left/100, left%100, TVkbd_messages(k), elapsed/100,
  169.                        elapsed%100) ;
  170.       }
  171.    TVtimer_free(t) ;
  172.    TVkbd_clear(k) ;  /* get rid of typeahead */
  173.    TVwin_cursor(w,0,0) ;
  174.    TVwin_printf(w,"%5d buffers used after clearing typeahead   \r\n",TVkbd_messages(k));
  175.    while (bioskey(1))  /* brute-force keyboard clear */
  176.       bioskey(0) ;
  177.    TVsleep(100) ;
  178.    TVkbd_free(k) ;
  179.    TVwin_free(w) ;
  180.    TVkbd_setflags(NIL,KBD_ACTIVE) ;   /* open and make active again */
  181. }
  182.  
  183. /*===============================================================*/
  184.  
  185. void notify_func(NOTIFY_MSG *msg)
  186. {
  187.    char mail[8] ;
  188.    int count ;
  189.  
  190.    /* NOTE: can't use TVwin_printf unless we can ensure that it isn't used in */
  191.    /* any routines which might be interrupted for this notification */
  192.  
  193.    TVwin_swrite(NIL,"\r\n                                                                 \r") ;
  194.    switch (msg->event)
  195.       {
  196.       case TV_HMOVE:
  197.       case TV_VMOVE:
  198.                TVwin_swrite(NIL,"Hey, don't move me!  Now at ") ;
  199.                write_int(msg->msg.movement.row) ;
  200.                TVwin_swrite(NIL,",") ;
  201.                write_int(msg->msg.movement.col) ;
  202.                break ;
  203.       case TV_HSIZE:
  204.       case TV_VSIZE:
  205.                TVwin_swrite(NIL,"I liked my previous size!  New size ") ;
  206.                write_int(msg->msg.resizing.rows) ;
  207.                TVwin_swrite(NIL," by ") ;
  208.                write_int(msg->msg.resizing.cols) ;
  209.                break ;
  210.       case TV_HSCROLL:
  211.                TVwin_swrite(NIL,"You scrolled me ") ;
  212.                if (msg->msg.scrolling.amount > 0)
  213.                   TVwin_swrite(NIL,"right") ;
  214.                else if (msg->msg.scrolling.amount < 0)
  215.                   TVwin_swrite(NIL,"left") ;
  216.                else
  217.                   TVwin_swrite(NIL,"[done]") ;
  218.                break ;
  219.       case TV_VSCROLL:
  220.                TVwin_swrite(NIL,"You scrolled me ") ;
  221.                if (msg->msg.scrolling.amount > 0)
  222.                   TVwin_swrite(NIL,"down") ;
  223.                else if (msg->msg.scrolling.amount < 0)
  224.                   TVwin_swrite(NIL,"up") ;
  225.                else
  226.                   TVwin_swrite(NIL,"[done]") ;
  227.                break ;
  228.       case TV_CLOSE:
  229.                TVwin_swrite(NIL,"You can't close me yet!  Next time WILL close me") ;
  230.                TVwin_cancel(NIL,TV_CLOSE,FALSE) ;
  231.                break ;
  232.       case TV_HIDE:
  233.                TVwin_swrite(NIL,"You hid me!") ;
  234.                break ;
  235.       case TV_HELP:
  236.                TVwin_swrite(NIL,"Sorry, no help available.  Mouse at (") ;
  237.                write_int(msg->msg.help.mouse_row) ;
  238.                TVwin_swrite(NIL,",") ;
  239.                write_int(msg->msg.help.mouse_col) ;
  240.                TVwin_swrite(NIL,")") ;
  241.                break ;
  242.       case TV_COLORS:
  243.                TVwin_swrite(NIL,"Was the color changed?") ;
  244.                break ;
  245.       case TV_SWITCHEDTO:
  246.                TVwin_swrite(NIL,"Thanks for making me active.") ;
  247.                break ;
  248.       case TV_SWITCHEDAWAY:
  249.                TVwin_swrite(NIL,"Hey, I want to stay active!") ;
  250.                break ;
  251.       case TV_VIDEOMODE:
  252.                TVwin_swrite(NIL,"New video mode is ") ;
  253.                write_int(msg->msg.video_mode) ;
  254.                break ;
  255.       case TV_SCISSORS_CUT:
  256. /*               TVmbx_write(msg->msg.scissors.mailbox,0,0,"",0) ;  /* keep DV happy */
  257.                TVwin_swrite(NIL,"Sorry, don't know how to cut (") ;
  258.                write_int(msg->msg.scissors.up_left_row) ;
  259.                TVwin_swrite(NIL,",") ;
  260.                write_int(msg->msg.scissors.up_left_col) ;
  261.                TVwin_swrite(NIL,") to (") ;
  262.                write_int(msg->msg.scissors.up_left_row + msg->msg.scissors.height - 1) ;
  263.                TVwin_swrite(NIL,",") ;
  264.                write_int(msg->msg.scissors.up_left_col + msg->msg.scissors.width - 1) ;
  265.                TVwin_swrite(NIL,")") ;
  266.                break ;
  267.       case TV_SCISSORS_COPY:
  268. /*               TVmbx_write(msg->msg.scissors.mailbox,0,0,"",0) ;  /* keep DV happy */
  269.                TVwin_swrite(NIL,"Sorry, don't know how to copy (") ;
  270.                write_int(msg->msg.scissors.up_left_row) ;
  271.                TVwin_swrite(NIL,",") ;
  272.                write_int(msg->msg.scissors.up_left_col) ;
  273.                TVwin_swrite(NIL,") to (") ;
  274.                write_int(msg->msg.scissors.up_left_row + msg->msg.scissors.height - 1) ;
  275.                TVwin_swrite(NIL,",") ;
  276.                write_int(msg->msg.scissors.up_left_col + msg->msg.scissors.width - 1) ;
  277.                TVwin_swrite(NIL,")") ;
  278.                break ;
  279.       case TV_SCISSORS_PASTE:
  280.                TVwin_swrite(NIL,"Pasting (") ;
  281.                write_int(msg->msg.scissors.up_left_row) ;
  282.                TVwin_swrite(NIL,",") ;
  283.                write_int(msg->msg.scissors.up_left_col) ;
  284.                TVwin_swrite(NIL,") to (") ;
  285.                write_int(msg->msg.scissors.up_left_row + msg->msg.scissors.height - 1) ;
  286.                TVwin_swrite(NIL,",") ;
  287.                write_int(msg->msg.scissors.up_left_col + msg->msg.scissors.width - 1) ;
  288.                TVwin_swrite(NIL,")--") ;
  289.                count = TVmbx_size(msg->msg.scissors.mailbox) ;
  290.                write_int(count) ;
  291.                TVwin_swrite(NIL," msgs\r\nPasted data: ") ;
  292.                while (count > 0)
  293.                   {
  294.                   count -= TVreadmail(msg->msg.scissors.mailbox,mail,sizeof(mail)) ;
  295.                   TVwin_swrite(NIL,mail) ;
  296.                   }
  297.                TVmbx_clear(msg->msg.scissors.mailbox) ;
  298.                break ;
  299.       case TV_MAINMENU:
  300.                TVwin_swrite(NIL,"Main menu popped up") ;
  301.                break ;
  302.       case TV_MENU_END:
  303.                TVwin_swrite(NIL,"Main menu put away") ;
  304.                break ;
  305.       default: TVwin_swrite(NIL,"Unknown event ") ;
  306.                write_int(msg->event) ;
  307.                TVwin_swrite(NIL,"!  What happened?") ;
  308.                break ;
  309.       }
  310. }
  311.  
  312. void notify_test(void)
  313. {
  314.    int i ;
  315.    char far *scrnbuf ;
  316.    int size, flag ;
  317.    int row, col ;
  318.  
  319.    standard_window() ;
  320.    TVwin_redraw(NIL) ;
  321.    for (i = TV_HMOVE ; i <= TV_MENU_END ; i++)
  322.       if (UIsignal(i,NIL,notify_func,1000) == SIGNAL_ERROR)
  323.          {
  324.          TVwin_printf(NIL,"\a\r\nUnable to set handler for signal %d\r\n",i) ;
  325.          while(i >= TV_HMOVE)
  326.             UIsignal(i--,NIL,NULL,0) ;
  327.          TVsleep(200) ;
  328.          return ;
  329.          }
  330.    TVwin_disallow(NIL,TV_QUIT) ;
  331.    TVwin_swrite(NIL,"\r\nJust try to do something to me! (including closing me)\r\n") ;
  332.    TVwin_cursor(NIL,4,0) ;
  333.    TVwin_swrite(NIL,"Press a key when done....\r\n") ;
  334.    TVwin_hcur(NIL) ;
  335.    TVgetbuf(NIL,&scrnbuf,&size,&flag) ;
  336.    while (bioskey(1) == 0)
  337.       {
  338.       switch (scrnbuf[0])
  339.          {
  340.          case '|': scrnbuf[0] = '/' ;
  341.                    break ;
  342.          case '/': scrnbuf[0] = '-' ;
  343.                    break ;
  344.          case '-': scrnbuf[0] = '\\' ;
  345.                    break ;
  346.          default:  scrnbuf[0] = '|' ;
  347.          }
  348.       TVqry_cursor(NIL,&row,&col) ;
  349.       if (row > 20)
  350.          TVwin_cursor(NIL,5,0) ;
  351.       TVsleep(20) ;
  352.       }
  353.    bioskey(0) ;
  354.    for (i = TV_HMOVE ; i <= TV_SWITCH ; i++)
  355.       UIsignal(i,NIL,NULL,0) ;  /* cancel notification */
  356.    TVwin_allow(NIL,TV_QUIT) ;
  357.    TVwin_clear(NIL) ;
  358. }
  359.  
  360. /*===============================================================*/
  361.  
  362. void pointer_test(void)
  363. {
  364.    OBJECT p ;
  365.    int i, rows, cols ;
  366.  
  367.    TVwin_title(NIL,"Mouse Demo") ;
  368.    standard_window() ;
  369.    TVwin_move(NIL,6,1) ;
  370.    TVwin_top(NIL) ;
  371.    TVwin_redraw(NIL) ;
  372.    p = TVptr_new() ;
  373.    TVptr_open(p,NIL) ;
  374.    TVptr_icon(p,'+') ;  /* this is actually ignored in DV, I assume it does work */
  375.                         /* as advertised under TopView */
  376.    TVwin_disallow(NIL,TV_HSIZE) ;
  377.    TVwin_disallow(NIL,TV_VSIZE) ;
  378.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  379.       TVapi_kmouse(TRUE) ;  /* make sure it is on */
  380.    TVwin_swrite(NIL,"\r\nMoving mouse pointer to screen origin") ;
  381.    TVsleep(100) ;
  382.    TVqry_position(NIL,&rows,&cols) ;
  383.    TVptr_goto(p,-rows,-cols) ;
  384.    TVsleep(100) ;
  385.    TVwin_swrite(NIL,"\r\nMoving mouse pointer to positions relative to window\r\n");
  386.    TVqry_size(NIL,&rows,&cols) ;
  387.    for (i = 0 ; i < rows ; i++)
  388.       {
  389.       TVptr_goto(p,i,i/2+1) ;
  390.       TVsleep(25) ;
  391.       }
  392.    TVwin_allow(NIL,TV_VSIZE) ;
  393.    TVwin_allow(NIL,TV_HSIZE) ;
  394.    TVptr_getscale(p,&rows,&cols) ;
  395.    TVwin_printf(NIL,"\r\nPointer scaling: %d rows and %d columns",rows,cols) ;
  396.    TVsleep(100) ;
  397.    TVptr_free(p) ;
  398.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  399.       TVapi_kmouse(FALSE) ; /* make sure it is off */
  400.    TVwin_bottom(NIL) ;
  401. }
  402.  
  403. void mouse_drawing_program(void)
  404. {
  405.    OBJECT p ;
  406.    POINTER_MSG msg ;
  407.    int left_button = FALSE ;
  408.    int right_button = FALSE ;
  409.  
  410.    TVwin_clear(NIL) ;
  411.    TVwin_cursor(NIL,0,0) ;
  412.    TVwin_top(NIL) ;
  413.    TVwin_resize(NIL,23,47) ;
  414.    TVwin_move(NIL,1,10) ;
  415.    TVwin_swrite(NIL,"Drawing Program.             Press key to quit\r\n"
  416.                     " Left button sets block, right button erases\r\n"
  417.                     "       Row:    4 Col:    0 Buttons:   \r\n"
  418.                     "----------------------------------------------\r\n") ;
  419.    TVwin_redraw(NIL) ;
  420.    p = TVptr_new() ;
  421.    TVptr_open(p,NIL) ;
  422.    TVptr_setflags(p,PTR_RELEASE|PTR_NOTTOP) ;
  423.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  424.       TVapi_kmouse(TRUE) ;  /* make sure it is on */
  425.    TVptr_goto(p,4,0) ;
  426.    msg.row = 4 ; msg.column = 0 ; msg.button_state = 0 ;
  427.    while (bioskey(1) == 0)
  428.       if (TVptr_messages(p) != 0)  /* only read pointer if there is input */
  429.          {
  430.          TVptr_read(p,&msg) ;
  431.          if (msg.button_state & 1)
  432.             {
  433.             if (msg.button_state & 0x80)
  434.                left_button = TRUE ;
  435.             else if (msg.button_state & 0x40)
  436.                left_button = FALSE ;
  437.             }
  438.          else if (msg.button_state & 2)
  439.             if (msg.button_state & 0x80)
  440.                right_button = TRUE ;
  441.             else if (msg.button_state & 0x40)
  442.                right_button = FALSE ;
  443.          if (msg.row >= 4 && msg.row < 23 && msg.column >= 0 && msg.column < 46)
  444.             {
  445.             TVwin_cursor(NIL,msg.row,msg.column) ;
  446.             if (left_button)
  447.                TVputchar(NIL,'█',7) ;
  448.             else if (right_button)
  449.                TVputchar(NIL,' ',7) ;
  450.             }
  451.          if (msg.row < 4)
  452.             {
  453.             TVptr_goto(p,4,msg.column) ;
  454.             msg.row = 4 ;
  455.             }
  456.          TVwin_cursor(NIL,2,7) ;
  457.          TVwin_printf(NIL,"Row: %4d Col: %4d Buttons: %c%c", msg.row, msg.column,
  458.                         left_button ? 'L' : ' ',right_button ? 'R' : ' ') ;
  459.          }
  460.    bioskey(0) ;  /* swallow the keystroke */
  461.    TVptr_close(p) ;
  462.    TVptr_free(p) ;
  463.    if (TVisobj(p))
  464.       TVerrormsg(0,"Error--Pointer wasn't freed!",1,0,0,0) ;
  465.    else
  466.       {
  467.       TVwin_cursor(NIL,22,0) ;
  468.       TVwin_swrite(NIL,"Press a key to continue....") ;
  469.       get_key() ;
  470.       }
  471.    if (TVqry_kmouse())      /* if we are using a keyboard mouse */
  472.       TVapi_kmouse(FALSE) ; /* make sure it is off */
  473.    TVwin_bottom(NIL) ;
  474. }
  475.  
  476. /*===============================================================*/
  477.  
  478. void multiwindow_test(void)
  479. {
  480.    OBJECT win1 = TVwin_new(NIL,10,15) ;
  481.    OBJECT win2 = TVwin_new(NIL,5,20) ;
  482.    OBJECT win3 = TVwin_new(NIL,8,30) ;
  483.  
  484.    standard_window() ;
  485.    TVwin_redraw(NIL) ;
  486.    TVwin_move(win1,6,60) ;
  487.    TVwin_title(win1,"Window 1") ;
  488.    TVwin_redraw(win1) ;
  489.    TVwin_move(win2,1,52) ;
  490.    TVwin_title(win2,"Window 2") ;
  491.    TVwin_redraw(win2) ;
  492.    TVwin_move(win3,4,40) ;
  493.    TVwin_title(win3,"Window 3") ;
  494.    TVwin_redraw(win3) ;
  495.    TVwin_title(NIL,"Multiwindow Demo") ;
  496.    TVwin_redraw(NIL) ;
  497.    TVsleep(150) ;
  498.    TVwin_reorder(win1,OBJSEG(win3),OBJSEG(win2),OBJSEG(TVmywindow()),OBJSEG(win1),0);
  499.    TVwin_swrite(win1,"Window 1 on top") ;
  500.    TVsleep(150) ;
  501.    TVwin_reorder(win3,OBJSEG(win2),OBJSEG(win1),OBJSEG(TVmywindow()),OBJSEG(win3),0);
  502.    TVwin_swrite(win3,"Window 3 on top") ;
  503.    TVsleep(150) ;
  504.    TVwin_reorder(win2,OBJSEG(win3),OBJSEG(TVmywindow()),OBJSEG(win1),OBJSEG(win2),0);
  505.    TVwin_swrite(win2,"Window 2 on top") ;
  506.    TVsleep(150) ;
  507.    TVwin_reorder(NIL,OBJSEG(win2),OBJSEG(win3),OBJSEG(win1),OBJSEG(TVmywindow()),0);
  508.    TVwin_swrite(NIL,"\r\nWindow 0 on top") ;
  509.    TVsleep(100) ;
  510.    TVwin_top(win3) ;
  511.    TVwin_swrite(win3,"\n\rWindow 3 on top again") ;
  512.    TVsleep(100) ;
  513.    TVwin_topsys(win2) ;
  514.    TVwin_swrite(win2,"\n\rWindow 2 now topmost" ) ;
  515.    TVsleep(100) ;
  516.    TVwin_top(NIL) ;
  517.    TVwin_swrite(NIL,"\n\rBack to window 0" ) ;
  518.    TVsleep(100) ;
  519.    TVwin_swrite(NIL,"\r\nPlease open another window, then press a key....") ;
  520.    TVwin_top(NIL) ;  /* need to be topmost to have keyboard attached */
  521.    get_key() ;
  522.    TVwin_swrite(NIL,"\n\rAbout to hide and then unhide all my windows....") ;
  523.    TVsleep(150) ;
  524.    TVapp_hide(NIL) ;    /* also puts us in background, */
  525.    TVsleep(100) ;
  526.    TVapp_show(NIL) ;
  527.    TVsleep(10) ;
  528.    TVapp_gofore(NIL) ;  /* so have to force ourself into foreground */
  529.    TVwin_swrite(NIL,"\r\nDone!") ;
  530.    TVwin_redraw(NIL) ;
  531.    TVsleep(50) ;
  532.    TVwin_swrite(NIL,"\r\n\nI am about to put myself in the background, and"
  533.                     "\r\nthen back into the foreground") ;
  534.    TVsleep(200) ;
  535.    TVapp_goback(NIL) ;
  536.    TVsleep(100) ;
  537.    TVapp_gofore(NIL) ;
  538.    TVwin_swrite(NIL,"\r\nDone!") ;
  539.    TVsleep(50) ;
  540.    TVwin_free(win3) ;
  541.    TVsleep(50) ;
  542.    TVwin_free(win2) ;
  543.    TVsleep(50) ;
  544.    TVwin_free(win1) ;
  545.    TVsleep(50) ;
  546.    TVwin_frattr(NIL,0x70) ;  /* reverse video */
  547.    TVwin_top(NIL) ;          /* make window active */
  548.    TVwin_swrite(NIL,"\r\nPress a key to continue....") ;
  549.    TVwin_redraw(NIL) ;       /* make sure physical screen is updated */
  550.    TVkbd_setflags(NIL,KBD_ACTIVE) ;  /* make sure we get kbd input */
  551.    get_key() ;
  552. }
  553.  
  554. /*===============================================================*/
  555.  
  556. void far subtask1(int parent)
  557. {
  558.    char kbd_input[16] ;
  559.    char mbx_input[32] ;
  560.    int mbx_status ;
  561.    OBJECT mbx ;
  562.  
  563.    do {
  564.       TVkbd_read(NIL,kbd_input,sizeof(kbd_input)) ;
  565.       if (kbd_input[0] != 0x1B)
  566.          TVwin_swrite(NIL,kbd_input) ;
  567.       } while (kbd_input[0] != 0x1B) ;
  568.    TVwin_clear(NIL) ;
  569.    do {
  570.       TVreadmail(NIL,mbx_input, sizeof(mbx_input)) ;
  571.       mbx_status = (int) TVmbx_status(NIL) ;
  572.       if (mbx_input[0] == '\0')
  573.          TVwin_swrite(NIL,"\r\nThat's all, folks!" ) ;
  574.       else
  575.          {
  576.          TVwin_printf(NIL, "\r\nRead: '%s' with status %d",mbx_input,mbx_status) ;
  577.          if (OBJSEG(TVmbx_sender(NIL)) == parent)
  578.             TVwin_swrite(NIL," from parent") ;
  579.          else
  580.             TVwin_swrite(NIL," from a stranger") ;
  581.          }
  582.       } while (mbx_input[0] != '\0') ;
  583.    TVsleep(250) ;
  584.    TVwin_clear(NIL) ;
  585.    TVwin_swrite(NIL,"Test of named mailboxes:\r\n") ;
  586.    mbx = TVmbx_new() ;
  587.    TVmbx_open(mbx);
  588.    TVmbx_name(mbx,"Test Mailbox") ;
  589.    TVmbx_clear(mbx) ;
  590.    TVmbx_write(TVmbxof(MK_OBJ(parent)),FALSE,0,"Ready",5) ;
  591.    TVreadmail(mbx,mbx_input,sizeof(mbx_input)) ;
  592.    TVwin_swrite(NIL,"Got '") ;
  593.    TVwin_swrite(NIL,mbx_input) ;
  594.    TVwin_swrite(NIL,"'") ;
  595.    TVsleep(150) ;  /* don't ACK right away */
  596.    TVmbx_write(TVmbxof(MK_OBJ(parent)),FALSE,0,"Done",4) ;
  597.    TVreadmail(NIL,mbx_input,sizeof(mbx_input)) ;
  598.    TVmbx_close(mbx) ;
  599.    TVmbx_free(mbx) ;
  600. }
  601.  
  602. void far subtask2(int parent)
  603. {
  604.    int row = 0, col = 0 ;
  605.    int drow, dcol ;
  606.    int rows, cols ;
  607.    int rep ;
  608.  
  609.    (void) parent ;  /* get rid of TurboC's warning about unused parameters */
  610.    TVwin_cursor(NIL,0,0) ;
  611.    TVwin_hcur(NIL) ;
  612.    drow = 1 ;
  613.    dcol = 1 ;
  614.    for (rep = 0 ; rep < 30 ; rep++)
  615.       do {
  616.          if (TVmbx_size(NIL) != 0)
  617.             {
  618.             TVmbx_clear(NIL) ;  /* discard messages, only used to notify us */
  619.             TVtask_stop(NIL) ;   /* and suspend ourselves */
  620.             }
  621.          TVwin_cursor(NIL,row,col) ;
  622.          TVwin_swrite(NIL," ") ;
  623.          TVqry_size(NIL, &rows, &cols) ;
  624.          if (row < 0 || row >= rows-1)
  625.             drow = -drow ;
  626.          if (col < 0 || col >= cols-1)
  627.             dcol = -dcol ;
  628.          row += drow ;
  629.          col += dcol ;
  630.          TVwin_cursor(NIL,row,col) ;
  631.          TVwin_swrite(NIL,"+") ;
  632.          TVsleep(10) ;
  633.          } while (row != 0 || col != 0) ;
  634. }
  635.  
  636. void stripCRLF(char *buf)
  637. {
  638.    char *s = buf + strlen(buf) -1 ;
  639.  
  640.    while (s >= buf && (*s == '\r' || *s == '\n'))
  641.       s-- ;
  642.    s[1] = '\0' ;
  643. }
  644.  
  645. DVP_file DVPbuffer ;
  646. char prog[40], arg1[40] ;
  647.  
  648. void app_new_test(void)
  649. {
  650.    char *progname ;
  651.    OBJECT new_task ;
  652.  
  653.    TVwin_clear(NIL) ;
  654.    TVwin_cursor(NIL,0,0) ;
  655.    TVwin_swrite(NIL,"\r\nOK, now let's load a user program.\r\nProgram's name, including extension: ");
  656.    TVwin_hcur(NIL) ;
  657.    fgets(prog,sizeof(prog),stdin) ;
  658.    stripCRLF(prog) ;
  659.    TVwin_swrite(NIL,"\r\nThe program's argument: " ) ;
  660.    TVwin_hcur(NIL) ;
  661.    fgets(arg1,sizeof(arg1),stdin) ;
  662.    stripCRLF(arg1) ;
  663.    progname = searchpath(prog) ;
  664.    if (progname)
  665.       {
  666.       TVwin_printf(NIL,"\nInvoking '%s %s'\n",progname,arg1) ;
  667.       new_task = TVapp_new(NIL,10,1,13,78,TRUE,progname,progname,arg1,NULL) ;
  668.       if (new_task != NIL)
  669.          {
  670.          TVwin_swrite(NIL,"\r\nExperiment with switching between this program and "
  671.                           "\r\nthe one you just invoked.  Press a key when done") ;
  672.          get_key() ;
  673.          TVapp_free(new_task) ;
  674.          }
  675.       else
  676.          {
  677.          TVwin_printf(NIL,"Program not loaded, error code %d\r\n"
  678.                           "Press a key....",_doserrno) ;
  679.          get_key() ;
  680.          }
  681.       }
  682.    else
  683.       {
  684.       TVwin_printf(NIL,"\n\n\nCouldn't find %s!\n", prog ) ;
  685.       TVsleep(150) ;
  686.       }
  687. }
  688.  
  689. void app_start_test(void)
  690. {
  691.    int size ;
  692.    FILE *fp ;
  693.  
  694.    standard_window() ;
  695.    TVwin_title(NIL,"Create new Window") ;
  696.    TVwin_swrite(NIL,"This next test may cause your system to lock up.\r\n"
  697.                     "It is known to cause a lockup the next time you\r\n"
  698.                     "try to open a window under DV 2.00 (6-16-87)\r\n"
  699.                     "\r\n"
  700.                     "Type the keys from the open menu, or just Return to\r\n"
  701.                     "skip this test\r\n"
  702.                     "\r\n"
  703.                     "Keys on open menu: ") ;
  704.    TVwin_redraw(NIL) ;
  705.    fgets(arg1,sizeof(arg1),stdin) ;
  706.    if (arg1[0] && arg1[0] != '\n')
  707.       {
  708.       arg1[2] = '\0' ;
  709.       TVwin_swrite(NIL,"DV directory (i.e. C:\\DV): ") ;
  710.       TVwin_hcur(NIL) ;
  711.       fflush(stdin) ;
  712.       fgets(prog,sizeof(prog)-11,stdin) ;
  713.       if (prog[strlen(prog)-1] == '\n')
  714.          prog[strlen(prog)-1] = '\0' ;
  715.       strcat(prog,"\\") ;
  716.       strcat(prog,arg1) ;
  717.       strcat(prog,"-PIF.DVP") ;
  718.       if ((fp = fopen(prog,"rb")) == NULL)
  719.          TVwin_printf(NIL,"\r\nUnable to open %s!\r\n",prog) ;
  720.       else
  721.          {
  722.          size = fread(&DVPbuffer,1,sizeof(DVPbuffer),fp) ;
  723.          if (DVapp_start(&DVPbuffer,size) == 0)
  724.             TVwin_swrite(NIL,"Unable to open!\r\n") ;
  725.          fclose(fp) ;
  726.          }
  727.       TVwin_swrite(NIL,"Press a key....") ;
  728.       get_key() ;
  729.       }
  730. }
  731.  
  732. void fork_test(void)
  733. {
  734.    char key, keys[2] ;
  735.    OBJECT task1, task2 ;
  736.    int count = 0 ;
  737.    char mail[10] ;
  738.  
  739.    standard_window() ;
  740.    TVwin_resize(NIL,8,66) ;
  741.    TVwin_move(NIL,5,11) ;
  742.    TVwin_redraw(NIL) ;
  743.    task1 = TVtask_new(NIL,"Echo keys",1,39,3,40,NULL,1000,subtask1,FALSE) ;
  744.    if (task1 == NIL)
  745.       {
  746.       TVerrormsg(0,"Insufficient memory or other error--Press ESC",1,0,0,0);
  747.       return ;
  748.       }
  749.    task2 = TVtask_new(NIL,"Another task",14,1,10,78,NULL,1000,subtask2,FALSE) ;
  750.    if (task2 == NIL)
  751.       {
  752.       TVerrormsg(0,"Insufficient memory or other error--Press ESC",1,0,0,0) ;
  753.       TVtask_free(task1) ;
  754.       return ;
  755.       }
  756.    TVwin_top(NIL) ;  /* put the cursor back in our window */
  757.    TVwin_swrite(NIL,"Type characters to echo in other window, ESC to quit") ;
  758.    do {
  759.       key = get_key() ;
  760.       keys[0] = key ;
  761.       TVkbd_write(TVkbdof(task1),keys,1,0) ;
  762.       } while (key != 0x1B) ;
  763.    TVsleep(25) ;  /* allow time for other window to clear */
  764.    TVwin_swrite(NIL,"\r\nType strings to echo in other window, press just RETURN to quit\r\n") ;
  765.    TVwin_hcur(NIL) ;
  766.    do {
  767.       fgets(arg1, sizeof(arg1), stdin) ;
  768.       stripCRLF(arg1) ;
  769.       TVmbx_write(TVmbxof(task1),FALSE,count++,arg1, strlen(arg1)) ;
  770.    } while (strlen(arg1) > 0) ;
  771.  
  772.    TVmbx_clear(NIL) ;
  773.    TVwin_swrite(NIL,"\r\nTesting named mailboxes\r\n") ;
  774.    TVreadmail(NIL,mail,sizeof(mail)) ;  /* wait for other task to set up mbx */
  775.    TVwin_swrite(NIL,"sending... " ) ;
  776.    TVmbx_write(TVmbx_find("Test Mailbox"),FALSE,0,"Test successful",15) ;
  777.    TVreadmail(NIL,mail,sizeof(mail)) ;  /* wait for ACK */
  778.    TVwin_printf(NIL,"got ACK: '%s'",mail) ;
  779.    TVmbx_write(TVmbxof(task1),FALSE,0,"Quit",4) ;
  780.  
  781.    TVsleep(100) ;  /* allow time for other window to close */
  782.    TVwin_swrite(NIL,"\r\n\r\nPress a key to continue....") ;
  783.    get_key() ;
  784.    TVwin_move(NIL,1,1) ;
  785.    TVwin_resize(NIL,9,66) ;
  786.    TVwin_redraw(NIL) ;  /* update window's size and position on the screen */
  787.    TVsendmail(TVmbxof(task2),"",0) ;  /* would like to do TVtask_stop(task2) */
  788.                                       /* but DV 2.00 only allows suspending */
  789.                                       /* the current process, not others */
  790.    TVwin_clear(NIL) ;
  791.    TVwin_origin(NIL,0,0) ;
  792.    TVwin_cursor(NIL,0,0) ;
  793.    TVwin_swrite(NIL,"\r\nThe 'bouncing' plus sign in the other window should"
  794.                     "\r\nhave stopped moving.  Press a key....") ;
  795.    get_key() ;
  796.    TVtask_start(task2) ;
  797.    TVwin_swrite(NIL,"\r\nIt should have started moving again.  Press a key....") ;
  798.    get_key() ;
  799.    TVtask_free(task1) ;
  800.    TVtask_free(task2) ;  /* make sure the subtasks are both terminated */
  801.    app_new_test() ;
  802.    app_start_test() ;
  803.    TVwin_clear(NIL) ;
  804. }
  805.  
  806. /*===============================================================*/
  807.  
  808. void far second_level_interrupt(void)
  809. {
  810.    /* note that in this routine, DS/ES/SS are unknown */
  811.    TVsound(1000,10) ;
  812. }
  813.  
  814. void interrupt_test(void)
  815. {
  816.    WORD bit = TVgetbit(second_level_interrupt) ;
  817.  
  818.    standard_window() ;
  819.    TVwin_swrite(NIL,"\r\n\r\nPress a key to test second level interrupts") ;
  820.    TVwin_redraw(NIL) ;
  821.    get_key() ;
  822.    TVwin_swrite(NIL,"\r\n\r\nBeeping....") ;
  823.    TVsetbit(bit) ;
  824.    TVsleep(100) ;
  825.    TVfreebit(bit) ;
  826.    TVwin_swrite(NIL,"Done!\r\n") ;
  827. }
  828.  
  829. /*===============================================================*/
  830.  
  831. void objectq_test(void)
  832. {
  833.    OBJECT p = TVptr_new() ;
  834.    OBJECT obj ;
  835.    char buffer[100] ;
  836.    int i, count ;
  837.    POINTER_MSG msg ;
  838.  
  839.    standard_window() ;
  840.    TVwin_title(NIL,"OBJECTQ demo") ;
  841.    TVwin_swrite(NIL,"Waiting for input from either the keyboard or a mouse\r\n\r\n") ;
  842.    TVwin_hcur(NIL) ;
  843.    TVwin_redraw(NIL) ;
  844.    TVobq_open(NIL) ;
  845.    TVptr_open(p,NIL) ;
  846.    TVptr_setflags(p,PTR_NOTFORE|PTR_NOTTOP|PTR_RELEASE) ;
  847.    TVptr_erase(p) ;
  848.    TVkbd_clear(NIL) ;
  849.    TVkbd_setflags(NIL,KBD_ACTIVE) ;
  850.    TVobq_add(NIL,p) ;
  851.    TVobq_add(NIL,TVmykbd()) ;
  852.    TVobq_close(NIL) ;    /* need to close it so that all objects can be used */
  853.    obj = TVobq_read(NIL) ;
  854.    if (obj == p)
  855.       {
  856.       TVptr_read(obj,&msg) ;
  857.       TVwin_printf(NIL,"Got row: %d  col: %d  buttons: %02.2x\n",msg.row,
  858.                                                   msg.column,msg.button_state) ;
  859.       }
  860.    else
  861.       {
  862.       count = TVkbd_read(obj,buffer,sizeof(buffer)) ;
  863.       TVwin_swrite(NIL,"\r\nGot: ") ;
  864.       for (i = 0 ; i < count ; i++)
  865.          TVwin_printf(NIL,"%02x ",buffer[i]) ;
  866.       }
  867.    TVobq_remove(NIL,p) ;  /* don't take input from mouse anymore */
  868.    TVptr_close(p) ;       /* don't need the object, so free it */
  869.    TVptr_free(p) ;
  870.    TVsleep(100) ;
  871.    TVobq_close(NIL) ;
  872. }
  873.  
  874. /*===============================================================*/
  875.  
  876. extern WORD _restore_DS(void) ;
  877.  
  878. void far kbd_filter(void)
  879. {
  880.    WORD ax = _AX ;   /* store the parameters which were passed in registers */
  881.    WORD bx = _BX ;
  882.    WORD cx = _CX ;
  883.    WORD dx = _DX ;
  884.    WORD ds = _DS ;   /* and DS, which we will be clobbering */
  885.  
  886.    _restore_DS() ;   /* get back TurboC's data segment (not necessary in this */
  887.                      /* trivial filter function, though) */
  888.    /* tell DESQview to ignore non-numeric characters in numeric fields */
  889.    if ((dx & F_NUMBER) != 0 && ax >= ' ' && ax <= 0xFF)
  890.       ax = (ax >= '0' && ax <= '9') ? 0 : 0x100 ;
  891.    else if (ax > 0xFF)
  892.       ax = 0 ;  /* we want to use the extended-ASCII keystrokes */
  893.    _DX = dx ;
  894.    _CX = cx ;
  895.    _BX = bx ;
  896.    _DS = ds ;
  897.    _AX = ax ;
  898. }
  899.  
  900. /*===============================================================*/
  901.  
  902. void field_test(void)
  903. {
  904.    char buffer[50] ;
  905.    BYTE *fields ;
  906.    int status, len ;
  907.  
  908.    TVwin_title(NIL,"Field Demo") ;
  909.    standard_window() ;
  910.    TVwin_swrite(NIL,"Field-mode test\r\n"
  911.                     "Cursor should be  \031  there\r\n"
  912.                     "Enter a number:     Enter a string:\r\n"
  913.                     "Forced uppercase string:        With value: \r\n"
  914.                     "Press RETURN when done, or click here: ") ;
  915.    fields = TVfld_build_header(5,F_ALLOWKBD|F_READARRAY,0x70,0x0F) ;
  916.    TVfld_build_entry(fields,1,2,16,2,18,F_FILLIN,F_NEXT|F_NUMBER|F_CLEAR,1,0) ;
  917.    TVfld_build_entry(fields,2,2,35,2,50,F_FILLIN,F_NEXT|F_CLEAR|4,1,0) ;
  918.    TVfld_build_entry(fields,3,3,25,3,30,F_FILLIN,F_NEXT|F_UPPER|F_CLEAR,1,0) ;
  919.    TVfld_build_entry(fields,4,3,44,3,57,F_FILLIN,F_NEXT|F_CLEAR,1,0) ;
  920.    TVfld_build_entry(fields,5,4,39,4,42,F_MENU,'\r',0x70,0) ;
  921.    TVwin_stream(NIL,fields) ;
  922.    TVfld_swrite(NIL,4,"default") ;
  923.    TVfld_attr(NIL,4,0x70) ;
  924.    TVfld_cursor(NIL,1) ;   /* position cursor in first field */
  925.    TVwin_redraw(NIL) ;
  926.    TVfld_altmode(NIL,TRUE) ;
  927.    TVkbd_setflags(NIL,KBD_FILTERALL) ;
  928.    TVkbd_setesc(NIL,kbd_filter) ;
  929.    len = TVkbd_read(NIL,buffer,sizeof(buffer)) ;
  930.    status = (int) TVkbd_status(NIL) ;
  931.    TVfld_altmode(NIL,FALSE) ;
  932.    free(fields) ;  /* now we can finally free the stream */
  933.    TVwin_gotoxy(NIL,0,6) ;
  934.    TVwin_printf(NIL,"Got '%.*s'\r\nStatus was %d\r\nPress a key....",len,buffer,status) ;
  935.    get_key() ;
  936. }
  937.  
  938. /*===============================================================*/
  939. /*===============================================================*/
  940.  
  941. void open_window(void)
  942. {
  943.    OBJECT w ;
  944.    int row, col, rows, cols ;
  945.  
  946.    standard_window() ;
  947.    TVwin_title(NIL,"UIwin_open() test") ;
  948.    TVwin_swrite(NIL,"About to ask you to select a window's size and position" ) ;
  949.    TVwin_redraw(NIL) ;
  950.    TVsleep(100) ;
  951.    w = UIwin_open(NIL,2,2,25,70,5,20) ;
  952.    TVwin_clear(NIL) ;
  953.    TVwin_cursor(NIL,0,0) ;
  954.    if (w)
  955.       {
  956.       TVqry_position(w,&row,&col) ;
  957.       TVqry_size(w,&rows,&cols) ;
  958.       TVwin_cursor(w,0,0) ;
  959.       TVwin_printf(w,"New window's handle: %Fp\r\n", w) ;
  960.       TVwin_printf(w,"Size: %dx%d\r\nPosition: (%d,%d)\r\nPress a key...",rows,cols,row,col) ;
  961.       TVwin_top(w) ;
  962.       TVwin_redraw(w) ;
  963.       get_key() ;
  964.       TVwin_free(w) ;
  965.       }
  966.    else
  967.       {
  968.       TVwin_swrite(NIL,"Cancelled!  Press a key...") ;
  969.       get_key() ;
  970.       }
  971. }
  972.  
  973. /*===============================================================*/
  974. /* restore as much of the old state as we've been able to save   */
  975. /*===============================================================*/
  976.  
  977. void restore_state(void)
  978. {
  979.    TVwin_lsize(NIL,orig_lrows,orig_lcols) ;
  980.    TVwin_title(NIL,old_title) ;
  981.    TVwin_frattr(NIL,old_frattr) ;
  982.    TVwin_move(NIL,orig_row,orig_col) ;
  983.    TVwin_resize(NIL,orig_rows,orig_cols) ;
  984.    TVwin_origin(NIL,org_row,org_col) ;
  985.    TVwin_redraw(NIL) ;  /* make sure screen is updated */
  986. }
  987.  
  988. /*===============================================================*/
  989.  
  990. void do_all(void)
  991. {
  992.    stream_test() ;
  993.    TVerrormsg(0,"TEST ERROR MESSAGE - press ESC",1,0,0,0);
  994.    notify_test() ;
  995.    timer_test() ;
  996.    pointer_test();
  997.    mouse_drawing_program() ;
  998.    field_test() ;
  999.    fork_test() ;
  1000.    interrupt_test() ;
  1001.    objectq_test() ;
  1002.    multiwindow_test() ;
  1003.    open_window() ;
  1004.    TVsound(200,5) ;
  1005.    TVsound(350,5) ;
  1006.    TVsound(500,5) ;
  1007.    TVsound(650,5) ;
  1008. }
  1009.  
  1010. /*===============================================================*/
  1011.  
  1012. MENU_ITEM main_menu_items[] = {
  1013.    { M_SPECIAL,"Do everything  \021─┘", '\r',0, FALSE },
  1014.    { M_SEP,    0,                       205, 0, FALSE },
  1015.    { M_HCENTER,"Single Tests",          0,   0, FALSE },
  1016.    { M_ITEM,   "Streams",               'S', 0, FALSE },
  1017.    { M_ITEM,   "Notification",          'N', 0, FALSE },
  1018.    { M_ITEM,   "Timers",                'T', 0, FALSE },
  1019.    { M_ITEM,   "Pointers...",           'P', 0, FALSE },
  1020.    { M_ITEM,   "Fields",                'F', 0, FALSE },
  1021.    { M_ITEM,   "Multitasking",          'M', 0, FALSE },
  1022.    { M_ITEM,   "Interrupts",            'I', 0, FALSE },
  1023.    { M_ITEM,   "objectQ",               'Q', 0, FALSE },
  1024.    { M_ITEM,   "Windows",               'W', 0, FALSE },
  1025.    { M_ITEM,   "Open window",           'O', 0, FALSE },
  1026.    { M_ITEM,   "soUnd...",              'U', 0, FALSE },
  1027.    { M_SEP,    0,                       205, 0, FALSE },
  1028.    { M_ITEM,   "eXit",                  'X', 0, FALSE },
  1029.    { M_END,    0,                       0,   0, FALSE }
  1030. } ;
  1031.  
  1032. MENU_OPTIONS main_menu_options = { " Demo ", 0, -1, FALSE, TRUE, TRUE, ' ' } ;
  1033.  
  1034. MENU_ITEM sound_menu_items[] = {
  1035.    { M_ITEM, "200 Hz tone",   '2', 0,   FALSE },
  1036.    { M_ITEM, "350 Hz tone",   '3', '5', FALSE },
  1037.    { M_ITEM, "500 Hz tone",   '5', 0,   FALSE },
  1038.    { M_ITEM, "650 Hz tone",   '6', '5', FALSE },
  1039.    { M_END,  0,               0,   0,   FALSE }
  1040. } ;
  1041.  
  1042. MENU_OPTIONS sound_menu_options = { " Sound Menu ", 16, -21, FALSE, TRUE, TRUE, ' ' } ;
  1043.  
  1044. MENU_ITEM pointer_menu_items[] = {
  1045.    { M_ITEM, "Program pointer movement", 'P', 0, FALSE },
  1046.    { M_ITEM, "Drawing program",          'D', 0, FALSE },
  1047.    { M_END,  0,                          0,   0, FALSE }
  1048. } ;
  1049.  
  1050. MENU_OPTIONS pointer_menu_options = { "Pointer Menu", 9, -21, FALSE, TRUE, TRUE, ' ' } ;
  1051.  
  1052. /*===============================================================*/
  1053.  
  1054. void sound_menu(void) ;
  1055. void pointer_menu(void) ;
  1056.  
  1057. void do_nothing(void)
  1058. {
  1059. }
  1060.  
  1061. void (*menu_functions[])(void) =
  1062.    {
  1063.    do_all, stream_test, notify_test, timer_test, do_nothing, field_test,
  1064.    fork_test, interrupt_test, objectq_test, multiwindow_test, open_window,
  1065.    do_nothing, do_nothing
  1066.    } ;
  1067.  
  1068. /*===============================================================*/
  1069.  
  1070. int menu_test(OBJECT window,int status,char *results)
  1071. {
  1072.    (void) window ;
  1073.    (void) results ;
  1074.    if (status == 2 || status == 27) /* right mouse button or ESC */
  1075.       return MA_REDO | MA_RESET ;
  1076.    else if (results[11] == 'Y')  /* is choice so'U'nd menu? */
  1077.       {
  1078.       sound_menu() ;
  1079.       results[11] = 'N' ;  /* reset the field */
  1080.       return MA_REDO | MA_SELECT ;
  1081.       }
  1082.    else if (results[4] == 'Y')   /* is choice 'P'ointer menu? */
  1083.       {
  1084.       pointer_menu() ;
  1085.       return MA_REDO | MA_RESET ;
  1086.       }
  1087.    else
  1088.       return MA_DONE ;
  1089. }
  1090.  
  1091. /*===============================================================*/
  1092.  
  1093. void sound_menu(void)
  1094. {
  1095.    void *menu = UImenu_build(sound_menu_items,&sound_menu_options) ;
  1096.    char results[5] ;  /* there are four items */
  1097.    int i ;
  1098.  
  1099.    if (menu == ME_TOOBIG)
  1100.       TVwin_printf(NIL, "Menu too big!\n") ;
  1101.    else if (menu == ME_NOMEM)
  1102.       TVwin_printf(NIL, "Not enough memory for menu!\n") ;
  1103.    else if (menu == ME_BADITEM)
  1104.       TVwin_printf(NIL, "Error in menu item!  You probably forgot the M_END\n" ) ;
  1105.    else
  1106.       {
  1107.       (void) UImenu_show(menu,TRUE,NULL,results) ;
  1108.       if (strchr(results,'Y') != NULL)
  1109.          TVsound(200+150*(strchr(results,'Y')-results),4) ;
  1110.       else /* hit Esc */
  1111.          {
  1112.          for (i = 0 ; i < 30 ; i++)
  1113.             TVsound(300+100*i,3) ;
  1114.          TVnosound() ;   /* test cancellation of enqueued notes */
  1115.          }
  1116.       }
  1117. }
  1118.  
  1119. /*===============================================================*/
  1120.  
  1121. void pointer_menu(void)
  1122. {
  1123.    void *menu = UImenu_build(pointer_menu_items,&pointer_menu_options) ;
  1124.    char results[3] ;
  1125.  
  1126.    if (menu == ME_TOOBIG)
  1127.       TVwin_printf(NIL, "Menu too big!\n") ;
  1128.    else if (menu == ME_NOMEM)
  1129.       TVwin_printf(NIL, "Not enough memory for menu!\n") ;
  1130.    else if (menu == ME_BADITEM)
  1131.       TVwin_printf(NIL, "Error in menu item!  You probably forgot the M_END\n" ) ;
  1132.    else
  1133.       {
  1134.       (void) UImenu_show(menu,TRUE,NULL,results) ;
  1135.       if (results[0] == 'Y')
  1136.          pointer_test() ;
  1137.       else if (results[1] == 'Y')
  1138.          mouse_drawing_program() ;
  1139.       }
  1140. }
  1141.  
  1142. /*===============================================================*/
  1143.  
  1144. void main_menu(void)
  1145. {
  1146.    void *menu = UImenu_build(main_menu_items,&main_menu_options) ;
  1147.    char results[14] ;  /* there are 13 menu items */
  1148.  
  1149.    if (menu == ME_TOOBIG)
  1150.       TVwin_printf(NIL, "Menu too big!\n" ) ;
  1151.    else if (menu == ME_NOMEM)
  1152.       TVwin_printf(NIL, "Not enough memory for menu!\n" ) ;
  1153.    else if (menu == ME_BADITEM)
  1154.       TVwin_printf(NIL, "Error in menu item!  You probably forgot the M_END\n" ) ;
  1155.    else
  1156.       {
  1157.       do {
  1158.          save_state() ;    /* save size/pos/title of window */
  1159.          (void) UImenu_show(menu,TRUE,menu_test,results) ;
  1160.          if (strchr(results,'Y') != NULL)
  1161.             (*menu_functions[strchr(results,'Y') - results])() ;
  1162.          restore_state() ; /* restore window to its previous state */
  1163.          } while (results[strlen(results)-1] == 'N') ;
  1164.       free( menu ) ;
  1165.       }
  1166. }
  1167.  
  1168. /*===============================================================*/
  1169.  
  1170. void main()
  1171. {
  1172.    /* initialize everything and return DESQview version number */
  1173.    if (DVinit() == 0)
  1174.       {
  1175.       fputs("This program requires DESQview 2.0 or later\n",stderr);
  1176.       exit(1);
  1177.       }
  1178.    main_menu() ;
  1179.    TVwin_clear(NIL) ;
  1180.    /* quit DESQview API */
  1181.    DVexit() ;
  1182. }
  1183.  
  1184. /* End of DEMO.C */
  1185.