home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ioctlapi.zip
/
appsrc.zip
/
commands.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-16
|
12KB
|
384 lines
//-----------------------------------------------------------------------------
// Freeware. This file may be used freely to promote the ioctl90 mixer API.
//-----------------------------------------------------------------------------
// commands.c
//
// User I/O and menu processing
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include <string.h> // memset
#include <ctype.h> // toupper
#include <stdio.h>
#include <os2.h> // typedefs
#include "data.h"
#include "asciinum.h"
#include "util.h"
#include "commands.h"
#include "ioctl90.h"
#include "mixerapi.h"
char Line [256];
BOOL fCommandsDone = FALSE;
void CommandsHelp (void)
{
printf ("\nIOCTL90 Mixer API test program. " __DATE__ ". Joe Nord\n");
printf ("\n");
printf ("IOCTL Category 0x90, functions:\n");
printf ("40 - MonoInSet 60 - MonoInQuery\n");
printf ("41 - PhoneSet 61 - PhoneQuery\n");
printf ("42 - MicSet 62 - MicQuery\n");
printf ("43 - LineSet 63 - LineQuery\n");
printf ("44 - CDSet 64 - CDQuery\n");
printf ("45 - VideoSet 65 - VideoQuery\n");
printf ("46 - AuxSet 66 - AuxQuery\n");
printf ("4B - BassTrebleSet 6B - BassTrebleQuery\n");
printf ("4C - ThreeDSet 6C - ThreeDQuery\n");
printf ("4D - StreamVolSet 6D - StreamVolQuery\n");
printf ("4E - RecordSrcSet 6E - RecordSrcQuery\n");
printf ("4F - RecordGainSet 6F - RecordGainQuery\n");
printf ("80 - ApiLevelQuery\n");
printf ("81 - GetApiMap\n");
printf ("82 - CallbackReg (automatic at program start)\n");
printf ("83 - MsgBuf [0, 1]\n");
printf ("\n");
printf ("Commands:\n");
printf (" \"xx LL RR m\" - Send IOCTL 90, function xx (hex) with\n");
printf (" parms LL and RR (decimal) and m (boolean).\n");
printf (" The volume parms are only required on Set functions.\n");
printf (" Right volume defaults to same as left.\n");
printf (" m (mute) defaults to 0 => Audible\n");
printf (" \"q\" - Quit\n");
printf ("\n");
}
void FilterLine (char *pString)
{
while (*pString)
{
*pString = toupper (*pString);
if (*pString != 0 && *pString < ' ')
*pString = ' ';
pString++;
}
}
void CommandsProcessLine (void)
{
int iRC;
ULONG ulRC;
int i;
BOOL fBadCommand = FALSE;
USHORT usFunc;
USHORT usLeft;
USHORT usRight;
USHORT usMute;
USHORT usBase;
MIXSTRUCT Mix;
ULONG ulAPILevel = 1; // Default level is level 1
BYTE APIMap[256];
MIXMSGBUF MsgBuf;
char *pMessages;
BOOL fClear;
FilterLine (Line); // Convert to upper case
i = 0;
while (Line[i] != '\0' && Line[i] <= ' ') // Skip spaces
i++;
switch ( Line[i] )
{
case 'Q':
fCommandsDone = TRUE;
break;
case 'H':
case '?':
CommandsHelp ();
break;
case '\0': // No command entered (enter pressed)
break;
case '4':
case '6':
case '8':
iRC = AsciiToUshort (&Line[i], &usFunc, BASE16);
if (iRC == 0)
{
if (usFunc == 0x4E) // Record source set
usBase = BASE16;
else
usBase = BASE10;
if (usFunc >= 0x40 && usFunc <= 0x4F)
{
// Is a set function
// Skip the function number and following spaces
// Index to left volume parm
while (Line[i] != '\0' && Line[i] > ' ')
i++;
while (Line[i] != '\0' && Line[i] <= ' ')
i++;
if (Line[i] == '\0')
{
printf ("Left volume is required\n");
break;
}
usLeft = 0;
iRC = AsciiToUshort (&Line[i], &usLeft, usBase);
if (usBase == BASE16)
{
if (iRC != 0)
{
printf ("Left volume must be range 0..0xFFFF hex\n");
break;
}
}
else
{
if (iRC != 0 || usLeft > 100)
{
printf ("Left volume must be range 0..100 decimal\n");
break;
}
}
// Skip the left volume and following spaces
// Index to right volume parm
while (Line[i] != '\0' && Line[i] > ' ')
i++;
while (Line[i] != '\0' && Line[i] <= ' ')
i++;
if (Line[i] == '\0')
{
if (usFunc == 0x4E)
{
usRight = 0; // Unused parm (set to zero)
}
else
{
usRight = usLeft; // Default right to same as left
usMute = 0;
}
}
else // Right volume is specified
{
if (usFunc == 0x4E)
{
printf ("Right volume is ununsed on this function\n");
break;
}
usRight = 0;
iRC = AsciiToUshort (&Line[i], &usRight, BASE10);
if (iRC != 0 || usRight > 100)
{
printf ("Right volume must be range 0..100 decimal\n");
break;
}
// Skip the right volume and following spaces
// Index to mute parm
while (Line[i] != '\0' && Line[i] > ' ')
i++;
while (Line[i] != '\0' && Line[i] <= ' ')
i++;
usMute = 0;
if (Line[i] != '\0') // Mute parm is specified
{
iRC = AsciiToUshort (&Line[i], &usMute, BASE16);
if (iRC != 0 || usMute > 3)
{
printf ("Mute must be 0..3\n");
break;
}
}
}
// Issue the IOCTL
// printf ("DosDevIOCTL 90, %x, %d, %d, %d\n", usFunc, usLeft, usRight, usMute);
memset (&Mix, '\0', sizeof(Mix));
Mix.Mute = usMute;
Mix.VolumeL = usLeft;
Mix.VolumeR = usRight;
mixerapiIOCTL90 (usFunc, &Mix, sizeof(Mix));
}
else if (usFunc >= 0x60 && usFunc <= 0x6F)
{
// Is a query function
// Skip the function number and following spaces
// Index to left volume parm
while (Line[i] != '\0' && Line[i] > ' ')
i++;
while (Line[i] != '\0' && Line[i] <= ' ')
i++;
if (Line[i] != '\0')
{
printf ("No parms on query functions\n");
break;
}
// Issue the IOCTL
usLeft = 0;
usRight = 0;
usMute = 0;
memset (&Mix, '\0', sizeof(Mix));
// printf ("DosDevIOCTL 90, %x, %d, %d, %d\n", usFunc, usLeft, usRight, usMute);
ulRC = mixerapiIOCTL90 (usFunc, &Mix, sizeof(Mix));
if (ulRC != 0)
{
printf ("IOCTL Failed (0x%x)\n", ulRC);
break;
}
usMute = Mix.Mute;
usLeft = Mix.VolumeL;
usRight = Mix.VolumeR;
if (usBase == BASE16)
{
printf (" %x %x %x %x\n", usFunc, usLeft, usRight, usMute);
}
else
{
printf (" %x %u %u %x\n", usFunc, usLeft, usRight, usMute);
}
}
else if (usFunc == 0x80) // ApiLevelQuery
{
ulRC = mixerapiIOCTL90 (0x80, &ulAPILevel, sizeof(ulAPILevel));
if (ulRC != 0)
{
printf ("IOCTL Failed (0x%x)\n", ulRC);
break;
}
printf ("APILevel = %u\n", ulAPILevel);
}
else if (usFunc == 0x81) // GetApiMap
{
memset (&APIMap, '\0', sizeof(APIMap));
ulRC = mixerapiIOCTL90 (0x81, &APIMap, sizeof(APIMap));
if (ulRC != 0)
{
printf ("IOCTL Failed (0x%x)\n", ulRC);
break;
}
HexDump ("APIMap", &APIMap, sizeof(APIMap));
}
else if (usFunc == 0x82) // CallbackReg
{
printf ("CallbackReg is done automatically at program start\n");
}
else if (usFunc == 0x83) // MsgBuf
{
// Skip the function number and following spaces
// Index to left volume parm (clear or not clear)
while (Line[i] != '\0' && Line[i] > ' ')
i++;
while (Line[i] != '\0' && Line[i] <= ' ')
i++;
if (Line[i] == '\0')
{
fClear = FALSE;
}
else
{
usLeft = 0;
iRC = AsciiToUshort (&Line[i], &usLeft, BASE10);
if (iRC != 0 || usLeft > 1)
{
printf ("Clear must be range 0..1\n");
break;
}
fClear = usLeft;
}
// How much memory must we allocate?
memset (&MsgBuf, '\0', sizeof(MsgBuf));
ulRC = mixerapiIOCTL90 (0x83, &MsgBuf, sizeof(MsgBuf));
if (ulRC != 0)
{
printf ("IOCTL Failed, get buf size ulRC:0x%x\n", ulRC);
break;
}
pMessages = malloc (MsgBuf.ulSize);
if (pMessages == NULL)
{
printf ("malloc failed (%u bytes)\n", MsgBuf.ulSize);
break;
}
// Fetch the message text (optionally clear the buffer)
MsgBuf.pBuffer = (ULONG) pMessages;
MsgBuf.fClear = fClear;
ulRC = mixerapiIOCTL90 (0x83, &MsgBuf, sizeof(MsgBuf));
if (ulRC != 0)
{
printf ("IOCTL Failed, get buffer ulRC:0x%x\n", ulRC);
free (pMessages);
break;
}
// Display the results
printf ("MsgBuf structure:\n");
printf (" ulSize = %u\n", MsgBuf.ulSize);
printf (" fClear = %u\n", MsgBuf.fClear);
printf (" fError = %u\n", MsgBuf.fError);
printf (" fNewInfo = %u\n", MsgBuf.fNewInfo);
printf (" ulLost = %u\n", MsgBuf.ulCharsLost);
printf ("\n");
printf ("%s", pMessages);
free (pMessages);
}
else
{
printf ("Unknown IOCTL Function ('?' for list)\n");
}
}
break;
default:
fBadCommand = TRUE;
break;
}
if (fBadCommand)
{
printf ("Unknown command\n");
iRC = 3;
}
}
void CommandsMain (void)
{
CommandsHelp();
while (! fCommandsDone) // Variable updated by 'Q' command
{
printf (":");
fCommandsDone = (fgets(Line, sizeof(Line), stdin) == NULL);
if (! fCommandsDone)
CommandsProcessLine ();
}
}