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