home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / videotlk.zip / SAMPLES / DIVEOLD / DIVELIB.C < prev    next >
Text File  |  1998-12-24  |  19KB  |  532 lines

  1. // #define DEBUG
  2. #define VCAI_ENABLED
  3. #define DIVE_ENABLED
  4. #define VCAI_MONITOR
  5.  
  6. #define INCL_DOS
  7. #define INCL_DOSERRORS
  8. #define INCL_GPI
  9. #define INCL_WIN
  10. #define INCL_32
  11.  
  12. #include <os2.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16.  
  17. #define  _MEERROR_H_
  18. #include <mmioos2.h>                   /* It is from MMPM toolkit           */
  19. #include <dive.h>
  20. #include <fourcc.h>
  21. #include <vcadd.h>
  22. #include <vcai.h>
  23.  
  24. #include "dive.h"
  25. #include "pmtv2rem.h"
  26.  
  27. #define WIDTH   (300)
  28. #define HEIGHT  (240)
  29.  
  30. HWND        HwndNBFrame;            // Notebook frame handle
  31. BOOL        NotebookOpen = FALSE;   // Notebook not open
  32.  
  33. void remote_open (MOUSEPOS mousepos);
  34.  
  35. PWINDATA DiveSetup (char *name, USHORT instance, USHORT connector);
  36. int DiveRegister (HAB hab);
  37. int DiveStop (void);
  38.  
  39. static void msg_box (UCHAR *txt, UCHAR *title, ULONG options);
  40.  
  41. static WINDATA      WTV_data;
  42. static DIVE_CAPS    DiveCaps = {0};         // DIVE capabilities of system
  43. static FOURCC       fccFormats[100] = {0};  // Color format code
  44. static SETUP_BLITTER    SetupBlitter;       // structure for blitter ops.
  45.  
  46.  
  47. /* This function will display a TV in the window using DIVE.  The basic     *
  48.  * theory is that the WinCast board will be continually capturing into the  *
  49.  * buffer and DIVE will blit the image onto the screen.  The blitter is     *
  50.  * setup in the main thread of the program where window details are known.  */
  51. VOID APIENTRY DiveTV (ULONG data_addr)
  52. {
  53. PWINDATA    win_data = NULL;        /* Structure holding window information */
  54. UCHAR      *tv_image = NULL;        /* Capture buffer for TV image          */
  55. size_t      tv_size = 0;            /* Size of capture buffer               */
  56. ULONG       rc = 0;                 /* DIVE error return code               */
  57. ULONG       dive_srcbuf_no = 0;     /* DIVE source buffer number            */
  58. ULONG       line_len = 0;
  59. ULONG       scanline_bytes = 0;
  60. ULONG       scanlines = 0;
  61. PBYTE       dive_buf_addr = 0;
  62. RECTL       dive_rect;
  63.  
  64.     /* Set the window information and check it's valid.                     */
  65.     if ((win_data = (PWINDATA)data_addr) == NULL)
  66.     {
  67.         DosExit (EXIT_PROCESS, 1);
  68.         return;
  69.     }
  70.  
  71.     /* Wait until we are permitted to proceed                               */
  72.     while (win_data->win_blit_halt)
  73.         DosSleep (100);
  74.  
  75.     /* Allocate a capture buffer for the image and declare it to DIVE       */
  76.     tv_size = (size_t)(win_data->win_dive_width * win_data->win_dive_height * 4);
  77.     rc = DosAllocMem ((PPVOID)&tv_image, tv_size, (PAG_COMMIT | PAG_WRITE));
  78.     if (rc != NO_ERROR)
  79.     {
  80.         DosExit (EXIT_PROCESS, 1);
  81.         return;
  82.     }
  83.  
  84. #ifdef DIVE_ENABLED
  85.     line_len = (win_data->win_dive_width << 1);
  86.     line_len = (line_len - (line_len % 4));
  87.     rc = DiveAllocImageBuffer (win_data->win_dive_handle,
  88.                                &dive_srcbuf_no, FOURCC_Y422,
  89.                                win_data->win_dive_width,
  90.                                win_data->win_dive_height,
  91.                                0,                       // DIVE sets line len
  92.                                (PBYTE)tv_image);
  93.     if (rc)
  94.     {
  95.         DosExit (EXIT_PROCESS, 1);
  96.         return;
  97.     }
  98.     dive_rect.xLeft = 0;
  99.     dive_rect.yTop = 0;
  100.     dive_rect.xRight = win_data->win_dive_width;
  101.     dive_rect.yBottom = win_data->win_dive_height;
  102. #endif
  103.  
  104. #ifdef VCAI_ENABLED
  105.  
  106.     // Connect to the capture board and start the capture.
  107.  
  108.         VcaiVideoRectValidate (0, 0,
  109.                            win_data->win_dive_width, win_data->win_dive_height,
  110.                            0, 0,
  111.                            win_data->win_dive_width, win_data->win_dive_height);
  112. #ifdef VCAI_MONITOR
  113.         VcaiWCastMonitor (win_data->win_dive_width, win_data->win_dive_height,
  114.                       (ULONG)tv_image);
  115.  
  116. //      VcaiVideoRectValidate (0, 0,
  117. //                         win_data->win_dive_width, win_data->win_dive_height,
  118. //                         0, 0,
  119. //                         win_data->win_dive_width, win_data->win_dive_height);
  120.  
  121.         VcaiOverlay (TRUE);
  122. #endif
  123. #endif
  124.  
  125.         win_data->win_bliting = TRUE;
  126.         while (!win_data->win_blit_halt)
  127.         {
  128. #ifdef DIVE_ENABLED
  129.         DosSleep (30);
  130.  
  131.         /* Blit the image to the screen.  There may be a need for the DIVE  *
  132.          * buffer (dive_srcbuf_no) to be DiveBeginImageBufferAccess'ed      *
  133.          * before the blit is made.                                         */
  134.             DiveBlitImage (win_data->win_dive_handle,
  135.                        dive_srcbuf_no, DIVE_BUFFER_SCREEN);
  136. #endif
  137.     }
  138.  
  139. #ifdef VCAI_ENABLED
  140. #ifdef VCAI_MONITOR
  141.         VcaiOverlay (FALSE);
  142.  
  143.     // This call will stop displaying the image and free the memory that is
  144.     // stuck in the PC RAM
  145.         VcaiWCastMonitor (0, 0, 0L);
  146. #endif
  147.  
  148.         VcaiVideoInputSet (4);
  149.         VcaiDeviceClose (win_data->win_vcai_handle);
  150. #endif
  151.  
  152.     /* Free any buffers and undeclare any of the DIVE buffers used          */
  153. #ifdef DIVE_ENABLED
  154.         DiveFreeImageBuffer (win_data->win_dive_handle, dive_srcbuf_no);
  155. #endif
  156.         DosFreeMem (tv_image);
  157.  
  158.     /* Inform the main thread that all has finished okay.                   */
  159.         win_data->win_bliting = FALSE;
  160. }
  161.  
  162.  
  163. MRESULT EXPENTRY TVWindowProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  164. {
  165. static PWINDATA win_data = NULL;    /* Pointer to window data               */
  166. HPS             hps;                /* Presentation Space handle            */
  167. HRGN            hrgn;               /* Region handle                        */
  168. RGNRECT         rgnCtl;             /* Processing control structure         */
  169. RECTL           rcl;                /* Current widow rectangle              */
  170. POINTL          pointl;             /* Point to offset from Desktop         */
  171. ULONG           rc;
  172. ULONG           width;              /* Width of the current rectangle       */
  173. MOUSEPOS        mousepos;           /* Position of mouse in window          */
  174.  
  175.     /* Get the pointer to window data                                       */
  176.     if (win_data == NULL)
  177.     {
  178.         if ((win_data = (PWINDATA)WinQueryWindowULong (hwnd, 0)) == NULL)
  179.             return WinDefWindowProc (hwnd, msg, mp1, mp2);
  180.     }
  181.  
  182.     /* Handle messages to this window                                       */
  183.     switch (msg)
  184.     {
  185.     case WM_COMMAND:
  186.         switch (SHORT1FROMMP (mp1))
  187.         {
  188.         case ID_FILE_EXIT:
  189.             win_data->win_blit_halt = TRUE;
  190.             DiveSetupBlitter (win_data->win_dive_handle, 0);
  191.             WinPostMsg (hwnd, WM_QUIT, 0L, 0L);
  192.             break;
  193.  
  194.         case ID_TV_SETUP:
  195.             if (NotebookOpen)
  196.             {
  197.                 WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  198.                                (PSZ)"Settings notebook already open",
  199.                                (PSZ)WTV_NAME, 0, MB_OK | MB_INFORMATION);
  200.                 break;
  201.             }
  202.             HwndNBFrame = WinLoadSecondaryWindow (HWND_DESKTOP, HWND_DESKTOP,
  203.                                                   (PFNWP)NotebookDlgProc,
  204.                                                   (HMODULE)NULLHANDLE,
  205.                                                   IDD_NOTE,
  206.                                                   NULL);
  207.             break;
  208.  
  209.         case ID_TV_CON1:
  210.         case ID_TV_CON2:
  211.         case ID_TV_RF:
  212.         case ID_TV_SVHS:
  213.         case ID_TV_TEST:
  214.  
  215.             if (win_data->win_vcai_handle == 0)
  216.             {
  217.                 WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  218.                                (PSZ)"Connector not initialised",
  219.                                (PSZ)WTV_NAME, 0, MB_OK | MB_INFORMATION);
  220.                 break;
  221.             }
  222. #ifdef VCAI_ENABLED
  223.             /* Now, alter the connector to the appropriate one              */
  224.             VcaiVideoInputSet (SHORT1FROMMP(mp1)-BASE_CONNECTOR);
  225. #endif
  226.             break;
  227.  
  228.         default:
  229.             /* Let PM handle this message.                                  */
  230.             return WinDefWindowProc (hwnd, msg, mp1, mp2);
  231.         }
  232.         break;
  233.  
  234.     case WM_BUTTON1CLICK :
  235.         WinQueryWindowRect (hwnd, &rcl);
  236.         WinMapWindowPoints (hwnd, HWND_DESKTOP, (PPOINTL)&rcl, 2);
  237.         mousepos.mp_x = MOUSEMSG (&msg)->x + rcl.xLeft;
  238.         mousepos.mp_y = MOUSEMSG (&msg)->y + rcl.yBottom;
  239.         remote_open (mousepos);
  240.         break;
  241.  
  242.     case WM_VRNDISABLED:
  243. #ifdef DIVE_ENABLED
  244.         /* Stop the blitter                                                 */
  245.         DiveSetupBlitter (win_data->win_dive_handle, 0);
  246. #endif
  247.         break;
  248.  
  249.     case WM_VRNENABLED:
  250.         if ((hps = WinGetPS (hwnd)) == 0)
  251.             break;
  252.         if ((hrgn = GpiCreateRegion (hps, 0L, NULL)) == RGN_ERROR)
  253.         {
  254.             WinReleasePS( hps );
  255.             break;
  256.         }
  257.  
  258.         /* NOTE: If mp1 is zero, then this was just a move message.     *
  259.          * Illustrate the visible region on a WM_VRNENABLE.             */
  260.         WinQueryVisibleRegion (hwnd, hrgn);
  261.         rgnCtl.ircStart     = 0;
  262.         rgnCtl.crc          = 50;
  263.         rgnCtl.ulDirection  = RECTDIR_LFRT_TOPBOT;
  264.  
  265.         /* Get the all ORed rectangles                                  */
  266.         rc = (ULONG)GpiQueryRegionRects (hps, hrgn, NULL,
  267.                                          &rgnCtl, win_data->win_rcls);
  268.         if (rc == FALSE)
  269.         {
  270. #ifdef DIVE_ENABLED
  271.             /* Reset the blitter and close                              */
  272.             DiveSetupBlitter (win_data->win_dive_handle, 0);
  273. #endif
  274.             GpiDestroyRegion (hps, hrgn);
  275.             WinReleasePS (hps);
  276.             break;
  277.         }
  278.         win_data->win_rcl_cnt = rgnCtl.crcReturned;
  279.  
  280.         /* Now find the window position and size, relative 2 parent         *
  281.          * Convert the point to offset from desktop lower left.             */
  282.         WinQueryWindowPos (win_data->win_hwnd_client, &win_data->win_swp);
  283.         pointl.x = win_data->win_swp.x;
  284.         pointl.y = win_data->win_swp.y;
  285.  
  286.         WinMapWindowPoints (win_data->win_hwnd_frame,
  287.                             HWND_DESKTOP, &pointl, 1);
  288.  
  289.         /* Tell DIVE about the new settings.                                */
  290.         SetupBlitter.lScreenPosX       = pointl.x;
  291.         SetupBlitter.lScreenPosY       = pointl.y;
  292.         SetupBlitter.ulDstWidth        = win_data->win_swp.cx;
  293.         SetupBlitter.ulDstHeight       = win_data->win_swp.cy;
  294.         SetupBlitter.ulNumDstRects     = win_data->win_rcl_cnt;
  295.         SetupBlitter.pVisDstRects      = win_data->win_rcls;
  296.  
  297. #ifdef DIVE_ENABLED
  298.         DiveSetupBlitter (win_data->win_dive_handle, &SetupBlitter);
  299. #endif
  300.         win_data->win_blit_halt = FALSE;
  301.  
  302.         GpiDestroyRegion (hps, hrgn);
  303.         WinReleasePS (hps);
  304.         break;
  305.  
  306.  
  307.     case WM_REALIZEPALETTE:
  308. #ifdef DIVE_ENABLED
  309.         /* This tells DIVE that the physical palette may have changed.      */
  310.         DiveSetDestinationPalette (win_data->win_dive_handle, 0, 0, 0);
  311. #endif
  312.         break;
  313.  
  314.     case WM_CLOSE:
  315.         /* Post to quit the dispatch message loop.                          */
  316.         win_data->win_blit_halt = TRUE;
  317.         DiveSetupBlitter (win_data->win_dive_handle, 0);
  318.         WinPostMsg (hwnd, WM_QUIT, 0L, 0L);
  319.         break;
  320.  
  321.     default:
  322.         /* Let PM handle this message.                                      */
  323.         return WinDefWindowProc (hwnd, msg, mp1, mp2);
  324.     }
  325.     return ( FALSE );
  326. }
  327.  
  328.  
  329. PWINDATA DiveSetup (char *name, USHORT instance, USHORT connector)
  330. {
  331.     DRIVERHANDLE vhandle;
  332.     char txt[400];
  333.  
  334.         WTV_data.win_vcai_connector = connector;
  335.         strcpy  (WTV_data.win_vcai_name, name);
  336.         WTV_data.win_vcai_no        = instance;
  337.         vhandle = VcaiDeviceOpen (name, instance);
  338.         if (vhandle <= 0)
  339.         {
  340.             sprintf (txt, "Cannot Open Device %s %u !", name, instance);
  341.             WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
  342.                        txt,
  343.                        (PSZ)WTV_NAME,
  344.                        0, MB_OK | MB_INFORMATION);
  345.             return FALSE;
  346.         }
  347.         WTV_data.win_vcai_handle = vhandle;
  348.         VcaiDeviceConnect (vhandle);
  349.         VcaiVideoInputSet (connector);
  350.  
  351. #ifdef DIVE_ENABLED
  352.     // Get the DIVE capabilities and if the system is 16 coloured then exit
  353.  
  354.         DiveCaps.pFormatData    = fccFormats;
  355.         DiveCaps.ulFormatLength = 120;
  356.         DiveCaps.ulStructLen    = sizeof (DIVE_CAPS);
  357.         if (DiveQueryCaps (&DiveCaps, DIVE_BUFFER_SCREEN))
  358.         {
  359.             msg_box ("Unable to query the Dive environment",
  360.                  "Error", MB_OK | MB_ERROR);
  361.             return FALSE;
  362.         }
  363.  
  364.         if (DiveCaps.ulDepth < 8)
  365.         {
  366.             msg_box ("Unable to execute in a 16-colour environment",
  367.                   "Error", MB_OK | MB_ERROR);
  368.             return FALSE;
  369.         }
  370.  
  371.     // Calculate the bytes per pixel
  372.         WTV_data.win_sizebytes = DiveCaps.ulScanLineBytes /
  373.                                  DiveCaps.ulHorizontalResolution;
  374.  
  375.     // Open the DIVE device and the VCAI capture device
  376.         if (DiveOpen (&(WTV_data.win_dive_handle), FALSE, 0))
  377.         {
  378.             msg_box ("Unable to open the DIVE device",
  379.                   "Error", MB_OK | MB_ERROR);
  380.             return FALSE;
  381.         }
  382. #endif
  383.  
  384.     // Set the window size
  385.         WTV_data.win_width  = WIDTH;          // 640  400
  386.         WTV_data.win_height = HEIGHT;          // 320  300
  387.  
  388. #if 0
  389.         WTV_data.win_dive_width  = WTV_data.win_width - 4;
  390.         WTV_data.win_dive_height = (3 * WTV_data.win_height) >> 2;
  391. #else
  392.         WTV_data.win_dive_width  = WIDTH;     // 636
  393.         WTV_data.win_dive_height = HEIGHT;     // 320
  394. #endif
  395.         return &WTV_data;
  396. }
  397.  
  398. int DiveRegister (HAB hab)
  399. {
  400. ULONG   flCreate;           // Window creation control flags
  401. ULONG   rc;
  402.  
  403.     // Register a window class, and create a standard window.
  404.         WinRegisterClass (hab, (PSZ)"WTVWindow", TVWindowProc, 0, sizeof (ULONG));
  405.         flCreate = FCF_TASKLIST | FCF_SYSMENU  |
  406.                FCF_TITLEBAR | FCF_ICON |
  407.                FCF_SIZEBORDER | FCF_MINMAX | FCF_MENU | FCF_SHELLPOSITION;
  408.  
  409.     // Window
  410.         WTV_data.win_hwnd_frame = WinCreateStdWindow (HWND_DESKTOP,
  411.                                                   WS_VISIBLE, &flCreate,
  412.                                                   (PSZ)"WTVWindow",
  413.                                                   (PSZ)"DIVE Window",
  414.                                                   WS_SYNCPAINT | WS_VISIBLE,
  415.                                                   0, ID_MAINWND,
  416.                                                   &(WTV_data.win_hwnd_client));
  417.  
  418.         WinSetWindowULong (WTV_data.win_hwnd_client, 0, (ULONG)&WTV_data);
  419.  
  420.  
  421.     // Query some information about the window, i.e. size and position
  422.         WTV_data.win_cxWidthBorder =
  423.             (LONG)WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER);
  424.         WTV_data.win_cyWidthBorder =
  425.             (LONG)WinQuerySysValue (HWND_DESKTOP, SV_CYSIZEBORDER);
  426.         WTV_data.win_cyTitleBar    =
  427.             (LONG)WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);
  428.         WTV_data.win_cyMenu        =
  429.             (LONG)WinQuerySysValue (HWND_DESKTOP, SV_CYMENU);
  430.  
  431. //    WTV_data.win_cxWidthWindow   = (WTV_data.win_width / 2) +
  432.         WTV_data.win_cxWidthWindow   = WTV_data.win_width +
  433.                                        (WTV_data.win_cxWidthBorder * 2);
  434.         WTV_data.win_cyHeightWindow  = (WTV_data.win_cyWidthBorder * 2) +
  435.                                        WTV_data.win_cyTitleBar +
  436.                                        WTV_data.win_cyMenu +
  437.                                        WTV_data.win_height;
  438.  
  439.         WTV_data.win_cxWindowPos   =
  440.                      ((LONG)WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN)
  441.                                         - WTV_data.win_cxWidthWindow ) / 2;
  442.         WTV_data.win_cyWindowPos   =
  443.                      ((LONG)WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN)
  444.                                         - WTV_data.win_cyHeightWindow ) / 2;
  445.  
  446.  
  447.     // Set the window position and size.
  448.         WinSetWindowPos (WTV_data.win_hwnd_frame, HWND_TOP,
  449.                      WTV_data.win_cxWindowPos, WTV_data.win_cyWindowPos,
  450.                      WTV_data.win_cxWidthWindow, WTV_data.win_cyHeightWindow,
  451.                      SWP_SIZE | SWP_MOVE | SWP_SHOW | SWP_ACTIVATE);
  452.  
  453.     // Turn on visible region notification.
  454.         WinSetVisibleRegionNotify (WTV_data.win_hwnd_client, TRUE);
  455.  
  456.     // Send an invlaidation message to the client.
  457.         SetupBlitter.ulStructLen        = sizeof (SETUP_BLITTER);
  458.         SetupBlitter.fccSrcColorFormat  = FOURCC_Y422;
  459. //    SetupBlitter.ulSrcWidth         = (WTV_data.win_dive_width / 2);
  460.         SetupBlitter.ulSrcWidth         = WTV_data.win_dive_width;
  461.         SetupBlitter.ulSrcHeight        = WTV_data.win_dive_height;
  462.         SetupBlitter.ulSrcPosX          = 0;
  463.         SetupBlitter.ulSrcPosY          = 0;
  464.         SetupBlitter.ulDitherType       = 1;        // Dither please!
  465.         SetupBlitter.fInvert            = FALSE;
  466.  
  467.         SetupBlitter.lDstPosX = 0;
  468.         SetupBlitter.lDstPosY = 0;
  469.  
  470.         SetupBlitter.fccDstColorFormat = FOURCC_SCRN;
  471.  
  472.         WinPostMsg (WTV_data.win_hwnd_frame, WM_VRNENABLED, 0L, 0L);
  473.  
  474.     // Start up the blitting thread.
  475.         WTV_data.win_bliting = FALSE;
  476.         WTV_data.win_blit_halt = TRUE;
  477.         rc = DosCreateThread (&(WTV_data.win_blit_tid),
  478.                               (PFNTHREAD)DiveTV,
  479.                               (ULONG)&WTV_data, 0L, 8192L);
  480.         if (rc)
  481.         {
  482.             WinSetVisibleRegionNotify (WTV_data.win_hwnd_client, FALSE);
  483.  
  484. #ifdef DIVE_ENABLED
  485.             DiveClose (WTV_data.win_dive_handle);
  486. #endif
  487.             WinDestroyWindow (WTV_data.win_hwnd_frame);
  488.             return FALSE;
  489.         }
  490.  
  491.     // Set the proiroty of the blitting thread
  492.         DosSetPriority (PRTYS_THREAD, PRTYC_IDLETIME, 0, WTV_data.win_blit_tid);
  493.         WTV_data.win_blit_halt = FALSE;
  494.         return TRUE;
  495. }
  496.  
  497. int DiveStop ()
  498. {
  499. #ifdef DIVE_ENABLED
  500.     // Set the variable to end the running thread, and wait for it to end.
  501.         WTV_data.win_blit_halt = TRUE;
  502.         DosWaitThread (&(WTV_data.win_blit_tid), DCWW_WAIT);
  503. #endif
  504.  
  505. #ifdef DEBUG
  506.         msg_box ("DiveTV thread has been closed okay",
  507.                      "Info", MB_OK | MB_INFORMATION);
  508. #endif
  509.  
  510.     // Turn off visible region notificationm tidy up, and terminate DIVE
  511.         WinSetVisibleRegionNotify (WTV_data.win_hwnd_client, FALSE);
  512. #ifdef DIVE_ENABLED
  513.         DiveClose (WTV_data.win_dive_handle);
  514. #endif
  515.  
  516.     // Process for termination
  517.         WinDestroyWindow (WTV_data.win_hwnd_frame);
  518.  
  519.         return TRUE;
  520. }
  521.  
  522. static void msg_box (UCHAR *txt, UCHAR *title, ULONG options)
  523. {
  524.         WinMessageBox (HWND_DESKTOP,
  525.                        HWND_DESKTOP,
  526.                        txt,
  527.                        title,
  528.                        0,
  529.                        options);
  530. }
  531.  
  532.