home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / misc / vfwdk / samples / bravado / vmsg.c < prev    next >
C/C++ Source or Header  |  1993-01-31  |  24KB  |  708 lines

  1. /****************************************************************************
  2.  *
  3.  *   vmsg.c
  4.  * 
  5.  *   Video Message Processing
  6.  *
  7.  *   Microsoft Video for Windows Sample Capture Driver
  8.  *   Chips & Technologies 9001 based frame grabbers.
  9.  *
  10.  *   Copyright (c) 1992-1993 Microsoft Corporation.  All Rights Reserved.
  11.  *
  12.  *    You have a royalty-free right to use, modify, reproduce and 
  13.  *    distribute the Sample Files (and/or any modified version) in 
  14.  *    any way you find useful, provided that you agree that 
  15.  *    Microsoft has no warranty obligations or liability for any 
  16.  *    Sample Application Files which are modified. 
  17.  *
  18.  ***************************************************************************/
  19.  
  20. #include <windows.h>
  21. #include <mmsystem.h>
  22. #include <msvideo.h>
  23. #include <msviddrv.h>
  24. #include "ct.h"
  25. #include "config.h"
  26. #include "debug.h"
  27.  
  28. #define WIDTHBYTES(i)     ((unsigned)((i+31)&(~31))/8)  /* ULONG aligned ! */
  29.  
  30. static BOOL             fDeviceInitialized = FALSE;
  31. extern LPVIDEOHDR    lpVHdrFirst;
  32.  
  33. PCHANNEL NEAR PASCAL VideoOpen( LPVIDEO_OPEN_PARMS lpOpenParms)
  34. {
  35.     PCHANNEL    pChannel;
  36.     DEVICE_INIT di;
  37.     LPDWORD lpdwError = &lpOpenParms->dwError;
  38.     DWORD dwFlags = lpOpenParms-> dwFlags;
  39.  
  40.     //
  41.     //  if this is the very first open then init the hardware.
  42.     //
  43.  
  44.     *lpdwError = DV_ERR_OK;
  45.  
  46.     /* Only initalize on first call... */
  47.     if (!fDeviceInitialized) {
  48.  
  49.         /* Get Port/IRQ/Base, etc. from ini file */
  50.         GetHardwareSettingsFromINI (&di);
  51.  
  52. #if DEBUG
  53.         {
  54.             char buf[80];
  55.             wsprintf (buf, "Trying BasePort=%X,   IRQ=%d,   BaseMemory=%X", 
  56.                     di.wIOBase, di.bInterrupt, di.wSegment);
  57.             D1(buf);
  58.         }
  59. #endif
  60.         // Perform hardware initialization
  61.         if (! HardwareInit (&di)) {
  62.             *lpdwError = DV_ERR_NOTDETECTED;
  63.             return NULL;
  64.         }
  65.  
  66.         ConfigGetSettings();   // Get global hue, sat, channel, zoom
  67.  
  68.         // Create selector(s) to memory
  69.         GetFrameBufferPointer ((BYTE) (di.wSegment));
  70.  
  71.         // Can we access the frame buffer?
  72.     if ((*lpdwError = InitCheckMem()) == DV_ERR_OK) {  
  73.             if (ConfigInit(&di)) {       // Allocate copy buffer, init globals
  74.                 if (TransInit ()) {      // Init XLateTBLs, (ret. 0 on success)
  75.                     *lpdwError = DV_ERR_NOMEM;
  76.                 }
  77.                 else
  78.                     fDeviceInitialized = TRUE;
  79.             }
  80.             else
  81.                 *lpdwError = DV_ERR_NOMEM;
  82.     }
  83.  
  84.         if (*lpdwError != DV_ERR_OK) {
  85.             TransFini ();           // Free the translation table
  86.         HardwareFini();
  87.         return NULL;
  88.         }
  89. #if DEBUG
  90.         {
  91.             char buf[80];
  92.             wsprintf (buf, "Actual BasePort=%X,   IRQ=%d,   BaseMemory=%X", 
  93.                     wPCVideoAddress, gbInt, di.wSegment);
  94.             D1(buf);
  95.         }
  96. #endif
  97.     } // end if this is the first open
  98.  
  99.     // get instance memory
  100.     pChannel = (PCHANNEL)LocalAlloc (LPTR, sizeof(CHANNEL));
  101.  
  102.     if (pChannel == NULL)
  103.         return (PCHANNEL) NULL;
  104.  
  105.     //
  106.     //  make sure the channel is not already in use
  107.     //
  108.     switch ( dwFlags & 
  109.         ( VIDEO_EXTERNALIN | VIDEO_EXTERNALOUT | VIDEO_IN | VIDEO_OUT) ) {
  110.  
  111.         case VIDEO_EXTERNALIN:
  112.             if( gwCaptureUsage >= MAX_CAPTURE_CHANNELS)
  113.                 goto error;
  114.             gwCaptureUsage++;
  115.             break;
  116.  
  117.         case VIDEO_EXTERNALOUT:
  118.             if( gwDisplayUsage >= MAX_DISPLAY_CHANNELS)
  119.                 goto error;
  120.             gwDisplayUsage++;
  121.             break;
  122.  
  123.         case VIDEO_IN:
  124.             if( gwVideoInUsage >= MAX_IN_CHANNELS)
  125.                 goto error;
  126.             gwVideoInUsage++;
  127.             break;
  128.  
  129.         case VIDEO_OUT:
  130.             if( gwVideoOutUsage >= MAX_OUT_CHANNELS)
  131.                 goto error;
  132.             gwVideoOutUsage++;
  133.             break;
  134.  
  135.         default:
  136.             goto error;
  137.     }
  138.  
  139.     //
  140.     //  now that the hardware is allocated init our instance struct.
  141.     //
  142.     pChannel->fccType           = OPEN_TYPE_VCAP;
  143.     pChannel->dwOpenType        = 
  144.     (dwFlags & (VIDEO_EXTERNALIN|VIDEO_EXTERNALOUT|VIDEO_IN|VIDEO_OUT));
  145.     pChannel->dwOpenFlags       = dwFlags;
  146.     pChannel->lpVHdr            = NULL;
  147.     pChannel->dwError           = 0L;
  148.  
  149.     gwDriverUsage++;
  150.     return pChannel;
  151.  
  152. error:
  153.     if (pChannel)
  154.         LocalFree((HLOCAL)pChannel);
  155.  
  156.     *lpdwError = DV_ERR_ALLOCATED;
  157.  
  158.     return NULL;
  159. }
  160.  
  161. DWORD NEAR PASCAL VideoClose(PCHANNEL pChannel)
  162. {
  163.     // Decrement the channel open counters
  164.  
  165.     switch (pChannel-> dwOpenType) {
  166.         case VIDEO_EXTERNALIN:
  167.             gwCaptureUsage--;
  168.             break;
  169.         case VIDEO_EXTERNALOUT:
  170.             gwDisplayUsage--;
  171.             break;
  172.         case VIDEO_IN:
  173. #ifdef USE_PROFILER
  174.             ProfFinish();
  175. #endif
  176.             // If started, or buffers in the queue,
  177.             // don't let the close happen
  178.             if (gfVideoInStarted || lpVHdrFirst)
  179.                 return DV_ERR_STILLPLAYING;
  180.  
  181.             gwVideoInUsage--;
  182.             break;
  183.         case VIDEO_OUT:
  184.             gwVideoOutUsage--;
  185.             break;
  186.         default:
  187.             break;
  188.     }
  189.  
  190.     gwDriverUsage--;  // Overall driver useage count
  191.  
  192.     if (gwDriverUsage == 0) {
  193.         HardwareFini ();        // Shut down the device
  194.         TransFini ();           // Free the translation table
  195.         FreeFrameBufferSelector ();  // Free the frame buffer selector 
  196.         fDeviceInitialized = FALSE;
  197.     }
  198.  
  199.     // Free the instance data
  200.     LocalFree((HLOCAL)pChannel);
  201.  
  202.     return DV_ERR_OK;
  203. }
  204.  
  205. /****************************************************************************
  206.   Show channel specific configuration dialogs
  207. ****************************************************************************/
  208. DWORD NEAR PASCAL VideoDialog (DWORD dwOpenType, HWND hWndParent, DWORD dwFlags)
  209. {
  210.     switch (dwOpenType) {
  211.         case VIDEO_EXTERNALIN:
  212.             if (dwFlags & VIDEO_DLG_QUERY)
  213.                 return DV_ERR_OK;       // Support the dialog
  214.             DialogBox(ghModule, MAKEINTRESOURCE(DLG_VIDEOSOURCE),
  215.                     (HWND)hWndParent, VideoSourceDlgProc);
  216.             break;
  217.  
  218.         case VIDEO_IN:
  219.             if (dwFlags & VIDEO_DLG_QUERY)
  220.                 return DV_ERR_OK;       // Support the dialog
  221.             DialogBox(ghModule, MAKEINTRESOURCE(DLG_VIDEOFORMAT),
  222.                     (HWND)hWndParent, VideoFormatDlgProc);
  223.             break;
  224.  
  225.         case VIDEO_OUT:
  226.             return DV_ERR_NOTSUPPORTED;
  227.  
  228.         case VIDEO_EXTERNALOUT:
  229.             if (dwFlags & VIDEO_DLG_QUERY)
  230.                 return DV_ERR_OK;       // Support the dialog
  231.             DialogBox(ghModule, MAKEINTRESOURCE (DLG_VIDEODISPLAY),
  232.                     (HWND)hWndParent, VideoMonitorDlgProc);
  233.             break;
  234.  
  235.         default:
  236.             return DV_ERR_NOTSUPPORTED;
  237.     }
  238.     return DV_ERR_OK;   // on either cancel or OK
  239. }
  240.  
  241. /****************************************************************************
  242.   Paint the key color
  243. ****************************************************************************/
  244. DWORD NEAR PASCAL VideoUpdate (PCHANNEL pChannel, HWND hWnd, HDC hDC)
  245. {
  246.    CT_Update (hWnd, hDC);
  247.    return DV_ERR_OK;
  248. }
  249.  
  250. /****************************************************************************
  251.   handles DVM_GET_CHANNEL_CAPS message
  252. ****************************************************************************/
  253. DWORD NEAR PASCAL VideoChannelCaps (PCHANNEL pChannel, LPCHANNEL_CAPS lpCaps, DWORD dwSize)
  254. {
  255.     lpCaps-> dwFlags = 0L;
  256.  
  257.     switch (pChannel->dwOpenType) {
  258.         case VIDEO_EXTERNALIN:
  259.             // For this device, scaling happens during digitization
  260.             // into the frame buffer.
  261.             lpCaps-> dwFlags = VCAPS_CAN_SCALE;
  262.             lpCaps-> dwSrcRectXMod = 1;         // Src undefined at present
  263.             lpCaps-> dwSrcRectYMod = 1;
  264.             lpCaps-> dwSrcRectWidthMod = 1;
  265.             lpCaps-> dwSrcRectHeightMod = 1;
  266.             lpCaps-> dwDstRectXMod = 4;
  267.             lpCaps-> dwDstRectYMod = 2;
  268.             lpCaps-> dwDstRectWidthMod = 40;
  269.             lpCaps-> dwDstRectHeightMod = 30;
  270.             break;
  271.  
  272.         case VIDEO_IN:
  273.             lpCaps-> dwFlags = 0;       // No scaling or clipping
  274.             lpCaps-> dwSrcRectXMod = 4;
  275.             lpCaps-> dwSrcRectYMod = 2;
  276.             lpCaps-> dwSrcRectWidthMod = 40;
  277.             lpCaps-> dwSrcRectHeightMod = 30;
  278.             lpCaps-> dwDstRectXMod = 4;
  279.             lpCaps-> dwDstRectYMod = 2;
  280.             lpCaps-> dwDstRectWidthMod = 40;
  281.             lpCaps-> dwDstRectHeightMod = 30;
  282.             break;
  283.  
  284.         case VIDEO_OUT:
  285.             return DV_ERR_NOTSUPPORTED;  
  286.             break;
  287.  
  288.         case VIDEO_EXTERNALOUT:
  289.             // Overlay cannot scale. Positions on 4 pix X, 2 pix Y boundaries
  290.             lpCaps-> dwFlags = VCAPS_OVERLAY;
  291.             lpCaps-> dwSrcRectXMod = 4;
  292.             lpCaps-> dwSrcRectYMod = 2;
  293.             lpCaps-> dwSrcRectWidthMod = 40;
  294.             lpCaps-> dwSrcRectHeightMod = 30;
  295.             lpCaps-> dwDstRectXMod = 4;
  296.             lpCaps-> dwDstRectYMod = 2;
  297.             lpCaps-> dwDstRectWidthMod = 40;
  298.             lpCaps-> dwDstRectHeightMod = 30;
  299.             break;
  300.  
  301.         default:
  302.             return DV_ERR_NOTSUPPORTED;
  303.     }
  304.     return DV_ERR_OK;
  305. }
  306.  
  307. /****************************************************************************
  308.   handles DVM_SRC_RECT and DVM_DST_RECT messages
  309. ****************************************************************************/
  310. DWORD NEAR PASCAL VideoRectangles (PCHANNEL pChannel, BOOL fSrc, LPRECT lpRect, DWORD dwFlags)
  311. {
  312.     static RECT rcMaxRect = {0, 0, 640, 480};
  313.  
  314.     if (lpRect == NULL)
  315.         return DV_ERR_PARAM1;
  316.  
  317.     // Note: many of the uses of the rectangle functions are not actually
  318.     // implemented by the sample driver, (or by Vidcap), but are included 
  319.     // here for future compatibility.
  320.  
  321.     switch (pChannel->dwOpenType) {
  322.         case VIDEO_EXTERNALIN:
  323.             if (!fSrc) {
  324.                 switch (dwFlags) {
  325.                    case VIDEO_CONFIGURE_SET:
  326.                    case VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT:
  327.                         // Where in the frame buffer should the incoming
  328.                         // video be digitized?
  329.                         // For this driver, we only digitize to 0,0
  330.  
  331.                         if ((lpRect->left == 0) && (lpRect->top == 0)) {
  332.                             // We should really do some setup here, but for
  333.                             // the moment, all dimensions are really controlled
  334.                             // by the DVM_SET_FORMAT message.
  335.                             grcDestExtIn = *lpRect;
  336.                             return DV_ERR_OK;
  337.                         }
  338.                         break;
  339.  
  340.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT:
  341.                         *lpRect = grcDestExtIn;
  342.                         return DV_ERR_OK;
  343.                    
  344.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_MAX:
  345.                         *lpRect = rcMaxRect;
  346.                         return DV_ERR_OK;
  347.  
  348.                    default:
  349.                         break;
  350.                 }
  351.             }
  352.             return DV_ERR_NOTSUPPORTED;  
  353.             break;
  354.  
  355.         case VIDEO_IN:
  356.             if (fSrc) {
  357.                 switch (dwFlags) {
  358.                    case VIDEO_CONFIGURE_SET:
  359.                    case VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT:
  360.                         // Where in the frame buffer should we take
  361.                         // the image from?
  362.                         if ((lpRect->right - lpRect->left == (int)gwWidth) &&
  363.                                 (lpRect->bottom - lpRect->top == (int)gwHeight)) {
  364.                             grcSourceIn = *lpRect;
  365.                             return DV_ERR_OK;
  366.                         }
  367.                         break;
  368.  
  369.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT:
  370.                         *lpRect = grcSourceIn;
  371.                         return DV_ERR_OK;
  372.                    
  373.                    case VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_MAX:
  374.                         *lpRect = rcMaxRect;
  375.                         return DV_ERR_OK;
  376.  
  377.                    default:
  378.                         break;
  379.                 }
  380.             }
  381.             return DV_ERR_NOTSUPPORTED;  
  382.             break;
  383.  
  384.         case VIDEO_OUT:
  385.             return DV_ERR_NOTSUPPORTED;  
  386.             break;
  387.  
  388.         case VIDEO_EXTERNALOUT:
  389.             if (fSrc) {
  390.                 if (dwFlags & VIDEO_CONFIGURE_SET) {
  391.                     // What part of the frame buffer should the 
  392.                     // overlay display ?
  393.                     // These are "Windows style" rects,
  394.                     // ie. 0,0 to 160,120 specifies a 160x120 rect.
  395.                     return SetExtOutSourceRect(lpRect);
  396.                 }
  397.                 else
  398.                     return DV_ERR_NOTSUPPORTED;  
  399.             }
  400.             else {
  401.                 if (dwFlags & VIDEO_CONFIGURE_SET) {
  402.                     // Screen coordinates where the overlay should
  403.                     // appear.  These are "Windows style" rects,
  404.                     // ie. 0,0 to 160,120 specifies a 160x120 rect.
  405.                     return SetExtOutDestRect(lpRect);
  406.                 }
  407.                 else
  408.                     return DV_ERR_NOTSUPPORTED;  
  409.             }
  410.  
  411.             break;
  412.  
  413.         default:
  414.             return DV_ERR_NOTSUPPORTED;
  415.     }
  416.     return DV_ERR_NOTSUPPORTED;
  417. }
  418.  
  419. /****************************************************************************
  420.   handles ConfigureStorage message
  421.         lParam1 is lpszKeyFile
  422.         lParam2 is dwFlags
  423. ****************************************************************************/
  424. DWORD NEAR PASCAL VideoConfigureStorageMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  425. {
  426.     if (lParam2 & VIDEO_CONFIGURE_GET)
  427.         CT_LoadConfiguration ((LPSTR) lParam1);
  428.     else if (lParam2 & VIDEO_CONFIGURE_SET)
  429.         CT_SaveConfiguration ((LPSTR) lParam1);
  430.     else
  431.         return DV_ERR_FLAGS;
  432.  
  433.     return DV_ERR_OK;
  434. }
  435.  
  436. /****************************************************************************
  437.  
  438.   handles Configure messages for video
  439.         lParam1 is dwFlags
  440.         lParam2 is LPVIDEOCONFIGPARMS
  441.  
  442. ****************************************************************************/
  443. DWORD NEAR PASCAL VideoConfigureMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  444. {
  445.     LPVIDEOCONFIGPARMS lpcp;
  446.     LPDWORD     lpdwReturn;    // Return parameter from configure.
  447.     LPVOID    lpData1;    // Pointer to data1.
  448.     DWORD    dwSize1;    // size of data buffer1.
  449.     LPVOID    lpData2;    // Pointer to data2.
  450.     DWORD    dwSize2;    // size of data buffer2.
  451.     DWORD       dwFlags;
  452.  
  453.     if (pChannel-> dwOpenType != VIDEO_IN)
  454.         return DV_ERR_NOTSUPPORTED;
  455.  
  456.     dwFlags = lParam1;
  457.  
  458.     lpcp = (LPVIDEOCONFIGPARMS) lParam2;
  459.     lpdwReturn = lpcp-> lpdwReturn;
  460.     lpData1 = lpcp-> lpData1;     
  461.     dwSize1 = lpcp-> dwSize1;     
  462.     lpData2 = lpcp-> lpData2;     
  463.     dwSize2 = lpcp-> dwSize2;     
  464.  
  465.     // Validate dwFlags
  466.     // FIX
  467.  
  468.     switch (msg) {
  469.  
  470.     case DVM_PALETTE:
  471.         switch (dwFlags) {
  472.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_SET):
  473.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_GET):
  474.                 return DV_ERR_OK;
  475.  
  476.             case VIDEO_CONFIGURE_QUERYSIZE:
  477.             case (VIDEO_CONFIGURE_QUERYSIZE | VIDEO_CONFIGURE_GET):
  478.                *lpdwReturn = sizeof(LOGPALETTE) + 
  479.                     (palCurrent.palNumEntries-1) *
  480.                     sizeof(PALETTEENTRY);
  481.                break;
  482.  
  483.             case VIDEO_CONFIGURE_SET:
  484.             case (VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT):
  485.                 if (!lpData1)       // points to a LOGPALETTE structure.
  486.                     return DV_ERR_PARAM1;
  487.                 return (SetDestPalette ( (LPLOGPALETTE) lpData1, 
  488.                         (LPBYTE) NULL));
  489.                 break;
  490.  
  491.             case VIDEO_CONFIGURE_GET:
  492.             case (VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT):
  493.                return (GetDestPalette ( (LPLOGPALETTE) lpData1, 
  494.                         (WORD) dwSize1));
  495.                break;
  496.  
  497.             default:
  498.                return DV_ERR_NOTSUPPORTED;
  499.         } // end of DVM_PALETTE switch
  500.  
  501.         return DV_ERR_OK;   
  502.  
  503.     case DVM_PALETTERGB555:  
  504.         switch (dwFlags) {
  505.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_SET):
  506.                 return DV_ERR_OK;  // only set command is supported
  507.  
  508.             case VIDEO_CONFIGURE_SET:
  509.             case (VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT):
  510.                 if (!lpData1)       // points to a LOGPALETTE structure.
  511.                     return DV_ERR_PARAM1;
  512.                 if (!lpData2)       // points to a 32k byte RGB555 translate table.
  513.                     return DV_ERR_PARAM2;
  514.                 if (dwSize2 != 0x8000)
  515.                     return DV_ERR_PARAM2;
  516.                 return (SetDestPalette ((LPLOGPALETTE)lpData1, 
  517.                         (LPBYTE) lpData2));
  518.                 break;
  519.  
  520.             default:
  521.                 return DV_ERR_NOTSUPPORTED;
  522.         } // end of SETPALETTERGB555 switch
  523.         return DV_ERR_OK;
  524.  
  525.     case DVM_FORMAT:
  526.         switch (dwFlags) {
  527.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_SET):
  528.             case (VIDEO_CONFIGURE_QUERY | VIDEO_CONFIGURE_GET):
  529.                 return DV_ERR_OK;  // command is supported
  530.  
  531.             case VIDEO_CONFIGURE_QUERYSIZE:
  532.             case (VIDEO_CONFIGURE_QUERYSIZE | VIDEO_CONFIGURE_GET):
  533.                *lpdwReturn = sizeof(BITMAPINFOHEADER);
  534.                break;
  535.  
  536.             case VIDEO_CONFIGURE_SET:
  537.             case (VIDEO_CONFIGURE_SET | VIDEO_CONFIGURE_CURRENT):
  538.                 return (SetDestFormat ((LPBITMAPINFOHEADER) lpData1, 
  539.                         (WORD) dwSize1));
  540.                 break;
  541.  
  542.             case VIDEO_CONFIGURE_GET:
  543.             case (VIDEO_CONFIGURE_GET | VIDEO_CONFIGURE_CURRENT):
  544.                 return (GetDestFormat ((LPBITMAPINFOHEADER) lpData1, 
  545.                         (WORD) dwSize1));
  546.                 break;
  547.  
  548.             default:
  549.                return DV_ERR_NOTSUPPORTED;
  550.         }  //end of DVM_FORMAT switch
  551.  
  552.         return DV_ERR_OK;
  553.  
  554.     default:        // Not a msg that we understand
  555.         return DV_ERR_NOTSUPPORTED;
  556.  
  557.     } // end of msg switch
  558.  
  559.     return DV_ERR_NOTSUPPORTED;
  560. }
  561.  
  562. /****************************************************************************
  563.  
  564.   handles Stream messages for video 
  565.  
  566. ****************************************************************************/
  567. DWORD NEAR PASCAL VideoStreamMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  568. {
  569.     DWORD       dwOpenType = pChannel-> dwOpenType;
  570.  
  571.  
  572.     if (dwOpenType == VIDEO_EXTERNALIN) {       // Capture channel
  573.         switch (msg) {
  574.             case DVM_STREAM_INIT:
  575.                 CT_Acquire (TRUE);
  576.                 break;
  577.             case DVM_STREAM_FINI:
  578.                 CT_Acquire (FALSE);
  579.                 break;
  580.             default:
  581.                 return DV_ERR_NOTSUPPORTED;
  582.         }
  583.         return DV_ERR_OK;
  584.     }
  585.  
  586.     else if (dwOpenType == VIDEO_EXTERNALOUT) { // Overlay channel
  587.         switch (msg) {
  588.             case DVM_STREAM_INIT:
  589.                 CT_OverlayEnable (TRUE);
  590.                 break;
  591.             case DVM_STREAM_FINI:
  592.                 CT_OverlayEnable (FALSE);
  593.                 break;
  594.             default:
  595.                 return DV_ERR_NOTSUPPORTED;
  596.         }
  597.         return DV_ERR_OK;
  598.     }
  599.  
  600.     else switch (msg) {                         // Input channel
  601.         //
  602.         //  lParam1     -   LPVIDEO_STREAM_INIT_PARMS
  603.         //
  604.         //  lParam2     -   sizeof (LPVIDEO_STREAM_INIT_PARMS)
  605.         //
  606.         case DVM_STREAM_INIT:           
  607.             return InStreamOpen((LPVIDEO_STREAM_INIT_PARMS)lParam1 );
  608.  
  609.         case DVM_STREAM_FINI:
  610.             return InStreamClose();
  611.  
  612.         case DVM_STREAM_GETERROR:
  613.             return InStreamError((LPDWORD) lParam1, (LPDWORD) lParam2);
  614.  
  615.         case DVM_STREAM_GETPOSITION:
  616.             return InStreamGetPos((LPMMTIME) lParam1, (DWORD) lParam2);
  617.  
  618.         case DVM_STREAM_ADDBUFFER:
  619.             return InStreamAddBuffer((LPVIDEOHDR)lParam1);
  620.  
  621.         case DVM_STREAM_PREPAREHEADER:  // Handled by MSVideo
  622.             return DV_ERR_NOTSUPPORTED;
  623.  
  624.         case DVM_STREAM_UNPREPAREHEADER: // Handled by MSVideo
  625.             return DV_ERR_NOTSUPPORTED;
  626.  
  627.         case DVM_STREAM_RESET:          
  628.             return InStreamReset();
  629.  
  630.         case DVM_STREAM_START:          
  631.             return InStreamStart();
  632.  
  633.         case DVM_STREAM_STOP:           
  634.             return InStreamStop();
  635.  
  636.         default:
  637.             return DV_ERR_NOTSUPPORTED;
  638.  
  639.     } // end switch on message type
  640. }
  641.  
  642. /****************************************************************************
  643.  
  644.   Main message handler
  645.  
  646. ****************************************************************************/
  647. DWORD NEAR PASCAL VideoProcessMessage(PCHANNEL pChannel, UINT msg, LONG lParam1, LONG lParam2)
  648. {
  649.     DWORD       dwOpenType = pChannel-> dwOpenType;
  650.  
  651.     switch (msg) {
  652.         case DVM_GETERRORTEXT: /* lParam1 = LPVIDEO_GETERRORTEXT_PARMS */
  653.             if (LoadString(ghModule, 
  654.                     (WORD)  ((LPVIDEO_GETERRORTEXT_PARMS) lParam1) ->dwError,
  655.                     (LPSTR) ((LPVIDEO_GETERRORTEXT_PARMS) lParam1) ->lpText,
  656.                     (int)   ((LPVIDEO_GETERRORTEXT_PARMS) lParam1) ->dwLength))
  657.                 return DV_ERR_OK;
  658.             else
  659.                 return DV_ERR_PARAM1;
  660.             break;            
  661.  
  662.         //
  663.         //  lParam1     -   hWndParent
  664.         //
  665.         //  lParam2     -   flags
  666.         //
  667.         case DVM_DIALOG: /* lParam1 = hWndParent, lParam2 = dwFlags */
  668.             return (VideoDialog (dwOpenType, (HWND) lParam1, (DWORD) lParam2));
  669.             break;
  670.  
  671.         case DVM_PALETTE:
  672.         case DVM_FORMAT:
  673.         case DVM_PALETTERGB555:
  674.             return VideoConfigureMessage(pChannel, msg, lParam1, lParam2);
  675.  
  676.         case DVM_SRC_RECT:
  677.         case DVM_DST_RECT:
  678.             return VideoRectangles (pChannel, (msg == DVM_SRC_RECT) /* fSource */,
  679.                         (LPRECT) lParam1, 
  680.                         (DWORD) lParam2);
  681.  
  682.         case DVM_UPDATE:
  683.             if (dwOpenType != VIDEO_EXTERNALOUT)
  684.                 return DV_ERR_NOTSUPPORTED;
  685.             return VideoUpdate (pChannel, (HWND) lParam1, (HDC) lParam2);
  686.  
  687.         case DVM_CONFIGURESTORAGE:
  688.             return VideoConfigureStorageMessage(pChannel, msg, lParam1, lParam2);
  689.  
  690.         case DVM_FRAME:
  691.             if (dwOpenType != VIDEO_IN)
  692.                 return DV_ERR_NOTSUPPORTED;
  693.  
  694.             return (CaptureFrame((LPVIDEOHDR)lParam1));
  695.  
  696.         case DVM_GET_CHANNEL_CAPS:
  697.             return VideoChannelCaps (pChannel, (LPCHANNEL_CAPS) lParam1,  (DWORD)lParam2); 
  698.  
  699.         default:
  700.             if (msg >= DVM_STREAM_MSG_START && msg <= DVM_STREAM_MSG_END)
  701.                 return VideoStreamMessage(pChannel, msg, 
  702.                         lParam1, lParam2);
  703.             else
  704.                 return DV_ERR_NOTSUPPORTED;
  705.     }
  706. }
  707.  
  708.