home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wvis0626.zip / warpvision_20020626.zip / libDIVEpm.cpp < prev    next >
C/C++ Source or Header  |  2002-06-24  |  9KB  |  304 lines

  1. /*
  2.     OS/2 DIVE class library: PM related functions
  3.     Copyright (C) 1997 by Andrew Zabolotny <bit@eltech.ru>
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #define INCL_DOS
  21. #define INCL_WIN
  22. #define INCL_OS2MM
  23.  
  24. #include <os2.h>
  25. #include <os2me.h>
  26. #include <process.h>
  27. #include <signal.h>
  28. #include "libDIVE.h"
  29. #include "libDIVEpm.h"
  30.  
  31. #define WM_DiveCommand  0x9F37      // Choose a unused msg #
  32. #define defWindowStyle  FCF_TITLEBAR | FCF_SYSMENU | FCF_ACCELTABLE
  33.  
  34. static volatile TID PMtid = 0;          // PM thread ID
  35.  volatile HWND PMmng = NULLHANDLE;// PM request manager window
  36. static diveApp *volatile dA;            // PM application object
  37. static volatile HMTX semBusy;           // PM thread requests semaphore
  38. static volatile HEV semSleep;           // PM thread will post this
  39. FGVideoMode *vmList;                    // Pointer to an array of FGVideoMode
  40. u_int vmCount;                          // Number of videomodes in vmList
  41. long DesktopW, DesktopH;                // Desktop width x height
  42. HMODULE gdMH = NULLHANDLE;              // Module (DLL) handle
  43.  
  44. static MRESULT EXPENTRY PMmanager (HWND Handle, ULONG Message, MPARAM MsgParm1, MPARAM MsgParm2)
  45. {
  46.   PMrq *rqData = (PMrq *) MsgParm2;
  47.   ULONG rc = pmrcOK;
  48.  
  49.   switch (Message)
  50.   {
  51.     case WM_DiveCommand:
  52.       switch ((ULONG) MsgParm1)
  53.       {
  54.         case pmcmdCreateWindow:
  55.         {
  56.           // Create a DIVE window
  57.           HWND wnd = dA->CreateWindow ((PSZ) rqData->Parm.CreateWindow.Title, gdMH, idDive, defWindowStyle);
  58.  
  59.           if (wnd)
  60.             rqData->Parm.CreateWindow.Handle = wnd;
  61.           else
  62.             rc = pmrcWindowCreationError;
  63.           break;
  64.         }
  65.         case pmcmdDestroyWindow:
  66.         {
  67.           WinDestroyWindow (rqData->Parm.DestroyWindow.Handle);
  68.           break;
  69.         }
  70.         case pmcmdCreateDIVEctx:
  71.         {
  72.           // Create a DIVE context
  73.           rqData->Parm.CreateCtx.dW = new diveWindow (rqData->Parm.CreateCtx.Mode->Width,
  74.             rqData->Parm.CreateCtx.Mode->Height, (FOURCC) rqData->Parm.CreateCtx.Mode->PixelFormat,
  75.             rqData->Parm.CreateCtx.Mode->SrcWidth,
  76.             rqData->Parm.CreateCtx.Mode->SrcHeight,
  77.             rqData->Parm.CreateCtx.Mode->Buffers);
  78.           if (!rqData->Parm.CreateCtx.dW)
  79.           {
  80.             rc = pmrcDIVEfailure;
  81.             break;
  82.           }
  83.           if (rqData->Parm.CreateCtx.dW->lastError != derrOK)
  84.           {
  85.             delete rqData->Parm.CreateCtx.dW;
  86.  
  87.             rqData->Parm.CreateCtx.dW = NULL;
  88.             rc = pmrcDIVEfailure;
  89.             break;
  90.           }
  91.           break;
  92.         }
  93.         case pmcmdDestroyDIVEctx:
  94.         {
  95.           if (rqData->Parm.DestroyCtx.dW)
  96.             delete rqData->Parm.DestroyCtx.dW;
  97.           else
  98.             rc = pmrcNotInitialized;
  99.           break;
  100.         }
  101.         case pmcmdBindDIVEctx:
  102.         {
  103.           int i, Scale, W, H;
  104.  
  105.           if (!rqData->Parm.BindCtx.dW->Bind (rqData->Parm.BindCtx.Handle))
  106.           {
  107.             rc = pmrcBadWindow;
  108.             break;
  109.           }
  110.           // If we have a *frame* window, we have full control of it
  111.           if (rqData->Parm.BindCtx.dW->diveFR)
  112.           {
  113.             // Disable DIVE window accelerator table, if we want to use OS/2 reserved keys
  114.             rqData->Parm.BindCtx.dW->DisableAccelTable ();
  115.  
  116.             // Compute optimal window scale
  117.             Scale = rqData->Parm.BindCtx.DesktopW / rqData->Parm.BindCtx.dW->BufferWidth ();
  118.             i = rqData->Parm.BindCtx.DesktopH / rqData->Parm.BindCtx.dW->BufferHeight ();
  119.             if (Scale > i)
  120.               Scale = i;
  121.             if (Scale == 0)
  122.             {
  123.               W = rqData->Parm.BindCtx.DesktopW;
  124.               H = rqData->Parm.BindCtx.DesktopH;
  125.             } else
  126.             {
  127.               W = rqData->Parm.BindCtx.dW->BufferWidth () * Scale;
  128.               H = rqData->Parm.BindCtx.dW->BufferHeight () * Scale;
  129.             }
  130.             rqData->Parm.BindCtx.dW->Resize (W, H, TRUE);
  131. //            if ((W == rqData->Parm.BindCtx.DesktopW) && (H == rqData->Parm.BindCtx.DesktopH))
  132. //              rqData->Parm.BindCtx.dW->FullScreen (TRUE);
  133.           }
  134.           break;
  135.         }
  136.         case pmcmdUnbindDIVEctx:
  137.         {
  138.           if (!rqData->Parm.BindCtx.dW->Unbind (FALSE))
  139.           {
  140.             rc = pmrcNotBound;
  141.             break;
  142.           }
  143.           break;
  144.         }
  145.         case pmcmdShowWindow:
  146.         {
  147.           rqData->Parm.ShowWin.dW->Show (rqData->Parm.ShowWin.State);
  148.           break;
  149.         }
  150.         case pmcmdResizeWindow:
  151.         {
  152.           rqData->Parm.Resize.dW->Resize (rqData->Parm.Resize.Width,
  153.             rqData->Parm.Resize.Height, rqData->Parm.Resize.Center);
  154.           break;
  155.         }
  156.         case pmcmdLocateWindow:
  157.         {
  158.           rqData->Parm.Locate.dW->SetPos (rqData->Parm.Locate.x, rqData->Parm.Locate.y);
  159.           break;
  160.         }
  161.       }
  162.       if (rqData)
  163.       {
  164.         rqData->rc = rc;
  165.         DosPostEventSem (semSleep);
  166.       }
  167.       return NULL;
  168.     default:
  169.       return WinDefWindowProc (Handle, Message, MsgParm1, MsgParm2);
  170.   }
  171. }
  172.  
  173. void _Optlink PMthread (void *)
  174. {
  175. //  DosSetPriority (PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0);
  176.  
  177.   dA = new diveApp ();
  178.   if (dA)
  179.   {
  180.     PMmng = dA->CreateWindow (NULL, NULLHANDLE, 0, 0);
  181.     if (PMmng)
  182.     {
  183.       WinSubclassWindow (PMmng, PMmanager);
  184.       dA->Run ();
  185.       PMmng = NULLHANDLE;
  186.     }
  187.     delete dA;
  188.   }
  189. }
  190.  
  191. u_int PMcall (long Command, void *rq)
  192. {
  193.   ULONG tmp;
  194.   HWND pmt;
  195.   PMrq *req = (PMrq *) rq;
  196.  
  197.   if ((pmt = PMmng) == NULL)
  198.     return pmrcNotInitialized;
  199.   DosRequestMutexSem (semBusy, SEM_INDEFINITE_WAIT);
  200.   DosResetEventSem (semSleep, &tmp);
  201.   WinPostMsg (pmt, WM_DiveCommand, (MPARAM) Command, (MPARAM) rq);
  202.   DosWaitEventSem (semSleep, SEM_INDEFINITE_WAIT);
  203.   DosReleaseMutexSem (semBusy);
  204.   return req->rc;
  205. }
  206.  
  207. static bool QueryDIVE ()
  208. {
  209.   // Query DIVE capabilities and record supported resolutions & color depths
  210.   DIVE_CAPS DiveCaps;
  211.  
  212.   DiveCaps.pFormatData = NULL;
  213.   DiveCaps.ulFormatLength = 0;
  214.   DiveCaps.ulStructLen = sizeof (DIVE_CAPS);
  215.  
  216.   if (DiveQueryCaps (&DiveCaps, DIVE_BUFFER_SCREEN) != DIVE_ERR_INSUFFICIENT_LENGTH)
  217.     return FALSE;
  218.   DiveCaps.pFormatData = malloc (DiveCaps.ulFormatLength);
  219.   if (DiveQueryCaps (&DiveCaps, DIVE_BUFFER_SCREEN) != DIVE_SUCCESS)
  220.     return FALSE;
  221.  
  222.   DesktopW = DiveCaps.ulHorizontalResolution;
  223.   DesktopH = DiveCaps.ulVerticalResolution;
  224.   bool native;
  225.   for (u_int t = 0; t < 2; t++)
  226.   {
  227.     if (t > 0)
  228.       vmList = (FGVideoMode *) malloc (vmCount * sizeof (FGVideoMode));
  229.     vmCount = 0;
  230.     native = FALSE;
  231.     for (u_int i = 0; i < DiveCaps.ulInputFormats; i++)
  232.     {
  233.       FOURCC fcc = ((FOURCC *) DiveCaps.pFormatData)[i];
  234.       if (t == 1)
  235.       {
  236.         FGVideoMode *Mode = &vmList [vmCount];
  237.  
  238.         Mode->Width = DesktopW;
  239.         Mode->Height = DesktopH;
  240.         Mode->PixelFormat = fcc;
  241.         Mode->Buffers = DIVE_MAXBUFFERS;
  242.         Mode->Flags = vmfWindowed | vmfHardware2D | (DiveCaps.fccColorEncoding == fcc ? vmfNative : 0);
  243.         Mode->IndexBits = 0;
  244.       }
  245.       if (DiveCaps.fccColorEncoding == fcc)
  246.         native = TRUE;
  247.       vmCount++;
  248.     }
  249.  
  250.     // If native color format is not in supported list, add it anyway
  251.     if (!native)
  252.     {
  253.       if (t == 1)
  254.       {
  255.         FGVideoMode *Mode = &vmList [vmCount];
  256.  
  257.         Mode->Width = DesktopW;
  258.         Mode->Height = DesktopH;
  259.         Mode->PixelFormat = DiveCaps.fccColorEncoding;
  260.         Mode->Buffers = DIVE_MAXBUFFERS;
  261.         Mode->Flags = vmfWindowed | vmfHardware2D | vmfNative;
  262.         Mode->IndexBits = 0;
  263.       }
  264.       vmCount++;
  265.     }
  266.   }
  267.   free (DiveCaps.pFormatData);
  268.   return TRUE;
  269. }
  270.  
  271. bool gdDiveInitialize ()
  272. {
  273.   if (PMtid)
  274.     return TRUE;
  275.   if (!QueryDIVE ())
  276.     return FALSE;
  277.   PMtid = _beginthread (PMthread, NULL, 0x8000, NULL);
  278.   for (int i = 0; i < 100; i++)
  279.   {
  280.     DosSleep (30);
  281.     if (PMmng)
  282.     {
  283.       if (DosCreateMutexSem (NULL, (PHMTX) &semBusy, 0, FALSE))
  284.         return FALSE;
  285.       if (DosCreateEventSem (NULL, (PHEV) &semSleep, 0, FALSE))
  286.         return FALSE;
  287.       return TRUE;
  288.     }
  289.   }
  290.   return FALSE;
  291. }
  292.  
  293. bool gdDiveDeinitialize ()
  294. {
  295.   if (!PMtid)
  296.     return TRUE;
  297.   WinPostQueueMsg (dA->MQ, WM_QUIT, (MPARAM) 0, (MPARAM) 0);
  298.   DosWaitThread ((PTID) &PMtid, DCWW_WAIT);
  299.   DosCloseEventSem (semSleep);
  300.   DosCloseMutexSem (semBusy);
  301.   PMtid = 0;
  302.   return TRUE;
  303. }
  304.