home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ioctlapi.zip / appsrc.zip / commands.c < prev    next >
C/C++ Source or Header  |  1999-12-16  |  12KB  |  384 lines

  1. //-----------------------------------------------------------------------------
  2. // Freeware.  This file may be used freely to promote the ioctl90 mixer API.
  3. //-----------------------------------------------------------------------------
  4. // commands.c
  5. //
  6. // User I/O and menu processing
  7. //-----------------------------------------------------------------------------
  8.  
  9. #include <stdlib.h>
  10. #include <string.h> // memset
  11. #include <ctype.h> // toupper
  12. #include <stdio.h>
  13.  
  14. #include <os2.h>                        // typedefs
  15.  
  16. #include "data.h"
  17. #include "asciinum.h"
  18. #include "util.h"
  19. #include "commands.h"
  20. #include "ioctl90.h"
  21. #include "mixerapi.h"
  22.  
  23. char Line [256];
  24. BOOL fCommandsDone = FALSE;
  25.  
  26. void CommandsHelp (void)
  27. {
  28.    printf ("\nIOCTL90 Mixer API test program.  " __DATE__ ".  Joe Nord\n");
  29.    printf ("\n");
  30.    printf ("IOCTL Category 0x90, functions:\n");
  31.    printf ("40 - MonoInSet        60 - MonoInQuery\n");
  32.    printf ("41 - PhoneSet         61 - PhoneQuery\n");
  33.    printf ("42 - MicSet           62 - MicQuery\n");
  34.    printf ("43 - LineSet          63 - LineQuery\n");
  35.    printf ("44 - CDSet            64 - CDQuery\n");
  36.    printf ("45 - VideoSet         65 - VideoQuery\n");
  37.    printf ("46 - AuxSet           66 - AuxQuery\n");
  38.    printf ("4B - BassTrebleSet    6B - BassTrebleQuery\n");
  39.    printf ("4C - ThreeDSet        6C - ThreeDQuery\n");
  40.    printf ("4D - StreamVolSet     6D - StreamVolQuery\n");
  41.    printf ("4E - RecordSrcSet     6E - RecordSrcQuery\n");
  42.    printf ("4F - RecordGainSet    6F - RecordGainQuery\n");
  43.    printf ("80 - ApiLevelQuery\n");
  44.    printf ("81 - GetApiMap\n");
  45.    printf ("82 - CallbackReg (automatic at program start)\n");
  46.    printf ("83 - MsgBuf [0, 1]\n");
  47.    printf ("\n");
  48.    printf ("Commands:\n");
  49.    printf ("   \"xx LL RR m\" - Send IOCTL 90, function xx (hex) with\n");
  50.    printf ("                  parms LL and RR (decimal) and m (boolean).\n");
  51.    printf ("                  The volume parms are only required on Set functions.\n");
  52.    printf ("                  Right volume defaults to same as left.\n");
  53.    printf ("                  m (mute) defaults to 0 => Audible\n");
  54.    printf ("   \"q\"          - Quit\n");
  55.    printf ("\n");
  56. }
  57.  
  58. void FilterLine (char *pString)
  59. {
  60.    while (*pString)
  61.    {
  62.       *pString = toupper (*pString);
  63.       if (*pString != 0 && *pString < ' ')
  64.          *pString = ' ';
  65.       pString++;
  66.    }
  67. }
  68.  
  69. void CommandsProcessLine (void)
  70. {
  71.    int    iRC;
  72.    ULONG  ulRC;
  73.    int    i;
  74.    BOOL   fBadCommand = FALSE;
  75.    USHORT usFunc;
  76.    USHORT usLeft;
  77.    USHORT usRight;
  78.    USHORT usMute;
  79.    USHORT usBase;
  80.    MIXSTRUCT Mix;
  81.    ULONG  ulAPILevel = 1;       // Default level is level 1
  82.    BYTE   APIMap[256];
  83.    MIXMSGBUF MsgBuf;
  84.    char   *pMessages;
  85.    BOOL   fClear;
  86.  
  87.  
  88.    FilterLine (Line);                          // Convert to upper case
  89.    i = 0;
  90.    while (Line[i] != '\0' && Line[i] <= ' ')   // Skip spaces
  91.       i++;
  92.  
  93.    switch ( Line[i] )
  94.    {
  95.    case 'Q':
  96.       fCommandsDone = TRUE;
  97.       break;
  98.  
  99.    case 'H':
  100.    case '?':
  101.       CommandsHelp ();
  102.       break;
  103.  
  104.    case '\0': // No command entered (enter pressed)
  105.       break;
  106.  
  107.    case '4':
  108.    case '6':
  109.    case '8':
  110.       iRC = AsciiToUshort (&Line[i], &usFunc, BASE16);
  111.       if (iRC == 0)
  112.       {
  113.          if (usFunc == 0x4E) // Record source set
  114.             usBase = BASE16;
  115.          else
  116.             usBase = BASE10;
  117.  
  118.          if (usFunc >= 0x40 && usFunc <= 0x4F)
  119.          {
  120.             // Is a set function
  121.  
  122.             // Skip the function number and following spaces
  123.             // Index to left volume parm
  124.             while (Line[i] != '\0' && Line[i] > ' ')
  125.                i++;
  126.             while (Line[i] != '\0' && Line[i] <= ' ')
  127.                i++;
  128.  
  129.             if (Line[i] == '\0')
  130.             {
  131.                printf ("Left volume is required\n");
  132.                break;
  133.             }
  134.  
  135.             usLeft = 0;
  136.             iRC = AsciiToUshort (&Line[i], &usLeft, usBase);
  137.  
  138.             if (usBase == BASE16)
  139.             {
  140.                if (iRC != 0)
  141.                {
  142.                   printf ("Left volume must be range 0..0xFFFF hex\n");
  143.                   break;
  144.                }
  145.             }
  146.             else
  147.             {
  148.                if (iRC != 0 || usLeft > 100)
  149.                {
  150.                   printf ("Left volume must be range 0..100 decimal\n");
  151.                   break;
  152.                }
  153.             }
  154.  
  155.             // Skip the left volume and following spaces
  156.             // Index to right volume parm
  157.             while (Line[i] != '\0' && Line[i] > ' ')
  158.                i++;
  159.             while (Line[i] != '\0' && Line[i] <= ' ')
  160.                i++;
  161.  
  162.             if (Line[i] == '\0')
  163.             {
  164.                if (usFunc == 0x4E)
  165.                {
  166.                   usRight = 0;      // Unused parm (set to zero)
  167.                }
  168.                else
  169.                {
  170.                   usRight = usLeft; // Default right to same as left
  171.                   usMute = 0;
  172.                }
  173.             }
  174.             else // Right volume is specified
  175.             {
  176.                if (usFunc == 0x4E)
  177.                {
  178.                   printf ("Right volume is ununsed on this function\n");
  179.                   break;
  180.                }
  181.  
  182.                usRight = 0;
  183.                iRC = AsciiToUshort (&Line[i], &usRight, BASE10);
  184.                if (iRC != 0 || usRight > 100)
  185.                {
  186.                   printf ("Right volume must be range 0..100 decimal\n");
  187.                   break;
  188.                }
  189.  
  190.                // Skip the right volume and following spaces
  191.                // Index to mute parm
  192.                while (Line[i] != '\0' && Line[i] > ' ')
  193.                   i++;
  194.                while (Line[i] != '\0' && Line[i] <= ' ')
  195.                   i++;
  196.  
  197.                usMute = 0;
  198.                if (Line[i] != '\0')     // Mute parm is specified
  199.                {
  200.                   iRC = AsciiToUshort (&Line[i], &usMute, BASE16);
  201.                   if (iRC != 0 || usMute > 3)
  202.                   {
  203.                      printf ("Mute must be 0..3\n");
  204.                      break;
  205.                   }
  206.                }
  207.             }
  208.  
  209.             // Issue the IOCTL
  210.             // printf ("DosDevIOCTL 90, %x, %d, %d, %d\n", usFunc, usLeft, usRight, usMute);
  211.             memset (&Mix, '\0', sizeof(Mix));
  212.             Mix.Mute     = usMute;
  213.             Mix.VolumeL  = usLeft;
  214.             Mix.VolumeR  = usRight;
  215.             mixerapiIOCTL90 (usFunc, &Mix, sizeof(Mix));
  216.          } 
  217.          else if (usFunc >= 0x60 && usFunc <= 0x6F)
  218.          {
  219.             // Is a query function
  220.  
  221.             // Skip the function number and following spaces
  222.             // Index to left volume parm
  223.             while (Line[i] != '\0' && Line[i] > ' ')
  224.                i++;
  225.             while (Line[i] != '\0' && Line[i] <= ' ')
  226.                i++;
  227.  
  228.             if (Line[i] != '\0')
  229.             {
  230.                printf ("No parms on query functions\n");
  231.                break;
  232.             }
  233.  
  234.             // Issue the IOCTL
  235.             usLeft = 0; 
  236.             usRight = 0;
  237.             usMute = 0;
  238.             memset (&Mix, '\0', sizeof(Mix));
  239.  
  240.             // printf ("DosDevIOCTL 90, %x, %d, %d, %d\n", usFunc, usLeft, usRight, usMute);
  241.             ulRC = mixerapiIOCTL90 (usFunc, &Mix, sizeof(Mix));
  242.             if (ulRC != 0)
  243.             {
  244.                printf ("IOCTL Failed (0x%x)\n", ulRC);
  245.                break;
  246.             }
  247.  
  248.             usMute  = Mix.Mute;
  249.             usLeft  = Mix.VolumeL;
  250.             usRight = Mix.VolumeR;
  251.  
  252.             if (usBase == BASE16)
  253.             {
  254.                printf (" %x %x %x %x\n", usFunc, usLeft, usRight, usMute);
  255.             }
  256.             else
  257.             {
  258.                printf (" %x %u %u %x\n", usFunc, usLeft, usRight, usMute);
  259.             }
  260.  
  261.          }
  262.          else if (usFunc == 0x80)  // ApiLevelQuery
  263.          {
  264.             ulRC = mixerapiIOCTL90 (0x80, &ulAPILevel, sizeof(ulAPILevel));
  265.             if (ulRC != 0)
  266.             {
  267.                printf ("IOCTL Failed (0x%x)\n", ulRC);
  268.                break;
  269.             }
  270.             printf ("APILevel = %u\n", ulAPILevel);
  271.          }
  272.          else if (usFunc == 0x81)  // GetApiMap
  273.          {
  274.             memset (&APIMap, '\0', sizeof(APIMap));
  275.             ulRC = mixerapiIOCTL90 (0x81, &APIMap, sizeof(APIMap));
  276.             if (ulRC != 0)
  277.             {
  278.                printf ("IOCTL Failed (0x%x)\n", ulRC);
  279.                break;
  280.             }
  281.             HexDump ("APIMap", &APIMap, sizeof(APIMap));
  282.          }
  283.          else if (usFunc == 0x82)  // CallbackReg
  284.          {
  285.             printf ("CallbackReg is done automatically at program start\n");
  286.          }
  287.          else if (usFunc == 0x83)  // MsgBuf
  288.          {
  289.             // Skip the function number and following spaces
  290.             // Index to left volume parm (clear or not clear)
  291.             while (Line[i] != '\0' && Line[i] > ' ')
  292.                i++;
  293.             while (Line[i] != '\0' && Line[i] <= ' ')
  294.                i++;
  295.  
  296.             if (Line[i] == '\0')
  297.             {
  298.                fClear = FALSE;
  299.             }
  300.             else
  301.             {
  302.                usLeft = 0;
  303.                iRC = AsciiToUshort (&Line[i], &usLeft, BASE10);
  304.                if (iRC != 0 || usLeft > 1)
  305.                {
  306.                   printf ("Clear must be range 0..1\n");
  307.                   break;
  308.                }
  309.                fClear = usLeft;
  310.             }
  311.  
  312.             // How much memory must we allocate?
  313.             memset (&MsgBuf, '\0', sizeof(MsgBuf));
  314.             ulRC = mixerapiIOCTL90 (0x83, &MsgBuf, sizeof(MsgBuf));
  315.             if (ulRC != 0)
  316.             {
  317.                printf ("IOCTL Failed, get buf size ulRC:0x%x\n", ulRC);
  318.                break;
  319.             }
  320.  
  321.             pMessages = malloc (MsgBuf.ulSize);
  322.             if (pMessages == NULL)
  323.             {
  324.                printf ("malloc failed (%u bytes)\n", MsgBuf.ulSize);
  325.                break;
  326.             }
  327.  
  328.             // Fetch the message text (optionally clear the buffer)
  329.             MsgBuf.pBuffer = (ULONG) pMessages;
  330.             MsgBuf.fClear = fClear;
  331.             ulRC = mixerapiIOCTL90 (0x83, &MsgBuf, sizeof(MsgBuf));
  332.             if (ulRC != 0)
  333.             {
  334.                printf ("IOCTL Failed, get buffer ulRC:0x%x\n", ulRC);
  335.                free (pMessages);
  336.                break;
  337.             }
  338.  
  339.             // Display the results
  340.             printf ("MsgBuf structure:\n");
  341.             printf ("   ulSize   = %u\n", MsgBuf.ulSize);
  342.             printf ("   fClear   = %u\n", MsgBuf.fClear);
  343.             printf ("   fError   = %u\n", MsgBuf.fError);
  344.             printf ("   fNewInfo = %u\n", MsgBuf.fNewInfo);
  345.             printf ("   ulLost   = %u\n", MsgBuf.ulCharsLost);
  346.             printf ("\n");
  347.             printf ("%s", pMessages);
  348.  
  349.             free (pMessages);
  350.          }
  351.          else
  352.          {
  353.             printf ("Unknown IOCTL Function ('?' for list)\n");
  354.          }
  355.       }
  356.       break;
  357.  
  358.  
  359.    default:
  360.       fBadCommand = TRUE;
  361.       break;
  362.    }
  363.  
  364.    if (fBadCommand)
  365.    {
  366.       printf ("Unknown command\n");
  367.       iRC = 3;
  368.    }
  369. }
  370.  
  371.  
  372. void CommandsMain (void)
  373. {
  374.    CommandsHelp();
  375.  
  376.    while (! fCommandsDone)    // Variable updated by 'Q' command
  377.    {
  378.       printf (":");
  379.       fCommandsDone = (fgets(Line, sizeof(Line), stdin) == NULL);
  380.       if (! fCommandsDone)
  381.          CommandsProcessLine ();
  382.    }
  383. }
  384.