home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 4 Drivers / 04-Drivers.zip / SBOS2DEV.ZIP / mixertool / mixertool.c < prev    next >
C/C++ Source or Header  |  1992-10-24  |  23KB  |  870 lines

  1. #define INCL_GPILOGCOLORTABLE
  2. #define INCL_WINFRAMEMGR
  3. #define INCL_WINSYS
  4. #define INCL_WINSCROLLBARS
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <os2.h>
  9. #include "sblast_user.h"
  10. #include "mixertool.h"
  11.  
  12.  
  13. HFILE mixer_handle;
  14. struct sb_mixer_levels sblevels;
  15. struct sb_mixer_params sbparams;
  16.  
  17. #define ID_BUT1 100
  18.  
  19. HWND hwndFrame;
  20. HWND hwndScroll[9];
  21. HWND hwndButton[NUM_BUTTONS];
  22. HWND hwndPbutton;
  23.  
  24.  
  25. QMSG      qmsg;
  26. HMQ       hmq;
  27. HWND      hwnd;
  28. HPS       hps;
  29.  
  30.  
  31.  
  32. HAB  hab;
  33. FLAG srcsel[3];
  34.  
  35.  
  36. /* these procedures deal with calculating the position of various scrollbars
  37.  * and their associated text 
  38.  */
  39.  
  40. /* stuff controlling layout of scrollbars */
  41. #define L_R_SEP 1
  42. #define SB_SEP  2
  43. #define SB_WID  2
  44. #define SB_LEN  5
  45. #define XBORDER  3
  46. #define YBORDER_BOT  2
  47. #define YBORDER_TOP  4
  48.  
  49. /* store the average width, height of characters */
  50. USHORT fwidth, fheight;
  51. USHORT borderx, bordery;
  52.  
  53. /* This function returns the position of the lower left corner of
  54.  * the slider specified by slideID.
  55.  *
  56.  * Assumes global variables fwidth, fheight have been set
  57.  */
  58. void GetSliderPos(USHORT slideID, POINTL * pnt)
  59. {
  60.   /* first see if its part of a stereo slider pair */
  61.   if (slideID < SCR_CD)
  62.     {
  63.       /* compute position of left channel slider first */
  64.       pnt->x=(XBORDER+(slideID/2)*(2*SB_WID+SB_SEP+L_R_SEP))*fwidth;
  65.       /* if its the right channel add in left-right separation */
  66.       if (slideID & 1)
  67.     pnt->x += (SB_WID+L_R_SEP)*fwidth;
  68.       pnt->y=fheight*YBORDER_BOT;
  69.     }
  70.   else
  71.     {
  72.       /* compute position for CD slider */
  73.       pnt->x=(XBORDER+(slideID/2)*(2*SB_WID+SB_SEP+L_R_SEP))*fwidth;
  74.       /* if its the mic slider add slider separation */
  75.       if (slideID&1)
  76.     pnt->x += (SB_WID+SB_SEP)*fwidth;
  77.       pnt->y=fheight*YBORDER_BOT;
  78.     }
  79. }
  80.  
  81.  
  82.  
  83. /* these procedures handle the mixer levels */
  84. void StoreMixerLevel( USHORT slideID, USHORT mixlevel, 
  85.              struct sb_mixer_levels * sblev)
  86. {
  87.   switch (slideID)
  88.     {
  89.     case 0:
  90.       sblev->master.l = (BYTE) (15-mixlevel);
  91.       break;
  92.     case 1:
  93.       sblev->master.r = (BYTE) (15-mixlevel);
  94.       break;
  95.     case 2:
  96.       sblev->voc.l = (BYTE) (15-mixlevel);
  97.       break;
  98.     case 3:
  99.       sblev->voc.r = (BYTE) (15-mixlevel);
  100.       break;
  101.     case 4:
  102.       sblev->fm.l = (BYTE) (15-mixlevel);
  103.       break;
  104.     case 5:
  105.       sblev->fm.r = (BYTE) (15-mixlevel);
  106.       break;
  107.     case 6:
  108.       sblev->line.l = (BYTE) (15-mixlevel);
  109.       break;
  110.     case 7:
  111.       sblev->line.r = (BYTE) (15-mixlevel);
  112.       break;
  113.     case 8:
  114.       sblev->cd.r = sblev->cd.l = (BYTE) (15-mixlevel);
  115.       break;
  116.     case 9:
  117.       sblev->mic = (BYTE) (7-mixlevel);
  118.       break;
  119.     default:
  120.       break;
  121.     }
  122. }
  123.  
  124.  
  125. USHORT GetMixerLevel( USHORT slideID, struct sb_mixer_levels sblev)
  126. {
  127.   switch (slideID)
  128.     {
  129.     case 0:
  130.       return 15-sblev.master.l;
  131.       break;
  132.     case 1:
  133.       return 15-sblev.master.r;
  134.       break;
  135.     case 2:
  136.       return 15-sblev.voc.l;
  137.       break;
  138.     case 3:
  139.       return 15-sblev.voc.r;
  140.       break;
  141.     case 4:
  142.       return 15-sblev.fm.l;
  143.       break;
  144.     case 5:
  145.       return 15-sblev.fm.r;
  146.       break;
  147.     case 6:
  148.       return 15-sblev.line.l;
  149.       break;
  150.     case 7:
  151.       return 15-sblev.line.r;
  152.       break;
  153.     case 8:
  154.       return 15-sblev.cd.r;
  155.       break;
  156.     case 9:
  157.       return 7-sblev.mic;
  158.       break;
  159.     default:
  160.       return -1;
  161.       break;
  162.     }
  163. }
  164.  
  165.  
  166.  
  167.  
  168. /* subroutine to update display of mixer params */
  169. /* affects/uses global vars sbparams, srcsel    */
  170.  
  171. void UpdateMixerParams(void)
  172. {
  173.   USHORT i;
  174.   ULONG  parlen, datlen;
  175.  
  176.   /* read in current settings */
  177.   parlen=0;
  178.   datlen=sizeof(struct sb_mixer_params);
  179.   DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_READ_PARAMS,
  180.           NULL, 0, &parlen,
  181.           &sbparams, datlen, &datlen);
  182.  
  183.   for (i=0; i<3; i++) 
  184.     srcsel[i]=FALSE;
  185.  
  186.   switch(sbparams.record_source)
  187.     {
  188.     case SRC_MIC:
  189.       srcsel[2] = TRUE;
  190.       break;
  191.     case SRC_LINE:
  192.       srcsel[1] = TRUE;
  193.       break;
  194.     case SRC_CD:
  195.       srcsel[0] = TRUE;
  196.       break;
  197.     }
  198.  
  199.   for (i=0; i<3; i++) 
  200.     if (srcsel[i])
  201.       WinSendMsg(hwndButton[i], BM_SETCHECK, MPFROMSHORT(1), NULL);
  202.     else
  203.       WinSendMsg(hwndButton[i], BM_SETCHECK, MPFROMSHORT(0), NULL);
  204.  
  205.   if (sbparams.hifreq_filter)
  206.     {
  207.       WinSendMsg(hwndButton[3], BM_SETCHECK, MPFROMSHORT(1), NULL);
  208.       WinSendMsg(hwndButton[4], BM_SETCHECK, MPFROMSHORT(0), NULL);
  209.     }
  210.   else
  211.     {
  212.       WinSendMsg(hwndButton[3], BM_SETCHECK, MPFROMSHORT(0), NULL);
  213.       WinSendMsg(hwndButton[4], BM_SETCHECK, MPFROMSHORT(1), NULL);
  214.     }
  215.  
  216.   if (sbparams.filter_output)
  217.       WinSendMsg(hwndButton[5], BM_SETCHECK, MPFROMSHORT(1), NULL);
  218.   else
  219.       WinSendMsg(hwndButton[5], BM_SETCHECK, MPFROMSHORT(0), NULL);
  220.  
  221.   if (sbparams.filter_input)
  222.       WinSendMsg(hwndButton[6], BM_SETCHECK, MPFROMSHORT(1), NULL);
  223.   else
  224.       WinSendMsg(hwndButton[6], BM_SETCHECK, MPFROMSHORT(0), NULL);
  225.  
  226. }
  227.  
  228.   
  229.  
  230. /* labels for different sliders */
  231. char *slidenames[]={{"MAS"},{"VOC"},{"FM"},{"LINE"},{"CD"},{"MIC"}};
  232.  
  233.  
  234.  
  235. static MRESULT MainWndProc(hwnd, msg, mp1, mp2)
  236.      HWND          hwnd;
  237.      ULONG        msg;
  238.      MPARAM        mp1;
  239.      MPARAM        mp2;
  240. {
  241.   RECTL      rectl, txtrectl;
  242.   HPS        hps;
  243.   USHORT     i, slidepos;
  244.   ULONG      parlen, datlen;
  245.   SWP        winpos;
  246.   POINTL     bleft, tmppnt;
  247.   char       valstr[3];
  248.  
  249.  
  250.   switch(msg)
  251.     {
  252.     case WM_ERASEBACKGROUND:
  253.       return( (MRESULT) TRUE);
  254.       break;
  255.  
  256.  
  257.     case WM_PAINT:
  258.       hps=WinBeginPaint(hwnd, NULL, (PRECTL) &rectl);
  259.  
  260.       bleft.x=fwidth*XBORDER-(SB_WID*fwidth)/2;
  261.       bleft.y=0;
  262.       /* loop through scrollbars, inquire position and output values */
  263.       for (i=0; i<=SCR_MIC; i++)
  264.     {
  265.       slidepos=(USHORT)WinSendMsg(hwndScroll[i],SBM_QUERYPOS,NULL,NULL);
  266.       if (i!=SCR_MIC)
  267.         slidepos=15-slidepos;
  268.       else
  269.         slidepos=7-slidepos;
  270.       
  271.       _ultoa((ULONG)slidepos, valstr, 10);
  272.  
  273.       WinQueryWindowPos(hwndScroll[i], &winpos);
  274.       winpos.x -= borderx;
  275.       winpos.y -= bordery;
  276.       txtrectl.yBottom=winpos.y-(LONG)(1.75*fheight);
  277.       txtrectl.yTop=txtrectl.yBottom+(LONG)(1.25*fheight);
  278.       txtrectl.xLeft=winpos.x-(LONG)(0.25*winpos.cx);
  279.       txtrectl.xRight=txtrectl.xLeft+(LONG)(winpos.cx*1.4);
  280.  
  281.       /* put a box around it */
  282.       WinFillRect(hps, &txtrectl, SYSCLR_BACKGROUND);
  283.       tmppnt.x=txtrectl.xLeft;
  284.       tmppnt.y=txtrectl.yBottom;
  285.       GpiMove(hps,&tmppnt);
  286.       tmppnt.x=txtrectl.xRight;
  287.       tmppnt.y=txtrectl.yTop;
  288.       GpiBox(hps,DRO_OUTLINE,&tmppnt,0,0);
  289.  
  290.  
  291.       /* draw some text */
  292.       WinDrawText(hps, -1, (PCH) valstr, (PRECTL) &txtrectl,
  293.           (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  294.                 WinQuerySysColor (HWND_DESKTOP,
  295.                 SYSCLR_WINDOWTEXT,  0L)),
  296.           (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  297.                 WinQuerySysColor (HWND_DESKTOP,
  298.                 SYSCLR_WINDOW, 0L)),
  299.           DT_CENTER | DT_VCENTER );
  300.  
  301.       /* now put a label over slider indicating if Left or Right */
  302.       if (i<SCR_CD)
  303.         {
  304.           txtrectl.yBottom = winpos.y+winpos.cy;
  305.           txtrectl.yTop    = txtrectl.yBottom+(LONG)(1.25*fheight);
  306.           if (i & 1)
  307.         valstr[0] = 'R';
  308.           else
  309.         valstr[0] = 'L';
  310.           valstr[1] = '\0';
  311.  
  312.           WinDrawText(hps, -1, (PCH) valstr, (PRECTL) &txtrectl,
  313.               (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  314.                        WinQuerySysColor (HWND_DESKTOP,
  315.                          SYSCLR_WINDOWTEXT,  0L)),
  316.               (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  317.                        WinQuerySysColor (HWND_DESKTOP,
  318.                          SYSCLR_WINDOW, 0L)),
  319.               DT_CENTER | DT_VCENTER );
  320.  
  321.           /* put labels on too */
  322.           if (i & 1)
  323.         {
  324.           txtrectl.xLeft -= (L_R_SEP+SB_WID)*fwidth;
  325.           txtrectl.yTop  += fheight;
  326.           txtrectl.yBottom += fheight;
  327.           WinDrawText(hps, -1, slidenames[i/2], (PRECTL) &txtrectl,
  328.                 (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  329.                        WinQuerySysColor (HWND_DESKTOP,
  330.                          SYSCLR_WINDOWTEXT,  0L)),
  331.                 (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  332.                        WinQuerySysColor (HWND_DESKTOP,
  333.                          SYSCLR_WINDOW, 0L)),
  334.                 DT_CENTER | DT_VCENTER );
  335.         }
  336.  
  337.         }
  338.       else
  339.         {
  340.           /* put labels on CD, MIC controls */
  341.           txtrectl.yBottom = winpos.y+winpos.cy+fheight;
  342.           txtrectl.yTop    = txtrectl.yBottom+(LONG)(1.25*fheight);
  343.           txtrectl.xLeft  -= (LONG)(0.5*fwidth);
  344.           txtrectl.xRight += (LONG)(0.5*fwidth);
  345.           if (i==SCR_CD)
  346.         WinDrawText(hps, -1, "CD", (PRECTL) &txtrectl,
  347.                 (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  348.                        WinQuerySysColor (HWND_DESKTOP,
  349.                          SYSCLR_WINDOWTEXT,  0L)),
  350.                 (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  351.                        WinQuerySysColor (HWND_DESKTOP,
  352.                          SYSCLR_WINDOW, 0L)),
  353.                 DT_CENTER | DT_VCENTER );
  354.           else
  355.         WinDrawText(hps, -1, "MIC", (PRECTL) &txtrectl,
  356.                 (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  357.                        WinQuerySysColor (HWND_DESKTOP,
  358.                          SYSCLR_WINDOWTEXT,  0L)),
  359.                 (LONG) GpiQueryColorIndex (hps, (ULONG) NULL,
  360.                        WinQuerySysColor (HWND_DESKTOP,
  361.                          SYSCLR_WINDOW, 0L)),
  362.                 DT_CENTER | DT_VCENTER );
  363.  
  364.         }        
  365.  
  366.       
  367.     }      
  368.  
  369.  
  370.       (void)WinEndPaint(hps);
  371.       break;
  372.  
  373.  
  374.     /* this will handle case if they press the 'refresh' button */
  375.     case WM_COMMAND:
  376.       /* read values from SB Pro mixer, update display */
  377.       parlen=0;
  378.       datlen=sizeof(struct sb_mixer_levels);
  379.       DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_READ_LEVELS,
  380.           NULL, 0, &parlen,
  381.           &sblevels, datlen, &datlen);
  382.  
  383.  
  384.       /* update all sliders */
  385.       for (i=0;i<=SCR_MIC;i++)
  386.     WinSendMsg(hwndScroll[i], SBM_SETPOS, 
  387.            MPFROM2SHORT(GetMixerLevel(i,sblevels),0),NULL);
  388.  
  389.       /* refresh all labels for sliders */
  390.       for (i=0;i<=SCR_MIC;i++)
  391.     {
  392.       WinQueryWindowPos(hwndScroll[i], &winpos);
  393.       winpos.x -= borderx;
  394.       winpos.y -= bordery;
  395.       rectl.yBottom=winpos.y-(LONG)(1.75*fheight);
  396.       rectl.yTop=rectl.yBottom+(LONG)(1.25*fheight);
  397.       rectl.xLeft=winpos.x-(LONG)(0.25*winpos.cx);
  398.       rectl.xRight=rectl.xLeft+(LONG)(winpos.cx*1.4);
  399.       WinInvalidateRect(hwnd, &rectl, FALSE);
  400.     }
  401.  
  402.  
  403.       /* now handle parameters */
  404.       UpdateMixerParams();
  405.       break;
  406.  
  407.     /* this will handle button messages */
  408.     case WM_CONTROL:
  409.       /* figure out which button */
  410.       i=SHORT1FROMMP(mp1);
  411.       switch(i)
  412.     {
  413.       USHORT butnum;
  414.  
  415.     case ID_BUTSRCMIC:
  416.     case ID_BUTSRCCD:
  417.     case ID_BUTSRCLINE:
  418.       /* see if they clicked on the button */
  419.       if (SHORT2FROMMP(mp1)==BN_CLICKED ||
  420.           SHORT2FROMMP(mp1)==BN_DBLCLICKED)
  421.         {
  422.           /* inquire current state, then invert */
  423.           butnum = i-100;
  424.           if (srcsel[butnum]==FALSE)
  425.         {
  426.           for (i=0; i<3; i++)
  427.             if (i!=butnum)
  428.               {
  429.             if (srcsel[i])
  430.               WinSendMsg(hwndButton[i], 
  431.                      BM_SETCHECK,MPFROMSHORT(0),NULL);
  432.             srcsel[i]=FALSE;
  433.               }
  434.             else
  435.               {
  436.             WinSendMsg(hwndButton[i], 
  437.                    BM_SETCHECK,MPFROMSHORT(1),NULL);
  438.             srcsel[i]=TRUE;
  439.               }
  440.           
  441.           if (srcsel[0])
  442.             sbparams.record_source=SRC_CD;
  443.           else if (srcsel[1])
  444.             sbparams.record_source=SRC_LINE;
  445.           else 
  446.             sbparams.record_source=SRC_MIC;
  447.  
  448.           parlen=0;
  449.           datlen=sizeof(struct sb_mixer_params);
  450.           DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  451.                   NULL, 0, &parlen,
  452.                   &sbparams, datlen, &datlen);
  453.         }
  454.         }
  455.     
  456.       break;
  457.       
  458.     case ID_BUTFILTHI:
  459.     case ID_BUTFILTLO:
  460.       /* see if they clicked on the button */
  461.       if (SHORT2FROMMP(mp1)==BN_CLICKED ||
  462.           SHORT2FROMMP(mp1)==BN_DBLCLICKED)
  463.         {
  464.           if (i==ID_BUTFILTHI)
  465.         {
  466.           if (sbparams.hifreq_filter==FALSE)
  467.             {
  468.               sbparams.hifreq_filter=TRUE;
  469.               WinSendMsg(hwndButton[3], 
  470.                  BM_SETCHECK, MPFROMSHORT(1), NULL);
  471.               WinSendMsg(hwndButton[4], 
  472.                  BM_SETCHECK, MPFROMSHORT(0), NULL);
  473.             }
  474.         }
  475.           else
  476.         {
  477.           if (sbparams.hifreq_filter==TRUE)
  478.             {
  479.               sbparams.hifreq_filter=FALSE;
  480.               WinSendMsg(hwndButton[3], 
  481.                  BM_SETCHECK, MPFROMSHORT(0), NULL);
  482.               WinSendMsg(hwndButton[4], 
  483.                  BM_SETCHECK, MPFROMSHORT(1), NULL);
  484.             }
  485.         }
  486.           parlen=0;
  487.           datlen=sizeof(struct sb_mixer_params);
  488.           DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  489.               NULL, 0, &parlen,
  490.               &sbparams, datlen, &datlen);
  491.         }
  492.       break;
  493.       
  494.     case ID_BUTFILTOUT:
  495.       /* see if they clicked on the button */
  496.       if (SHORT2FROMMP(mp1)==BN_CLICKED ||
  497.           SHORT2FROMMP(mp1)==BN_DBLCLICKED)
  498.         {
  499.           if (WinSendMsg(hwndButton[5], BM_QUERYCHECK, NULL, NULL))
  500.         {
  501.           sbparams.filter_output = FALSE;
  502.           WinSendMsg(hwndButton[5], BM_SETCHECK,MPFROMSHORT(0),NULL);
  503.         }
  504.           else
  505.         {
  506.           sbparams.filter_output = TRUE;
  507.           WinSendMsg(hwndButton[5], BM_SETCHECK,MPFROMSHORT(1),NULL);
  508.         }
  509.           parlen=0;
  510.           datlen=sizeof(struct sb_mixer_params);
  511.           DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  512.               NULL, 0, &parlen,
  513.               &sbparams, datlen, &datlen);
  514.         }
  515.       break;
  516.       
  517.     case ID_BUTFILTIN:
  518.       /* see if they clicked on the button */
  519.       if (SHORT2FROMMP(mp1)==BN_CLICKED ||
  520.           SHORT2FROMMP(mp1)==BN_DBLCLICKED)
  521.         {
  522.           if (WinSendMsg(hwndButton[6], BM_QUERYCHECK, NULL, NULL))
  523.         {
  524.           sbparams.filter_input=FALSE;
  525.           WinSendMsg(hwndButton[6], BM_SETCHECK,MPFROMSHORT(0),NULL);
  526.         }
  527.           else
  528.         {
  529.           sbparams.filter_input=TRUE;
  530.           WinSendMsg(hwndButton[6], BM_SETCHECK,MPFROMSHORT(1),NULL);
  531.         }
  532.           parlen=0;
  533.           datlen=sizeof(struct sb_mixer_params);
  534.           DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_SET_PARAMS,
  535.               NULL, 0, &parlen,
  536.               &sbparams, datlen, &datlen);
  537.         }
  538.       break;
  539.       
  540.     default:
  541.       break;
  542.     }
  543.  
  544.  
  545.     /* This will handle a vertical scroll bar */
  546.     case WM_VSCROLL:
  547.  
  548.       /* see who was responsible */
  549.       i=SHORT1FROMMP(mp1);
  550.       if (i<10)
  551.     {
  552.       USHORT smax, smin;
  553.       MRESULT mr;
  554.       USHORT update=1;
  555.  
  556.       /* this is my scroll bar, see what they did */
  557.       switch(SHORT2FROMMP(mp2))
  558.         {
  559.         case SB_LINEUP:
  560.         case SB_LINEDOWN:
  561.  
  562.           slidepos=(USHORT)WinSendMsg(hwndScroll[i], SBM_QUERYPOS,
  563.                           NULL, NULL);
  564.           mr=WinSendMsg(hwndScroll[i], SBM_QUERYRANGE, NULL, NULL);
  565.           if (SHORT2FROMMP(mp2)==SB_LINEUP)
  566.         {
  567.           smin=SHORT1FROMMR(mr);
  568.           slidepos-=2;
  569.           if (slidepos < smin) slidepos=smin;
  570.         }
  571.           else
  572.         {
  573.           smax=SHORT2FROMMR(mr);
  574.           slidepos+=2;
  575.           if (slidepos > smax) slidepos=smax;
  576.         }
  577.           break;
  578.  
  579.         case SB_PAGEUP:
  580.         case SB_PAGEDOWN:
  581.  
  582.           slidepos=(USHORT)WinSendMsg(hwndScroll[i], SBM_QUERYPOS,
  583.                           NULL, NULL);
  584.  
  585.           mr=WinSendMsg(hwndScroll[i], SBM_QUERYRANGE, NULL, NULL);
  586.           if (SHORT2FROMMP(mp2)==SB_PAGEUP)
  587.         {
  588.           smin=SHORT1FROMMR(mr);
  589.           slidepos -=4;
  590.           if (slidepos < smin) slidepos=smin;
  591.         }
  592.           else
  593.         {
  594.           smax=SHORT2FROMMR(mr);
  595.           slidepos +=4;
  596.           if (slidepos >smax) slidepos=smax;
  597.         }
  598.           break;
  599.  
  600.         case SB_SLIDERPOSITION: 
  601.         case SB_SLIDERTRACK:
  602.  
  603.           slidepos=SHORT1FROMMP(mp2);
  604.           break;
  605.  
  606.         default:
  607.           update=0;
  608.           break;
  609.         }
  610.  
  611.       /* see if we should do anything */
  612.       if (update != 0)
  613.         {
  614.           /* send new volume to SBMIX */
  615.           parlen=0;
  616.           datlen=sizeof(struct sb_mixer_levels);
  617.           StoreMixerLevel(i, slidepos, &sblevels);
  618.           DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_SET_LEVELS,
  619.               NULL, 0, &parlen,
  620.               &sblevels, datlen, &datlen);
  621.  
  622.           /* read what position was really set to */
  623.           datlen=sizeof(struct sb_mixer_levels);
  624.           parlen=0;
  625.           DosDevIOCtl(mixer_handle, DSP_CAT,MIXER_IOCTL_READ_LEVELS,
  626.                  NULL, 0, &parlen,
  627.                  &sblevels, datlen, &datlen);
  628.           slidepos=GetMixerLevel(i, sblevels);
  629.  
  630.           /* now update scrollbar, text */
  631.           WinSendMsg(hwndScroll[i], SBM_SETPOS, MPFROM2SHORT(slidepos,0),
  632.              NULL);
  633.           /* now redraw the number at bottom of slidebar */
  634.           WinQueryWindowPos(hwndScroll[i], &winpos);
  635.           winpos.x -= borderx;
  636.           winpos.y -= bordery;
  637.           rectl.yBottom=winpos.y-(LONG)(1.75*fheight);
  638.           rectl.yTop=rectl.yBottom+(LONG)(1.25*fheight);
  639.           rectl.xLeft=winpos.x-(LONG)(0.25*winpos.cx);
  640.           rectl.xRight=rectl.xLeft+(LONG)(winpos.cx*1.4);
  641.           WinInvalidateRect(hwnd, &rectl, FALSE);
  642.           break;
  643.         }
  644.     }
  645.     default:
  646.       return(WinDefWindowProc(hwnd, msg,mp1,mp2));
  647.       break;
  648.     }
  649.  
  650.   return(0L);
  651. }
  652.  
  653.  
  654. void Error_and_exit( char * tempstr, int error )
  655. {
  656.   ULONG mbtype;
  657.  
  658.   if (error)
  659.     mbtype = MB_ERROR;
  660.   else
  661.     mbtype = MB_INFORMATION;
  662.  
  663.   /* open up informative dialog box */
  664.   WinMessageBox(HWND_DESKTOP, hwndFrame, tempstr, NULL,
  665.         ID_HELPWIN, MB_OK | mbtype );
  666.  
  667.   if (mixer_handle)
  668.     DosClose(mixer_handle);
  669.  
  670.   WinDestroyWindow(hwndFrame);
  671.   WinDestroyMsgQueue(hmq);
  672.   WinTerminate(hab);
  673.   exit(0);
  674. }
  675.  
  676.  
  677.  
  678.  
  679. int main (argc, argv )
  680. int argc;
  681. char *argv[];
  682. {
  683.   FONTMETRICS fm;
  684.  
  685.   USHORT i;
  686.   ULONG  status, action, datlen, parlen;
  687.   POINTL bleft;
  688.   RECTL  rect;
  689.  
  690.   ULONG     flCreate = FCF_TITLEBAR | FCF_BORDER | FCF_SYSMENU |
  691.                        FCF_MINBUTTON | FCF_SHELLPOSITION | FCF_TASKLIST |
  692.                FCF_ICON;
  693.  
  694.  
  695.   char      szTitle[]={"MixerTool"};
  696.  
  697.  
  698.  
  699.   /* before we do anything make sure we can open the mixer */
  700.   status = DosOpen( "SBMIX$", &mixer_handle, &action, 0,
  701.            FILE_NORMAL, FILE_OPEN,
  702.    OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_WRITE_THROUGH,
  703.               NULL );
  704.  
  705.   if (status != 0)
  706.     Error_and_exit("Error opening audio device SBMIX$.\n This Program must be run on a SBPRO.", TRUE);
  707.  
  708.   /* read current levels */
  709.   datlen=sizeof(struct sb_mixer_levels);
  710.   parlen=0;
  711.   status=DosDevIOCtl(mixer_handle, DSP_CAT, MIXER_IOCTL_READ_LEVELS,
  712.                     NULL, 0, &parlen,
  713.                     &sblevels, datlen, &datlen);
  714.   if (status != 0)
  715.     Error_and_exit("Error reading current mixer levels.", TRUE);
  716.  
  717.   /* everything ok, so continue */
  718.   hab = WinInitialize(QV_OS2);
  719.   hmq = WinCreateMsgQueue( hab, 0);
  720.  
  721.   /* register this window */
  722.   if (!WinRegisterClass(hab, szTitle, MainWndProc, 
  723.             CS_SIZEREDRAW, 0L))
  724.     return(0);
  725.  
  726.   /* create main window */
  727.   hwndFrame = WinCreateStdWindow((HAB)hab,
  728.                  0,
  729.                  (PVOID) &flCreate,
  730.                  (PSZ) szTitle,
  731.                  (PSZ) NULL,
  732.                  0L,
  733.                  (HMODULE) NULL,
  734.                  (USHORT) ID_MAIN,
  735.                  (PHWND) &hwnd);
  736.  
  737.   /* set title bar */
  738.   WinSetWindowText(WinWindowFromID (hwndFrame, FID_TITLEBAR), (PSZ) szTitle);
  739.  
  740.  
  741.   /* now figure out the size of current font */
  742.   hps=WinGetPS(hwnd);
  743.   GpiQueryFontMetrics(hps,(LONG)sizeof(FONTMETRICS), (PFONTMETRICS)&fm);
  744.  
  745.   /* record some useful info */
  746.   fwidth = (USHORT)(1.2*fm.lAveCharWidth);
  747.   fheight= (USHORT)(fm.lExternalLeading+fm.lMaxBaselineExt);
  748.  
  749.   WinReleasePS(hps);
  750.  
  751.  
  752.   /* now resize window */
  753.   WinSetWindowPos(hwndFrame, NULL, 0, 0,
  754.           (2*XBORDER+10*SB_WID+5*SB_SEP+4*L_R_SEP)*fwidth,
  755.           (SB_LEN+YBORDER_TOP+YBORDER_BOT+3)*fheight, 
  756.           SWP_SIZE | SWP_SHOW);
  757.  
  758.  
  759.   /* inquire into size of main window border */
  760.   borderx=(USHORT) WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
  761.   bordery=(USHORT) WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
  762.  
  763.   /* now make the scrollbars */
  764.   /* first lets do the stereo scrollbars */
  765.   for (i=0; i<=SCR_MIC; i++)
  766.     {
  767.       GetSliderPos(i, &bleft);
  768.       hwndScroll[i] = WinCreateWindow(hwndFrame, WC_SCROLLBAR, NULL,
  769.                SBS_VERT | WS_VISIBLE,
  770.                bleft.x,bleft.y,
  771.                SB_WID*fwidth,SB_LEN*fheight,
  772.                hwndFrame, HWND_TOP, i, NULL, NULL);
  773.  
  774.       if (i!=SCR_MIC)
  775.     {
  776.       /* Set range from 0 to 15 */
  777.       WinSendMsg(hwndScroll[i],SBM_SETSCROLLBAR, 
  778.              MPFROM2SHORT(GetMixerLevel(i, sblevels),0),
  779.              MPFROM2SHORT(0,14));
  780.     }
  781.       else
  782.     {
  783.       WinSendMsg(hwndScroll[i],SBM_SETSCROLLBAR, 
  784.              MPFROM2SHORT(GetMixerLevel(i, sblevels),0),
  785.              MPFROM2SHORT(0,6));
  786.     }
  787.     }
  788.   /* done with drawing scrollbars */
  789.   
  790.   /* Create buttons */
  791.   hwndButton[0] = WinCreateWindow(hwndFrame, WC_BUTTON, "SRC_CD",
  792.                WS_VISIBLE | BS_RADIOBUTTON,
  793.                (LONG)(2*fwidth),
  794.                (SB_LEN+YBORDER_BOT+2)*fheight+fheight/2,
  795.                11*fwidth,fheight,
  796.                hwndFrame, HWND_TOP, ID_BUTSRCCD, NULL, NULL);
  797.  
  798.   hwndButton[1] = WinCreateWindow(hwndFrame, WC_BUTTON, "SRC_LINE",
  799.                WS_VISIBLE | BS_RADIOBUTTON,
  800.                (LONG)(2*fwidth),
  801.                (SB_LEN+YBORDER_BOT+3)*fheight+fheight/2,
  802.                13*fwidth,fheight,
  803.                hwndFrame, HWND_TOP, ID_BUTSRCLINE, NULL, NULL);
  804.  
  805.   hwndButton[2] = WinCreateWindow(hwndFrame, WC_BUTTON, "SRC_MIC",
  806.                WS_VISIBLE | BS_RADIOBUTTON,
  807.                (LONG)(2*fwidth),
  808.                (SB_LEN+YBORDER_BOT+4)*fheight+fheight/2,
  809.                12*fwidth,fheight,
  810.                hwndFrame, HWND_TOP, ID_BUTSRCMIC, NULL, NULL);
  811.  
  812.   hwndButton[3] = WinCreateWindow(hwndFrame, WC_BUTTON, "FILT_HI",
  813.                WS_VISIBLE | BS_RADIOBUTTON,
  814.                (LONG)(15.5*fwidth),
  815.                (SB_LEN+YBORDER_BOT+4)*fheight+fheight/2,
  816.                11*fwidth,fheight,
  817.                hwndFrame, HWND_TOP, ID_BUTFILTHI, NULL, NULL);
  818.  
  819.   hwndButton[4] = WinCreateWindow(hwndFrame, WC_BUTTON, "FILT_LO",
  820.                WS_VISIBLE | BS_RADIOBUTTON,
  821.                (LONG)(15.5*fwidth),
  822.                        (SB_LEN+YBORDER_BOT+3)*fheight+fheight/2,
  823.                11*fwidth,fheight,
  824.                hwndFrame, HWND_TOP, ID_BUTFILTLO, NULL, NULL);
  825.  
  826.   hwndButton[5] = WinCreateWindow(hwndFrame, WC_BUTTON, "FILT_OUT",
  827.                WS_VISIBLE | BS_RADIOBUTTON,
  828.                (LONG)(27*fwidth),
  829.                        (SB_LEN+YBORDER_BOT+4)*fheight+fheight/2,
  830.                12*fwidth,fheight,
  831.                hwndFrame, HWND_TOP, ID_BUTFILTOUT, NULL, NULL);
  832.  
  833.   hwndButton[6] = WinCreateWindow(hwndFrame, WC_BUTTON, "FILT_IN",
  834.                WS_VISIBLE | BS_RADIOBUTTON,
  835.                (LONG)(27*fwidth),
  836.                (SB_LEN+YBORDER_BOT+3)*fheight+fheight/2,
  837.                12*fwidth,fheight,
  838.                hwndFrame, HWND_TOP, ID_BUTFILTIN, NULL, NULL);
  839.  
  840.   hwndPbutton = WinCreateWindow(hwndFrame, WC_BUTTON, "Refresh",
  841.                WS_VISIBLE | BS_PUSHBUTTON,
  842.                (LONG)(21*fwidth),
  843.                (SB_LEN+YBORDER_BOT+2)*fheight+fheight/4,
  844.                12*fwidth,(LONG)(1.25*fheight),
  845.                hwndFrame, HWND_TOP, ID_BUTREFRESH, NULL, NULL);
  846.  
  847.   UpdateMixerParams();
  848.  
  849.   /* show what we've done */
  850.   WinShowWindow(hwndFrame, TRUE);
  851.  
  852.   while(WinGetMsg(hab, (PQMSG)&qmsg,(HWND)NULL,0,0))
  853.     WinDispatchMsg(hab,(PQMSG)&qmsg);
  854.  
  855.  
  856.   /* destroy all sliderbars */
  857.   for (i=0; i<=SCR_MIC;i++)
  858.     WinDestroyWindow(hwndScroll[i]);
  859.  
  860.   for (i=0; i<NUM_BUTTONS; i++)
  861.     WinDestroyWindow(hwndButton[i]);
  862.  
  863.   WinDestroyWindow(hwndPbutton);
  864.  
  865.   WinDestroyWindow(hwndFrame);
  866.   WinDestroyMsgQueue(hmq);
  867.   WinTerminate(hab);
  868. }
  869.  
  870.