home *** CD-ROM | disk | FTP | other *** search
/ HomeWare 14 / HOMEWARE14.bin / os2 / cenv2_19.arj / OS2DEMO.CMD < prev    next >
OS/2 REXX Batch file  |  1994-03-09  |  40KB  |  1,092 lines

  1. @ECHO OFF
  2. REM *************************************************************
  3. REM *** OS2DEMO.CMD - Unattended demo script for showing off  ***
  4. REM *** ver.1         the powers of OS/2 running Windows, DOS ***
  5. REM ***               and PM programs. Thanks to Bob Weeks    ***
  6. REM ***               for the idea.                           ***
  7. REM *************************************************************
  8.  
  9. ::***************************************************************************
  10. ::***                   START OF CONFIGURATION SECTION
  11. ::***
  12. ::*** 1) Set the following GRAPHIC_PROGRAM_SPEC to specify a DOS program
  13. ::***    that runs at hi-resolution and looks good in a DOS box.
  14. ::***    If you can't think of something then just use COMMAND.COM.
  15.   SET GRAPHIC_PROGRAM_SPEC=E:\Personal\AcidWarp.exe
  16. ::***
  17. ::*** 2) During the demo, a coach window always shows at the bottom of
  18. ::***    the screen.  In the following lines, specify the the size of
  19. ::***    the font for that window (use a valid font size) and change
  20. ::***    the number of lines showing if you wish.
  21.   SET COACH_FONTSIZE=30x12
  22.   SET COACH_LINECOUNT=2
  23. ::***
  24. ::*** 3) The fancier Windows parts of this demo must communicate with
  25. ::***    multiple windows session using Nombas' CEnvi for Windows.
  26. ::***    If you don't already have CEnvi for Windows then you can
  27. ::***    probably download the software from wherever you got CEnvi
  28. ::***    for OS/2. If you register CEnvi for OS/2 then you also get
  29. ::***    CEnvi for Windows.  Contact Nombas is you need more help.
  30. ::***    Using CEnvi for Windows, you next need to create the
  31. ::***    ServeOS2.exe program.  To do this start windows, run
  32. ::***    CEnvi.exe, and at the CEnvi prompt enter:
  33. ::***           /BIND=ServeOS2 ServeOS2
  34. ::***    This will create the ServeOS2.exe file.  In the following
  35. ::***    line, set the SERVEOS2_SPEC variable to the location of
  36. ::***    the ServeOS2.exe executable.
  37.   SET SERVEOS2_SPEC=ServeOS2.exe
  38. ::***
  39. ::*** 4) This demo does some pretty fancy stuff, with complicated
  40. ::***    interactions between parts, and so it is not unreasonable
  41. ::***    to expect it to get "stuck" now and then.  (On the latest
  42. ::***    test on my system, which was also running a BBS at the same
  43. ::***    time as this demo, the demo ran for about 200 repetitions
  44. ::***    before it got stuck when a Windows applications had a GPF
  45. ::***    in the wrong place.  If you want the computer to reboot
  46. ::***    if anything goes wrong with the demo (for example, if the
  47. ::***    demo is to run unattended in a store, and the computer runs
  48. ::***    OS2DEMO.CMD when it reboots) then uncomment the following
  49. ::***    line.  DEMO_HUNG_REBOOT_TIMEOUT, if it exists in the
  50. ::***    environment block, specifies how many minutes the computer
  51. ::***    must appear to be hung (the focus window stops changing) before
  52. ::***    the computer reboots itself.  Warning: the computer doesn't
  53. ::***    do a controlled shutdown, but simplu mimics ctrl-alt-del.  This
  54. ::***    is very unlikely to cause any problems after minutes of the
  55. ::***    computer doing nothing.
  56.  REM SET DEMO_HUNG_REBOOT_TIMEOUT=3
  57. ::***
  58. ::*** 5) If you are experiencing periodic hangs of this DEMO, then
  59. ::***    it is useful to have some idea later about where the demo
  60. ::***    stopped running.  If you uncomment the following line and
  61. ::***    set it to specify a log file, then some information will be
  62. ::***    stored in the file to examine for the state of OS2DEMO.CMD
  63. ::***    to know where it hung.
  64.  REM SET OS2DEMO_LOGFILE=C:\OS2DEMO.LOG
  65. ::***
  66. ::*** 6) This is not necessary, but to make the Windows section of this
  67. ::***    demo look its best, you should start Windows and configure the
  68. ::***    CLOCK so that it is analog with seconds showing, the CALCULATOR
  69. ::***    so that is is in standard and not scientific mode, and the
  70. ::***    NOTEPAD so that the text is readable
  71. ::***
  72. ::*** 7) Register CEnvi.  Otherwise, this demo will occasionally get
  73. ::***    halted by a "PLEASE REGISTER, I NEED THE MONEY" message, which
  74. ::***    does not make for an impressive demo.
  75. ::***
  76. ::*** 8) Put a "REM" in front of the following line to avoid jumping to
  77. ::***    the "please configure" message
  78.  REM GOTO CONFIGURED
  79. ::***
  80. ::***                    END OF CONFIGURATION SECTION
  81. ::***************************************************************************
  82.  
  83. ECHO OS2DEMO: This is a very comprehensive stand-alone demo of
  84. ECHO          OS2. Before using this demo you should edit this
  85. ECHO          OS2Demo.cmd file and check the settings in the
  86. ECHO          Configuration section. After OS2Demo.cmd has been
  87. ECHO          edited then run it again to amaze your family and
  88. ECHO          friends.
  89. PAUSE
  90. EXIT
  91.  
  92.  
  93. :CONFIGURED
  94. IF "%1" == "CALLING_MYSELF" GOTO CALLING_MYSELF
  95.  
  96. REM *** KILL ANY SESSIONS WE MAY HAVE LEFT RUNNING
  97. call kill "OS/2 Demo"
  98. call kill "One DOS Session"
  99. call kill "Another DOS Session"
  100. call kill "OS2DEMO.BAT"
  101. call kill "Session:ServeOS2"
  102. call kill "OS2Demo Rebooter"
  103.  
  104. CALL SESSION.CMD /Title "OS/2 Demo" /F /WIN /MAX /FONT %COACH_FONTSIZE% %COMSPEC% /C %0 CALLING_MYSELF
  105.  
  106. EXIT
  107.  
  108. :CALLING_MYSELF
  109. REM **********************************************************
  110. REM *** This section is called by the first pass, but will ***
  111. REM *** have a better title and bigger font size, and put  ***
  112. REM *** this screen in lower right corner of the screen    ***
  113. REM **********************************************************
  114.  
  115. REM Make this window take up few lines only in
  116. mode 80,%COACH_LINECOUNT%
  117. call winset "OS/2 Demo" BIGGEST
  118. call winset "OS/2 Demo" BIGGEST
  119.  
  120. REM CEnvi script to move this window to the lower right corner of the screen
  121. CEnvi #include '%0,cmd,,GOTO END_LOWER_RIGHT,:END_LOWER_RIGHT'
  122. GOTO END_LOWER_RIGHT
  123.  
  124.    // Move this window to lower right corner of screen
  125.    #include "WinTools.lib"
  126.  
  127.    suspend(1000);
  128.    GetScreenSize(ScreenWidth,ScreenHeight);
  129.    GetSize(Info().WinHandle,MyWidth,MyHeight);
  130.    SetPosition(Info().WinHandle,ScreenWidth - MyWidth,0);
  131.    suspend(2000);
  132.  
  133. :END_LOWER_RIGHT
  134.  
  135. REM ****************************************************************
  136. REM *** HUNG_REBOOT: If the DEMO_HUNG_REBOOT_TIMEOUT environment ***
  137. REM *** variable was specified then start a hidden background    ***
  138. REM *** session that will reboot the computer if the window      ***
  139. REM *** focus stops changing                                     ***
  140. REM ****************************************************************
  141.  
  142. IF ""=="%DEMO_HUNG_REBOOT_TIMEOUT%" GOTO END_HUNG_REBOOT
  143. CALL SESSION.CMD /Title "OS2Demo Rebooter" /B /FS /HID CEnvi.exe #include '%0,CMD,,GOTO END_HUNG_REBOOT,:END_HUNG_REBOOT' RebootIfHung(%DEMO_HUNG_REBOOT_TIMEOUT%)
  144. GOTO END_HUNG_REBOOT
  145.  
  146. #define SUSPEND_BETWEEN_CHECKS   10 // approx. seconds between checks
  147.  
  148. RebootIfHung(MinutesToTimeout)
  149. {
  150.    MillisecondSuspend = 1000 * SUSPEND_BETWEEN_CHECKS;
  151.    SecondsToTimeout = 60 * MinutesToTimeout;
  152.    PreviousFocusWindow = GetFocus();
  153.    TimeOfLastFocusChange = time();
  154.  
  155.    for ( ; ; ) {
  156.       suspend(MillisecondSuspend);
  157.       if ( (FocusWindow = GetFocus()) != PreviousFocusWindow ) {
  158.          // focus window has changed. Good!
  159.          TimeOfLastFocusChange = time();
  160.          PreviousFocusWindow = FocusWindow;
  161.       } else {
  162.          // focus window has not changed
  163.          if ( SecondsToTimeout < difftime(time(),TimeOfLastFocusChange) ) {
  164.             RebootSystemEEEEK();
  165.          }
  166.       }
  167.    }
  168. }
  169.  
  170. GetFocus()
  171. {
  172.    #define HWND_DESKTOP 1
  173.    #define ORD_WIN32QUERYFOCUS   817
  174.    return DynamicLink("PMWIN",ORD_WIN32QUERYFOCUS,BIT32,CDECL,HWND_DESKTOP);
  175. }
  176.  
  177. RebootSystemEEEEK()
  178. {
  179.    #define ORD_DOS32OPEN   273
  180.    #define FILE_NORMAL     0x0000
  181.    #define FILE_OPEN       0x0001
  182.    #define OPEN_SHARE_DENYNONE      0x0040
  183.    #define OPEN_ACCESS_READWRITE    0x0002
  184.    if ( !DynamicLink("doscalls",ORD_DOS32OPEN,BIT32,CDECL,
  185.                      "\\DEV\\DOS$",FileHandle,ActionTaken,0,
  186.                      FILE_NORMAL,FILE_OPEN,
  187.                      OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,0) ) {
  188.  
  189.       #define ORD_DOS32DEVIOCTL     284
  190.       #define CATEGORY_DOSSYS       0xD5
  191.       #define FUNCTION_REBOOT       0xAB
  192.       DynamicLink("doscalls",ORD_DOS32DEVIOCTL,BIT32,CDECL,
  193.                   FileHandle,CATEGORY_DOSSYS,FUNCTION_REBOOT,
  194.                   NULL,0,NULL,NULL,0,NULL);
  195.  
  196.       #define ORD_DOS32CLOSE  257
  197.       DynamicLink("doscalls",ORD_DOS32CLOSE,BIT32,CDECL,FileHandle);
  198.    }
  199. }
  200.  
  201. :END_HUNG_REBOOT
  202.  
  203. REM *************************************************************
  204. REM *** STAY ON TOP: will now run code to stay on top, and    ***
  205. REM *** spawn a new CMD.EXE to continue with this batch file  ***
  206. REM *************************************************************
  207.  
  208. SET OS2DEMO_FILESPEC=%0
  209. SET DELDIR=
  210. CEnvi.exe #include '%0,cmd,,GOTO END_STAY_ON_TOP,:END_STAY_ON_TOP'
  211. GOTO END_STAY_ON_TOP
  212.  
  213.    #define ON_TOP_DELAY 1800
  214.    sprintf(SpawnCommand,"%s /C CEnvi #include \'%s,CMD,,AUTOMATED_SCRIPT_AT_LAST\' RunForever()",
  215.            defined(OS2_SHELL) ? OS2_SHELL : "CMD.EXE",OS2DEMO_FILESPEC);
  216.    CmdChildID = spawn(P_NOWAIT,SpawnCommand);
  217.  
  218.    while ( ValidProcessID(CmdChildID) ) {
  219.       PutMyselfOnTop();
  220.       suspend(ON_TOP_DELAY);
  221.    }
  222.  
  223.    ValidProcessID(id)   // return TRUE if this ID is OK
  224.    {
  225.       if ( pList = ProcessList(False) ) {
  226.          for ( li = GetArraySpan(pList); 0 <= li; li-- ) {
  227.             if ( id == pList[li].id )
  228.                return(True);
  229.          }
  230.       }
  231.       return False;
  232.    }
  233.  
  234.    SetWindowPos(pHandle,pBehindHandle,pColumn,pRow,pWidth,pHeight,pFlags)
  235.    {
  236.       #define ORD_WIN32SETWINDOWPOS 875
  237.       PMDynamicLink("PMWIN",ORD_WIN32SETWINDOWPOS,BIT32,CDECL,
  238.                     pHandle,pBehindHandle,pColumn,pRow,pWidth,pHeight,pFlags);
  239.    }
  240.  
  241.    PutMyselfOnTop()
  242.    {
  243.       #define HWND_TOP     3
  244.       #define SWP_ZORDER   4
  245.       SetWindowPos(Info().WinHandle,HWND_TOP,0,0,0,0,SWP_ZORDER);
  246.    }
  247.  
  248. :END_STAY_ON_TOP
  249. CEnvi printf('\a\a\a\a\a\a\a\a\a\a'); getch();
  250. EXIT
  251.  
  252.  
  253. AUTOMATED_SCRIPT_AT_LAST
  254. //***********************************************************************
  255. //***********************************************************************
  256. //************************                       ************************
  257. //************************  FINALLY! THE SCRIPT  ************************
  258. //************************                       ************************
  259. //***********************************************************************
  260. //***********************************************************************
  261.  
  262. #include <WinTools.lib>
  263. #include <Dos_Boss.lib>
  264. #include <Win_Boss.lib>
  265. #include <KeyPush.lib>
  266.  
  267. /*************** MANY DOS SESSIONS ***************/
  268. ManyDosSessions()
  269. {
  270.    LogHere("ManyDosSession()");
  271.    SetWindowTitle(Info().WinHandle,"OS/2 Demo: MULTIPLE SIMULTANEOUS DOS SESSIONS");
  272.  
  273.    EraseScreen();
  274.    printf("With OS/2, you can run as many DOS sessions in as many different ways\n"
  275.           "as you want.  ALL AT THE SAME TIME!!!");
  276.  
  277.    // Make a batch file for the DOS commands, and the GO file
  278.    lFp = fopen("C:\\OS2DEMO.BAT","wt");
  279.    fprintf(lFp,":AGAIN\n");
  280.    fprintf(lFp,"DIR /On\n");
  281.    fprintf(lFp,"CLS\n");
  282.    fprintf(lFp,"TYPE C:\\AUTOEXEC.BAT\n");
  283.    fprintf(lFp,"C:\n");
  284.    fprintf(lFp,"CD OS2\n");
  285.    fprintf(lFp,"DIR *.EXE /W\n");
  286.    fprintf(lFp,"CD \\\n");
  287.    fprintf(lFp,"SET\n");
  288.    fprintf(lFp,"ver\n");
  289.    fprintf(lFp,"@IF EXIST C:\\OS2DEMO.GO GOTO AGAIN\n");
  290.    fprintf(lFp,"EXIT\n");
  291.    fclose(lFp);
  292.    fclose(fopen("C:\\OS2DEMO.GO","w"));
  293.  
  294.    // start two DOS sessions
  295.    RestoreDefaultDOSSettings();
  296.    QCall("session_cmd", "/TITLE", "Another DOS session", "/F", "/WIN", "/DOS", "/FONT", "8x8",
  297.          "/SET", "IDLE_SECONDS=0", "/SET", "IDLE_SENSITIVITY=40" );
  298.    AnotherHwnd = GetWindowHandle("Another DOS session");
  299.    QCall("session_cmd", "/TITLE", "One DOS session", "/F", "/WIN", "/DOS", "/FONT", "16x8",
  300.          "/SET", "IDLE_SECONDS=0", "/SET", "IDLE_SENSITIVITY=40" );
  301.    OneHwnd = GetWindowHandle("One DOS session");
  302.  
  303.    // Start DOS windows 25-line mode
  304.    PasteToDOSWindow("One DOS session","mode 80,25\rcls\r");
  305.    PasteToDOSWindow("Another DOS session","mode 80,25\rcls\r");
  306.    WaitSeconds(3);
  307.  
  308.    // adjust one DOS window in upper-right edge of screen
  309.    ShowWindow(OneHwnd,SW_SHOWMAXNOACTIVE);
  310.    GetSize(OneHwnd,width,height);
  311.    SetPosition(OneHwnd,ScreenWidth-width,ScreenHeight-height);
  312.  
  313.    // adjust other DOS window so it's near left and just above this one
  314.    SetPosition(AnotherHwnd,12,MyHeight - 2);
  315.  
  316.    // Tell each DOS session to run the batch file
  317.    PasteToDOSWindow("One DOS session","C:\\OS2DEMO.BAT\r");
  318.    PasteToDOSWindow("Another DOS session","C:\\OS2DEMO.BAT\r");
  319.  
  320.    WaitSeconds(1);
  321.    SetWindowTitle(OneHwnd,"One DOS Session");
  322.    SetWindowTitle(AnotherHwnd,"Another DOS Session");
  323.  
  324.  
  325.    WaitSeconds(20);
  326.  
  327.    sprintf(lPosition,"%d,%d",ScreenWidth/10,ScreenHeight/4);
  328.    RestoreDefaultDOSSettings()
  329.    QCall("session_cmd", "/TITLE", "Hi-res graphics session", "/F", "/POS", lPosition, "/WIN", "/DOS",
  330.          "/SET", "IDLE_SECONDS=0", "/SET", "IDLE_SENSITIVITY=100",
  331.          "/SET", "HW_TIMER=1", "/SET", "VIDEO_8514A_XGA_IOTRAP=1",
  332.          GRAPHIC_PROGRAM_SPEC);
  333.    printf("  Including hi-res graphics...");
  334.  
  335.    WaitSeconds(20);
  336.  
  337.    EraseScreen();
  338.    printf("The DOS sessions may be windowed, as you see here\n"
  339.           "or they may be full screen...");
  340.    WaitSeconds(1);
  341.    QCall( "domenu_cmd", "Hi-res graphics session", "Full-screen" );
  342.  
  343.    // also tell the other DOS windows to go away
  344.    // tell both DOS sessions to exit
  345.    WaitSeconds(4);
  346.    printf("  or windowed again.");
  347.    QCall( "switch_cmd", "OS/2 Demo" );
  348.    QCall( "domenu_cmd", "Hi-res graphics session", "Windowed" );
  349.    WaitSeconds(5);
  350.  
  351.    QCall( "kill_cmd", "Hi-res graphics session");
  352.    EraseScreen();
  353.    printf("Give these DOS sessions a moment to exit...");
  354.    remove("C:\\OS2DEMO.GO");
  355.  
  356.    // Wait up to 20 seconds for these sessions to exit
  357.    StartTime = time();
  358.    while ( (IsWindow(OneHwnd) || IsWindow(AnotherHwnd))
  359.         && difftime(time(),StartTime) < 20 )
  360.       suspend(100);
  361.    // kill the windows just in case they're not already dead
  362.    QCall( "kill_cmd", "One DOS Session" );
  363.    QCall( "kill_cmd", "Another DOS Session" );
  364.    remove("C:\\OS2DEMO.BAT");
  365. }
  366.  
  367. /*************** MANY WINDOWS SESSIONS ***************/
  368.  
  369. NombasAdvertisement =
  370.    "MEMO\rTo: All personnel\r\r"
  371.    "I just saw an amazing computer demo. The automated demo was controlled "
  372.    "by a program called CEnvi, from Nombas, for OS/2, DOS, and Windows.\r\r"
  373.    "We need CEnvi NOW! Contact:\r"
  374.    "   Nombas\r"
  375.    "   P.O. Box 875\r"
  376.    "   Medford, MA 02155\r\r"
  377.    "CEnvi interprets the simple yet powerful Cmm language for our OS/2, DOS, "
  378.    "and Windows systems. CEnvi also creates hundreds of the simplest "
  379.    "programs you ever saw.  Our problems are solved by CEnvi: The Mother of "
  380.    "All Utilities!\r\r"
  381.    "I just can't say enough about Nombas' CEnvi. It's a scripting language, "
  382.    "a programmer's toolbox, a glue to connect all applications and operating "
  383.    "systems, and CEnvi (\'C\' Envy) is a catchy name.\r\r"
  384.    "IS and PC experts don't have to waste time anymore "
  385.    "customizing all of our computer systems, as now they can write simple "
  386.    "CEnvi scripts for every system, and customize them for each system.\r\r"
  387.    "Call Nombas: (617)391-6595 and get us a good deal on CEnvi for all "
  388.    "our systems all over the world.\r\r"
  389.    "Also, tell our application programmers to stop fiddling with their "
  390.    "internal macro language and use Nombas Cmm-interpreter.\r\r"
  391.    "Somebody get me a cheesburger!";
  392.  
  393.  
  394. ManyWindowsSessions()
  395. {
  396.    LogHere("ManyWindowsSessions()");
  397.    // start two ServeOS2 sessions to wait for our calls
  398.    RestoreDefaultDOSSettings();
  399.  
  400.    SetWindowTitle(Info().WinHandle,"OS/2 Demo: MULTIPLE SIMULTANEOUS WINDOWS SESSIONS");
  401.    EraseScreen();
  402.    printf("OS/2 supports your Windows applications.");
  403.    QCall("session_cmd", "/W", "/WIN", "/SEP",
  404.          "/SET", "IDLE_SECONDS=2", "/SET", "IDLE_SENSITIVITY=75",
  405.          "/SET", "DPMI_MEMORY_LIMIT=7",
  406.          SERVEOS2_SPEC, "/NAME", "Right", "/DELAY", "500" );
  407.    printf("\b,\nand OS/2 supports more Windows applications");
  408.    while ( !WinBossSelect("Right") ) suspend(800);
  409.    printf(", better,");
  410.  
  411.    // get the process ID of this session, so we can kill it later
  412.    lSwitchList = WinQuerySwitchList(Info().hab);
  413.    lSwitchCount = 1 + GetArraySpan(lSwitchList);
  414.    RightProcessID = 0;
  415.    for ( li = 0; li < lSwitchCount; li++ ) {
  416.       if ( 0 == WinQuerySwitchEntry(lSwitchList[li],lSwEntry)
  417.         && lSwEntry.title  &&  !stricmp(lSwEntry.title,"Session:ServeOS2.exe") ) {
  418.          RightProcessID = lSwEntry.process;
  419.          break;
  420.       }
  421.    }
  422.  
  423.    printf("\nthan ANY other operating system...");
  424.    QCall("session_cmd", "/W", "/WIN", "/SEP", "/ENH",
  425.          "/SET", "DPMI_MEMORY_LIMIT=4",
  426.          "/SET", "IDLE_SECONDS=2", "/SET", "IDLE_SENSITIVITY=75",
  427.          SERVEOS2_SPEC, "/NAME", "Left", "/DELAY", "500" );
  428.    printf("\b\b\b - bar none!");
  429.    while ( !WinBossSelect("Left") ) suspend(800);
  430.  
  431.    EraseScreen();
  432.    printf("With OS/2, you can run MULTIPLE copies of Windows 3.x sessions.");
  433.  
  434.    // start clock in left session at top, in middle
  435.    LClockWidth = LClockHeight = ScreenHeight / 4;
  436.    LClockLeft = (ScreenWidth/2-LClockWidth)/2;
  437.    LClockTop = ScreenHeight / 14;
  438.    LClockRight = LClockLeft + LClockWidth;
  439.    LClockBottom = LClockTop + LClockHeight;
  440.    WinBossSelect("Left");
  441.    if ( !WinFunction("spawn",LeftClockHandle,P_NOWAIT,"Clock.exe") )
  442.       FatalError("Unable to start clock.");
  443.    WinVoidFunction("SetWindowRect",LeftClockHandle,LClockLeft,LClockTop,LClockRight,LClockBottom);
  444.  
  445.    // start bigger clock on right
  446.    RClockWidth = RClockHeight = ScreenHeight / 3;
  447.    RClockLeft = ScreenWidth/2+(ScreenWidth/2-RClockWidth)/2;
  448.    RClockTop = LClockTop;
  449.    RClockRight = RClockLeft + RClockWidth;
  450.    RClockBottom = RClockTop + RClockHeight;
  451.    WinBossSelect("Right");
  452.    if ( !WinFunction("spawn",RightClockHandle,P_NOWAIT,"Clock.exe") )
  453.       FatalError("Unable to start clock.");
  454.    WinVoidFunction("SetWindowRect",RightClockHandle,RClockLeft,RClockTop,RClockRight,RClockBottom);
  455.  
  456.    printf("\nSuch as these two Windows clocks, each in its own separate session.");
  457.    WaitSeconds(13);
  458.  
  459.    // show that each different session is in a diff. mode with diff. settings
  460.    EraseScreen();
  461.    printf("Like DOS sessions under OS/2, each Windows session can have any configuration.");
  462.    WinVoidFunction("KeyPushFocusID",0);
  463.    WinVoidFunction("KeyStroke",WVK_ALT,'S');
  464.    WinVoidFunction("KeyStroke",WVK_UP);
  465.    WinVoidFunction("KeyStroke",WVK_RETURN);
  466.    printf("\nOn the right: Standard mode with 7 megabytes of memory.");
  467.    WaitSeconds(4);
  468.  
  469.    WinBossSelect("Left");
  470.    WinVoidFunction("SetActiveWindow",LeftClockHandle);
  471.    WinVoidFunction("KeyPushFocusID",0);
  472.    WinVoidFunction("KeyStroke",WVK_ALT,'S');
  473.    WinVoidFunction("KeyStroke",WVK_UP);
  474.    WinVoidFunction("KeyStroke",WVK_RETURN);
  475.    printf("\nOn the left: Enhanced mode with 4 megabytes of memory.");
  476.    WaitSeconds(7);
  477.    WinVoidFunction("KeyStroke",WVK_SPACE);
  478.  
  479.    WinBossSelect("Right");
  480.    WinVoidFunction("SetActiveWindow","About Clock");
  481.    WinVoidFunction("KeyStroke",WVK_SPACE);
  482.    WaitSeconds(3);
  483.  
  484.    EraseScreen();
  485.    printf("Each separate, seamless Windows session is just like one single Windows 3.x\n"
  486.           "running under DOS.");
  487.  
  488.    // Start Program Manager on the left and right, but with clock on top.  These
  489.    // program managers will fill up most of the screen side by side
  490.    ProgManWidth = ScreenWidth / 2 - ScreenWidth / 25;
  491.    ProgManTop = 0;
  492.    ProgManHeight = ScreenHeight - MyHeight - 20;
  493.    LProgmanLeft = ((ScreenWidth/2)-ProgManWidth)/2;
  494.    RProgmanLeft = ScreenWidth/2 + lProgmanLeft;
  495.    if ( !WinFunction("spawn",RightProgmanHandle,P_NOWAIT,"Progman.exe") )
  496.       FatalError("Unable to start right progman.");
  497.    WinVoidFunction("SetWindowRect",RightProgmanHandle,
  498.                    RProgmanLeft,ProgManTop,RProgmanLeft+ProgManWidth,ProgManTop+ProgManHeight);
  499.    WinVoidFunction("SetActiveWindow",RightClockHandle);
  500.  
  501.    // program manager on the left
  502.    WinBossSelect("Left");
  503.    if ( !WinFunction("spawn",LeftProgmanHandle,P_NOWAIT,"Progman.exe") )
  504.       FatalError("Unable to start left progman.");
  505.    WinVoidFunction("SetWindowRect",LeftProgmanHandle,
  506.                    LProgmanLeft,ProgManTop,LProgmanLeft+ProgManWidth,ProgManTop+ProgManHeight);
  507.    WinVoidFunction("SetActiveWindow",LeftClockHandle);
  508.  
  509.    // start Notepad.exe on the left side, bleeding a little onto the right
  510.    if ( !WinFunction("spawn",NotepadHandle,P_NOWAIT,"NotePad.exe") )
  511.       FatalError("Unable to start notepad.exe.");
  512.    NotepadTop = LClockBottom - 8;
  513.    NotepadLeft = 0;
  514.    NotepadRight = (ScreenWidth / 2) - (ScreenWidth / 20);
  515.    NotepadBottom = ScreenHeight - MyHeight + 5;
  516.    WinVoidFunction("SetWindowRect",NotepadHandle,NotepadLeft,NotepadTop,NotepadRight,NotepadBottom);
  517.  
  518.    WinBossSelect("Right");
  519.    if ( !WinFunction("spawn",RightCalcHandle,P_NOWAIT,"Calc.exe") )
  520.       FatalError("Unable to start calculator.");
  521.    WinVoidFunction("SetPosition",RightCalcHandle,ScreenWidth/2+ScreenWidth/30,RClockHeight + RClockTop - 13);
  522.    printf(" These two sessions, for example, are each SEPARATELY busy...");
  523.  
  524.    // spend a little while pushing buttons on the calculcators
  525.    WinBossSelect("Left");
  526.    WinVoidFunction("SetActiveWindow",NotepadHandle);
  527.    // Make sure notepad has word wrap on
  528.    WinFunction("GetMenu",NotepadMenu,NotepadHandle);
  529.    WinFunction("FindMenuString",WordWrapID,NotepadMenu,"Word Wrap");
  530.    #define WMF_CHECKED      0x08    // checkmark is next to item
  531.    #define WMF_BYCOMMAND    0x0000  // use the item ID
  532.    WinFunction("GetMenuState",WordWrapState,NotepadMenu,WordWrapID,WMF_BYCOMMAND);
  533.    if ( !(WMF_CHECKED & WordWrapState) )
  534.       WinVoidFunction("MenuCommand",NotepadHandle,WordWrapID);
  535.  
  536.    // send long Nombas advertisement to notpad
  537.    WinNoWaitFunction("SpeedKeys",NombasAdvertisement,50);
  538.  
  539.    WinBossSelect("Right");
  540.    WinVoidFunction("SetActiveWindow",RightCalcHandle);
  541.    WinVoidFunction("SpeedKeys","3.14159/-345+212.456=",900);
  542.  
  543.    // Cause a GPF in the right session, and wait till the GPF shows up
  544.    PreGPFWindow = GetActiveWindow();
  545.    WinNoWaitFunction("poke",0,UWORD32);
  546.    while ( PreGPFWindow == GetActiveWindow() ) suspend(800);
  547.    WaitSeconds(2);
  548.  
  549.    EraseScreen();
  550.    printf("OOOPS!  There's that dreaded Windows GPF in the session on the right.");
  551.    for ( i = 0; i < 4; i++ ) {
  552.       DosBeep(400,300);
  553.       DosBeep(200,300);
  554.    }
  555.    WaitSeconds(2);
  556.    printf("\nBut OS/2's crash protection lets the other Windows session continue...");
  557.    WaitSeconds(8);
  558.  
  559. //   WinBossSelect("Left");
  560. //   WinVoidFunction("SetActiveWindow",LeftCalcHandle);
  561. //   WinVoidFunction("SpeedKeys","6.2+3/4.5+8.2+4-0.15/3=",900);
  562.  
  563.    EraseScreen();
  564.    printf("OS/2 can end the \"CRASHED\" windows session...");
  565.    WaitSeconds(2);
  566.  
  567.    KeyStroke(VK_SPACE);
  568.    QCall( "kill_cmd", RightProcessID );
  569.    printf("\b\b\b, and continue without worry.");
  570.    WaitSeconds(7);
  571.  
  572.    EraseScreen();
  573.    printf("OS/2 truly is a better Window(s) than Windows\n"
  574.           "(More Wow than WOW!)");
  575.    WaitSeconds(4);
  576.    printf("   Let's continue...");
  577.    WaitSeconds(1);
  578.  
  579.    QCall( "kill_cmd", "Session:ServeOS2" );
  580.  
  581. }
  582.  
  583. /*************** DOS CONFIGURATIONS ***************/
  584. DosConfigurations()
  585. {
  586.    LogHere("DosConfigurations()");
  587.    SetWindowTitle(Info().WinHandle,"OS/2 Demo: BYE BYE MEMORY MANAGERS");
  588.  
  589.    EraseScreen();
  590.    printf("With OS/2, you don't need DOS memory managers, reboots, and frustration.\n"
  591.           "Each simultaneous DOS session in OS/2 has independent memory configuration.");
  592.  
  593.    lRowIncrement = ScreenHeight / 20;  // how much to raise each window
  594.    lColIncrement = ScreenWidth / 20;   // how much to push each window to the right
  595.  
  596.    lRow = MyHeight + ScreenHeight / 50;
  597.    lCol = ScreenWidth / 20;
  598.    sprintf(lPosition,"%d,%d",lCol,lRow);
  599.    RestoreDefaultDOSSettings();
  600.    QCall( "session_cmd", "/TITLE", "Teeny-Tiny DOS Memory", "/F", "/WIN", "/DOS",
  601.           "/FONT", "14x8", "/POS", lPosition, "/K",
  602.           "/SET", "DPMI_DOS_API=DISABLED",
  603.           "/SET", "DPMI_MEMORY_LIMIT=0",
  604.           "/SET", "DPMI_NETWORK_BUFF_SIZE=0",
  605.           "/SET", "EMS_FRAME_LOCATION=NONE",
  606.           "/SET", "EMS_MEMORY_LIMIT=0",
  607.           "/SET", "EMS_LOW_OS_MAP_REGION=0",
  608.           "/SET", "EMS_MEMORY_LIMIT=0",
  609.           "/SET", "XMS_HANDLES=0",
  610.           "/SET", "XMS_MEMORY_LIMIT=0",
  611.           "/SET", "XMS_MINIMUM_HMA=0",
  612.           "/SET", "DOS_RMSIZE=90",
  613.           "MEM.EXE" );
  614.    WaitSeconds(2);
  615.    EraseScreen();
  616.    printf("Here is a session with a mere 90K of memory...");
  617.    WaitSeconds(10);
  618.  
  619.    lRow += lRowIncrement; lCol += lColIncrement;
  620.    sprintf(lPosition,"%d,%d",lCol,lRow);
  621.    RestoreDefaultDOSSettings();
  622.    QCall( "session_cmd", "/TITLE", "Lots of EMS Memory", "/F", "/WIN", "/DOS",
  623.           "/FONT", "14x8", "/POS", lPosition, "/K",
  624.           "/SET", "DPMI_DOS_API=DISABLED",
  625.           "/SET", "DPMI_MEMORY_LIMIT=0",
  626.           "/SET", "DPMI_NETWORK_BUFF_SIZE=0",
  627.           "/SET", "EMS_FRAME_LOCATION=AUTO",
  628.           "/SET", "EMS_LOW_OS_MAP_REGION=0",
  629.           "/SET", "EMS_MEMORY_LIMIT=32768",
  630.           "/SET", "XMS_HANDLES=0",
  631.           "/SET", "XMS_MEMORY_LIMIT=0",
  632.           "/SET", "XMS_MINIMUM_HMA=0",
  633.           "MEM.EXE" );
  634.    WaitSeconds(1);
  635.    EraseScreen();
  636.    printf("Here is a session with 32 megabytes of EMS memory...");
  637.    WaitSeconds(7);
  638.  
  639.    lRow += lRowIncrement; lCol += lColIncrement;
  640.    sprintf(lPosition,"%d,%d",lCol,lRow);
  641.    RestoreDefaultDOSSettings();
  642.    QCall( "session_cmd", "/TITLE", "Lots of XMS Memory", "/F", "/WIN", "/DOS",
  643.           "/FONT", "14x8", "/POS", lPosition, "/K",
  644.           "/SET", "DPMI_DOS_API=DISABLED",
  645.           "/SET", "DPMI_MEMORY_LIMIT=0",
  646.           "/SET", "DPMI_NETWORK_BUFF_SIZE=0",
  647.           "/SET", "EMS_FRAME_LOCATION=NONE",
  648.           "/SET", "EMS_MEMORY_LIMIT=0",
  649.           "/SET", "EMS_LOW_OS_MAP_REGION=0",
  650.           "/SET", "EMS_MEMORY_LIMIT=0",
  651.           "/SET", "XMS_HANDLES=127",
  652.           "/SET", "XMS_MEMORY_LIMIT=16384",
  653.           "/SET", "XMS_MINIMUM_HMA=63",
  654.           "MEM.EXE" );
  655.    WaitSeconds(1);
  656.    EraseScreen();
  657.    printf("Here is a session with 16 megabyte of XMS memory...");
  658.    WaitSeconds(7);
  659.  
  660.    lRow += lRowIncrement; lCol += lColIncrement;
  661.    sprintf(lPosition,"%d,%d",lCol,lRow);
  662.    RestoreDefaultDOSSettings();
  663.    QCall( "session_cmd", "/TITLE", "Tons of Virtual Memory", "/F", "/WIN", "/DOS",
  664.           "/FONT", "14x8", "/POS", lPosition, "/K",
  665.           "/SET", "DPMI_DOS_API=ENABLED",
  666.           "/SET", "DPMI_MEMORY_LIMIT=512",
  667.           "/SET", "DPMI_NETWORK_BUFF_SIZE=0",
  668.           "/SET", "EMS_FRAME_LOCATION=AUTO",
  669.           "/SET", "EMS_LOW_OS_MAP_REGION=0",
  670.           "/SET", "EMS_MEMORY_LIMIT=32768",
  671.           "/SET", "XMS_HANDLES=127",
  672.           "/SET", "XMS_MEMORY_LIMIT=16384",
  673.           "/SET", "XMS_MINIMUM_HMA=63",
  674.           "MEM.EXE" );
  675.    WaitSeconds(1);
  676.    EraseScreen();
  677.    printf("Plus this session with 32 Mbyte EMS, 16 MByte XMS, and 512 MByte DPMI memory."
  678.           "\nThat's 560 Megs of memory--much more memory than is in this computer!");
  679.    WaitSeconds(7);
  680.  
  681.    lRow += lRowIncrement; lCol += lColIncrement;
  682.    sprintf(lPosition,"%d,%d",lCol,lRow);
  683.    RestoreDefaultDOSSettings();
  684.    QCall( "session_cmd", "/TITLE", "Lots of DOS Memory", "/F", "/WIN", "/DOS",
  685.           "/FONT", "14x8", "/POS", lPosition, "/K",
  686.           "/SET", "VIDEO_MODE_RESTRICTION=CGA            ",
  687.           "/SET", "DOS_DEVICE=",
  688.           "/SET", "DOS_FCBS=1",
  689.           "/SET", "DOS_FCBS_KEEP=1",
  690.           "/SET", "DOS_FILES=20",
  691.           "/SET", "DOS_HIGH=1",
  692.           "/SET", "DOS_RMSIZE=640",
  693.           "/SET", "DOS_UMB=1",
  694.           "/SET", "DPMI_DOS_API=DISABLED",
  695.           "/SET", "DPMI_MEMORY_LIMIT=0",
  696.           "/SET", "DPMI_NETWORK_BUFF_SIZE=0",
  697.           "/SET", "EMS_FRAME_LOCATION=NONE",
  698.           "/SET", "EMS_MEMORY_LIMIT=0",
  699.           "/SET", "EMS_LOW_OS_MAP_REGION=0",
  700.           "/SET", "EMS_MEMORY_LIMIT=0",
  701.           "/SET", "XMS_HANDLES=0",
  702.           "/SET", "XMS_MEMORY_LIMIT=0",
  703.           "/SET", "XMS_MINIMUM_HMA=0",
  704.           "MEM.EXE" );
  705.    WaitSeconds(1);
  706.    EraseScreen();
  707.    printf("Finally, here is a DOS session with over 700K conventional memory.");
  708.    WaitSeconds(8);
  709.  
  710.    QCall( "domenu_cmd", "Lots of DOS Memory", "Close" );
  711.    QCall( "domenu_cmd", "Tons of Virtual Memory", "Close" );
  712.    QCall( "domenu_cmd", "Lots of XMS Memory", "Close" );
  713.    QCall( "domenu_cmd", "Lots of EMS Memory", "Close" );
  714.    QCall( "domenu_cmd", "Teeny-Tiny DOS Memory", "Close" );
  715. }
  716.  
  717. /******************* PMApplets *******************/
  718.  
  719. PMApplets()
  720. {
  721.    LogHere("DosConfigurations()");
  722.    SetWindowTitle(Info().WinHandle,"OS/2 Demo: PM Appletts");
  723.  
  724.    EraseScreen();
  725.    printf("OS/2, the 32-bit multi-threaded, multi-tasking operating system\n"
  726.           "truly shines when running true 32-bit PM applications...");
  727.  
  728.    // start pmspread
  729.    PMSpreadWidth = ScreenWidth * 3 / 5 ;
  730.    PMSpreadHeight = (ScreenHeight - MyHeight) * 3 / 5 ;
  731.    PMSpreadCol = ScreenWidth - PMSpreadWidth;
  732.    PMSpreadRow = MyHeight;
  733.    sprintf(lSize,"%d,%d",PMSpreadWidth,PMSpreadHeight);
  734.    sprintf(lPos,"%d,%d",PMSpreadCol,PMSpreadRow);
  735.    QCall( "session_cmd", "/Title", "untitled - Spreadsheet", "/PM",
  736.           "/SIZE", lSize, "/POS", lPos, "PMSpread.exe" );
  737.  
  738.    // start klondike
  739.    KlondikeWidth = ScreenWidth * 5 / 7 ;
  740.    KlondikeHeight = (ScreenHeight - MyHeight) * 5 / 7 ;
  741.    KlondikeCol = 0;
  742.    KlondikeRow = MyHeight + (ScreenHeight - MyHeight) - KlondikeHeight;
  743.    sprintf(lSize,"%d,%d",KlondikeWidth,KlondikeHeight);
  744.    sprintf(lPos,"%d,%d",KlondikeCol,KlondikeRow);
  745.    QCall( "session_cmd", "/Title", "Klondike", "/PM", "/B",
  746.           "/SIZE", lSize, "/POS", lPos, "Klondike.exe" );
  747.    QCall( "domenu_cmd", "Klondike", "None" );
  748.  
  749.    EraseScreen();
  750.    printf("What do you want to do?  Work?  Play?");
  751.  
  752.    // tell klondike to go automatic
  753.    QCall( "domenu_cmd", "Klondike", "Very Slow" );
  754.    QCall( "domenu_cmd", "Klondike", "Auto play" );
  755.  
  756.    printf("  How about Work AND play?!\n"
  757.           "OS/2 will even play solitaire for you.  Talk about productivity!");
  758.  
  759.    #define PLAY_TIME    30    // how many seconds to play
  760.    StartPlay = time();
  761.    KeyPushFocusID(NULL);
  762.    directions = { VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN };
  763.    do {
  764.       // enter a number in the spreadsheet
  765.       for ( backspace = 0; backspace < 3; backspace++ ) {
  766.          suspend(250);
  767.          KeyStroke(VK_BACKSPACE);
  768.       } 
  769.       sprintf(RandomNumber,"%d",rand() % 1000);
  770.       SpeedKeys(RandomNumber,300);
  771.       suspend(300);
  772.       KeyStroke(VK_ENTER);
  773.       suspend(300);
  774.       KeyStroke(directions[rand() % 4]);
  775.       suspend(300);
  776.    } while ( difftime(time(),StartPlay) < PLAY_TIME );
  777.  
  778.    // turn off auto play
  779.    QCall( "switch_cmd", "Klondike" );
  780.    WaitSeconds(1);
  781.    KeyStroke(VK_CTRL,'P');
  782.    WaitSeconds(2);
  783.  
  784.    QCall( "kill_cmd", "Spreadsheet" );
  785.    QCall( "kill_cmd", "Klondike" );
  786. }
  787.  
  788. /************** QCall ************************
  789.  *** Quick call to included .CMD utilities ***
  790.  *********************************************/
  791.  
  792. QCall(pCmdName /*lotta args */)
  793. {
  794.    lArgc = va_arg();
  795.    for ( lVarCount = 0; lVarCount < lArgc; lVarCount++ ) {
  796.       lVar = va_arg(lVarCount);
  797.       if ( 1 == DataDimension(lVar) )
  798.          strcpy(lArgv[lVarCount],lVar);
  799.       else
  800.          sprintf(lArgv[lVarCount],"%d",lVar);
  801.    }
  802.    function(pCmdName,lArgc,lArgv);
  803. }
  804.  
  805.  
  806. #define main session_cmd
  807. #include <Session.cmd>
  808.  
  809. #define main switch_cmd
  810. #include <Switch.cmd>
  811.  
  812. #define main kill_cmd
  813. #include <Kill.cmd>
  814. KillQuietMode = True;
  815.  
  816. #define main winset_cmd
  817. #include <WinSet.cmd>
  818.  
  819. #define main domenu_cmd
  820. #include <DoMenu.cmd>
  821.  
  822. #define main switch_cmd
  823. #include <Switch.cmd>
  824.  
  825. /************************ SESSION ************************
  826.  *** session_cmd is called a lot here, so provide this ***
  827.  *** means to restore original sessions settings       ***
  828.  *********************************************************/
  829.  
  830. gDefaultDOSSettings = {
  831.    "COM_DIRECT_ACCESS=0",  // 0 or 1
  832.    "COM_HOLD=0",           // 0 or 1
  833.    "COM_RECEIVE_BUFFER_FLUSH="   // select one of the following
  834.       //"ALL",
  835.       //"RECEIVE DATA INTERRUPT ENABLE",
  836.       //"SWITCH TO FOREGROUND",
  837.       "NONE",
  838.    "COM_SELECT="
  839.       " ALL",
  840.       //"COM1",
  841.       //"COM2",
  842.       //"COM3",
  843.       //"COM4",
  844.       //"NONE",
  845.    "DOS_AUTOEXEC=C:\\AUTOEXEC.BAT",
  846.    "DOS_BACKGROUND_EXECUTION=1", // 0 or 1
  847.    "DOS_BREAK=1", // 0 or 1
  848.    "DOS_DEVICE=SIZE=0  C:\\OS2\\MDOS\\ANSI.SYS",
  849.    "DOS_FCBS=16",
  850.    "DOS_FCBS_KEEP=8",
  851.    "DOS_FILES=75",
  852.    "DOS_HIGH=0",  // 0 or 1
  853.    "DOS_LASTDRIVE=Z",
  854.    "DOS_RMSIZE=640",
  855.    "DOS_SHELL=C:\\OS2\\MDOS\\COMMAND.COM C:\\OS2\\MDOS",
  856.    "DOS_UMB=0",   // 0 or 1
  857.    "DOS_VERSION=DCJSS02.EXE,3,40,255"
  858.       "\nDFIA0MOD.SYS,3,40,255"
  859.       "\nDXMA0MOD.SYS,3,40,255"
  860.       "\nEXCEL.EXE,10,10,4"
  861.       "\nIBMCACHE.COM,3,40,255"
  862.       "\nIBMCACHE.SYS,3,40,255"
  863.       "\nISAM.EXE,3,40,255"
  864.       "\nISAM2.EXE,3,40,255"
  865.       "\nISQL.EXE,3,40,255"
  866.       "\nMSD.EXE,5,00,255"
  867.       "\nNET3.COM,3,40,255"
  868.       "\nNETX.COM,4,00,255"
  869.       "\nNETX.EXE,5,00,255"
  870.       "\nPSCPG.COM,3,40,255"
  871.       "\nSAF.EXE,3,40,255"
  872.       "\nWIN200.BIN,10,10,4",
  873.    "DPMI_DOS_API="   // select one of the following
  874.       "AUTO",
  875.       //"ENABLED",
  876.       //"DISABLED",
  877.    "DPMI_MEMORY_LIMIT=4",
  878.    "DPMI_NETWORK_BUFF_SIZE=8",
  879.    "EMS_FRAME_LOCATION="
  880.       "AUTO",
  881.       //"NONE",
  882.       //"C000",
  883.       //"C400",
  884.       //"C800",
  885.       //"CC00",
  886.       //"D000",
  887.       //"D400",
  888.       //"D800",
  889.       //"DC00",
  890.       //"8000",
  891.       //"8400",
  892.       //"8800",
  893.       //"8C00",
  894.       //"9000",
  895.    "EMS_HIGH_OS_MAP_REGION=0",
  896.    "EMS_LOW_OS_MAP_REGION=384",
  897.    "EMS_MEMORY_LIMIT=2048",
  898.    "HW_NOSOUND=0",      // 0 or 1
  899.    "HW_ROM_TO_RAM=0",   // 0 or 1
  900.    "HW_TIMER=0",        // 0 or 1
  901.    "IDLE_SECONDS=0",
  902.    "IDLE_SENSITIVITY=75",
  903.    "INT_DURING_IO=0",   // 0 or 1
  904.    "KBD_ALTHOME_BYPASS=0", // 0 or 1
  905.    "KBD_BUFFER_EXTEND=1",  // 0 or 1
  906.    "KBD_CTRL_BYPASS="   // select one of the following
  907.       "NONE",
  908.       //"ALT_ESC",
  909.       //"CTRL_ESC",
  910.    "KBD_RATE_LOCK=0",   // 0 or 1
  911.    "MEM_EXCLUDE_REGIONS=",
  912.    "MEM_INCLUDE_REGIONS=",
  913.    "MOUSE_EXCLUSIVE_ACCESS=0",   // 0 or 1
  914.    "PRINT_SEPARATE_OUTPUT=1",    // 0 or 1
  915.    "PRINT_TIMEOUT=15",
  916.    "VIDEO_8514A_XGA_IOTRAP=1",   // 0 or 1
  917.    "VIDEO_FASTPASTE=0",          // 0 or 1
  918.    "VIDEO_MODE_RESTRICTION="  // select one of the following
  919.       "NONE         ",
  920.       //"CGA            ",
  921.       //"MONO           ",
  922.    "VIDEO_ONDEMAND_MEMORY=1",    // 0 or 1
  923.    "VIDEO_RETRACE_EMULATION=1",  // 0 or 1
  924.    "VIDEO_ROM_EMULATION=1",      // 0 or 1
  925.    "VIDEO_SWITCH_NOTIFICATION=0",// 0 or 1
  926.    "VIDEO_WINDOW_REFRESH=1",
  927.    "XMS_HANDLES=32",
  928.    "XMS_MEMORY_LIMIT=2048",
  929.    "XMS_MINIMUM_HMA=0"
  930. };
  931.  
  932. RestoreDefaultDOSSettings()
  933. {
  934.    lSetCount = 1 + GetArraySpan(gDefaultDOSSettings);
  935.    undefine(MyDefaultDOSSettings);
  936.    for ( lSetting = 0; lSetting < lSetCount; lSetting++ )
  937.       strcpy(MyDefaultDOSSettings[lSetting],gDefaultDOSSettings[lSetting]);
  938. }
  939.  
  940. /*************** UTILITIES ************/
  941. SetScreenColors(pFore,pBack)
  942. {
  943.    // set color for bright white on blue background
  944.    #define BOLD_ON      1
  945.    #define BLACK_FOR    30
  946.    #define RED_FORE     31
  947.    #define GREEN_FORE   32
  948.    #define YELLOW_FORE  33
  949.    #define BLUE_FORE    34
  950.    #define MAGENTA_FORE 35
  951.    #define CYAN_FORE    36
  952.    #define WHITE_FORE   37
  953.    #define BLACK_BACK   40
  954.    #define RED_BACK     41
  955.    #define GREEN_BACK   42
  956.    #define YELLOW_BACK  43
  957.    #define BLUE_BACK    44
  958.    #define MAGENTA_BACK 45
  959.    #define CYAN_BACK    46
  960.    #define WHITE_BACK   47
  961.    printf("\033[0;%d;%d;%dm",YELLOW_FORE,BLUE_BACK,BOLD_ON);
  962. }
  963.  
  964. EraseScreen()  // clear screen
  965. {
  966.    printf("\033[2J");
  967. }
  968.  
  969. WaitSeconds(lSec)
  970. {
  971.    lStartTime = time();
  972.    while ( difftime(time(),lStartTime) < lSec )
  973.       suspend(500);
  974. }
  975.  
  976. FatalError(lFormatString/*,arg1,arg2...*/)
  977. {
  978.    va_start(lVaList,lFormatString);
  979.    printf("\a\a\a\n");
  980.    vprintf(lFormatString,lVaList);
  981.    va_end(lVaList);
  982.    abort();
  983. }
  984.  
  985. DosBeep(Frequency,Duration)   // play specified Frequency, in Hz, for specified
  986. {                             // duration, in milliseconds
  987.    #define ORD_DOS32BEEP   286
  988.    return DynamicLink("doscalls",ORD_DOS32BEEP,BIT32,CDECL,Frequency,Duration)
  989. }
  990.  
  991. //***************************************************************************
  992. //*** LogFile routines - If the OS2DEMO_LOGFILE environment variable is   ***
  993. //*** not defined then these do nothing.  Else they initialize the log    ***
  994. //*** file to append when the demo started at the end of the existing     ***
  995. //*** log file.  LogHere() messages are added to the log file whenever    ***
  996. //*** LogHere() is called, however these messages ovewrite each other so  ***
  997. //*** that the log file does not grow too very large.  LogHere() messages ***
  998. //*** timestamp and put a brief message so that you can look at the       ***
  999. //*** file later to get an idea of what the last message was before a     ***
  1000. //*** demo ever hangs                                                     ***
  1001.  
  1002. gLogFileSeek;
  1003. #define EOF_CHAR  ( 'Z' - 'A' + 1 ) // ctrl-Z = EOF
  1004. InitializeLogFile(); // initialize log file when starting OS2DEMO
  1005.  
  1006.  
  1007. LogHere(FormatString/*,arg1,arg2,arg3*/)
  1008. {
  1009.    if ( defined(gLogFileSeek) ) {
  1010.       if ( fp = fopen(OS2DEMO_LOGFILE,"r+t") ) {
  1011.  
  1012.          // print this messages where the log messages go
  1013.          fseek(fp,gLogFileSeek);
  1014.          va_start(va_list,FormatString);
  1015.          vfprintf(fp,FormatString,va_list);
  1016.          va_end(va_list);
  1017.  
  1018.          // print the current time
  1019.          CurrentTime = ctime(time());
  1020.          CurrentTime[strlen(CurrentTime)-1] = '\0';
  1021.          fprintf(fp,"\nLogHere at: %s\n",CurrentTime);
  1022.  
  1023.          // add ctrl-z (EOF) character after this message
  1024.          fprintf(fp,"%c",EOF_CHAR);
  1025.          fclose(fp);
  1026.       }
  1027.    }
  1028. }
  1029.  
  1030. InitializeLogFile()  // start log, set timestamp of start, and save seek position
  1031. {
  1032.    if ( defined(OS2DEMO_LOGFILE) ) {
  1033.       if ( (fp = fopen(OS2DEMO_LOGFILE,"r+b"))
  1034.         || (fp = fopen(OS2DEMO_LOGFILE,"wb")) ) {
  1035.          // read to end of file or EOF_CHAR
  1036.          fseek(fp,0,SEEK_SET);
  1037.          gLogFileSeek = ftell(fp);
  1038.          while ( EOF != (lChar = fgetc(fp))  &&  EOF_CHAR != lChar ) {
  1039.             gLogFileSeek = ftell(fp);
  1040.          }
  1041.  
  1042.          // write log time start message
  1043.          fseek(fp,gLogFileSeek);
  1044.          CurrentTime = ctime(time());
  1045.          CurrentTime[strlen(CurrentTime)-1] = '\0';
  1046.          fprintf(fp,"\r\n\r\n\r\nStartTest at: %s\r\n\r\n",CurrentTime);
  1047.          // remember where to write following messages
  1048.          gLogFileSeek = ftell(fp);
  1049.          fclose(fp);
  1050.       }
  1051.    }
  1052. }
  1053.  
  1054.  
  1055.  
  1056. /********************** MAIN OS2DEMO ROUTINE ***********************/
  1057.  
  1058. // Make a nicer screen color using ANSI codes;  Black on white?
  1059. SetScreenColors();
  1060. EraseScreen();
  1061.  
  1062. // get screen dimensions
  1063. GetScreenSize(ScreenWidth,ScreenHeight);
  1064. GetSize(Info().WinHandle,MyWidth,MyHeight);
  1065.  
  1066. RunForever()
  1067. {
  1068.    for( ; ; ) {
  1069.  
  1070.       LogHere("Start sesson all over again");
  1071.  
  1072.       ManyDosSessions();
  1073.  
  1074.       DosConfigurations();
  1075.  
  1076.       ManyWindowsSessions();
  1077.  
  1078.       PMApplets();
  1079.  
  1080.       //WorkplaceShell();  not written yet
  1081.  
  1082.       //WorkingTogether(); not written yet
  1083.  
  1084.       EraseScreen();
  1085.       SetWindowTitle(Info().WinHandle,"OS/2 Demo: ALL DONE!");
  1086.       printf("That was such a fun demo!  Let's do it again.");
  1087.       WaitSeconds(6);
  1088.    }
  1089. }
  1090.  
  1091.  
  1092.