
/*------------------------------------------------------------------*
 *                                                                  *
 *  Video Toolkit For OS/2 Version 2.0                              *
 *  Example PM Application No. 1                                    *
 *  Date : 22/02/95.                                                *
 *  Copyright (c) Abbotsbury Software Ltd., United Kingdom. 1995-98 *
 *                                                                  *
 *  Filename : ex1.c                                                *
 *                                                                  *
 *------------------------------------------------------------------*/

#define INCL_PM

#include <os2.h>
#include <os2me.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vcadd.h>
#include <vcai.h>
#include "ex1.h"
#include "helpfunc.h"


                            // The following external variable is imported
                            // from a DLL called VIDIPF (the binary of which
                            // is contained in the DLL sub-directory of the
                            // toolkit). The VIDIPF DLL allows the TV to be
                            // displayed within a help window, but it requires
                            // 1 piece of information. This is :-
                            //
                            //   1. Calling app window handle - for sending
                            //      an update message to the app when the
                            //      help window is closed.
// extern  HWND    HwndApp;

HWND    HwndFrame;

static  UCHAR   *Copyright =
  "Copyright (c) Abbotsbury Software Ltd., UK. 1994-1998. All Rights Reserved";
static  HAB     Hab;
static  LONG    NumColours, Width, Height;
static  LONG    Colours[256];
static  VCADEVINFO  DevInfo;
static  CHAR    txt[256];
static  DRIVERHANDLE    DevHandle;

int     main(int argc, char **argv);
void    msg_box (UCHAR *txt, UCHAR *title, ULONG options);
void    err_msg (UCHAR *mess);
MRESULT EXPENTRY ClientWndProc (HWND, ULONG, MPARAM, MPARAM);
MRESULT EXPENTRY QuitDlgProc (HWND, ULONG, MPARAM, MPARAM);
MRESULT EXPENTRY AboutDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);

static  void    init_colour (void);
static  LONG    get_colour (HPS hps);
static  void    map_pallete (HPS hps);

int main (int argc, char **argv)
{
    CHAR    szClient[] = "Client";
    ULONG   flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_ACCELTABLE |
                           FCF_SIZEBORDER | FCF_MINMAX | FCF_ICON |
                           FCF_SHELLPOSITION | FCF_TASKLIST;
    HMQ     hmq;
    QMSG    qmsg;
    USHORT  dev_instance;
    CHAR    dev_type[20];
    HWND    hwndClient;

        if (argc < 3)
            DosExit (EXIT_PROCESS, 1);

        Hab = WinInitialize (0);
        if (!Hab)
            DosExit (EXIT_PROCESS, 1);

        hmq = WinCreateMsgQueue (Hab, 0);
        if (!hmq)
            DosExit (EXIT_PROCESS, 1);

        strcpy (dev_type, argv[1]);
        dev_instance = (USHORT)atoi (argv[2]);
        DevHandle = VcaiDeviceOpen (dev_type, dev_instance);
        if (DevHandle < 0)
        {
            sprintf (txt, "Cannot Open Device %u !", atoi (argv[2]));
            msg_box (txt, "Error", MB_OK | MB_ERROR);
            DosExit (EXIT_PROCESS, 1);
        }

        VcaiWCastMonitor (800, 600, "");

        WinRegisterClass (Hab, szClient, ClientWndProc,
                          CS_SIZEREDRAW | CS_MOVENOTIFY, 0);

        sprintf (txt, "Example 1 - %s %u", dev_type, dev_instance);

        HwndFrame = WinCreateStdWindow (HWND_DESKTOP,
                                        WS_VISIBLE,
                                        &flFrameFlags,
                                        szClient,
                                        txt,
                                        0L,
                                        (HMODULE)NULLHANDLE,
                                        IDR_MAIN,
                                        &hwndClient);
        if (!HwndFrame)
            return 0;

                                // Setup the HwndApp variable exported by the
                                // VIDIPF DLL which allows the application
                                // window to be updated once the help window
                                // containing the TV is closed.
//        HwndApp = HwndFrame;

        DevInfo.Length = sizeof (VCADEVINFO);

        VcaiDeviceInfoGet (&DevInfo);

        HelpInit (HwndFrame);

        WinSetWindowPos (HwndFrame, NULLHANDLE, 20, 20, 256, 256, 0);

        while (WinGetMsg (Hab, &qmsg, NULLHANDLE, 0, 0))
            WinDispatchMsg (Hab, &qmsg);

        DestroyHelpInstance ();
        WinDestroyWindow (HwndFrame);
        WinDestroyMsgQueue (hmq);
        WinTerminate (Hab);
        DosExit (EXIT_PROCESS, 0);
}

void msg_box (UCHAR *txt, UCHAR *title, ULONG options)
{
        WinMessageBox (HWND_DESKTOP,
                       HWND_DESKTOP,
                       txt,
                       title,
                       IDD_MSG,
                       options);
}

void err_msg (UCHAR *mess)
{
    ERRORID err;
    UCHAR   txt[256];

        err = WinGetLastError (Hab);
        sprintf (txt, "%s - %lx", mess,  err & 0xffff);
        msg_box (txt, "Error", MB_OK | MB_ERROR);
}

MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
    static  BOOL minimize = FALSE;
    static  HWND hwnd_menu;
    HPS     hps;
    RECTL   rcl;
    LONG    bx, by, cy, x, y, ck;
    BOOL    success;
    PSWP    pswp;
    FILE *fd;

        switch(msg)
        {
            case WM_CREATE :
                VcaiOverlay (TRUE);
                VcaiFreeze (FALSE);
                init_colour ();
                hwnd_menu = WinLoadMenu (hwnd, NULLHANDLE, IDR_MAIN);
                break;
            case WM_PAINT :
                WinSetWindowPos (hwnd, NULLHANDLE, 20, 20, 256, 256, 0);
                hps = WinBeginPaint (hwnd, NULLHANDLE, &rcl);
                WinQueryWindowRect (hwnd, &rcl);
                ck = get_colour (hps);
                if ((ULONG)NumColours <= 256)
                    WinFillRect (hps, &rcl, Colours[ck]);
                else
                    WinFillRect (hps, &rcl, ck);
                WinEndPaint (hps);
                break;
            case MSG_SIZE_TV :
            case WM_SIZE :
            case WM_MOVE :
            case WM_WINDOWPOSCHANGED :
                if (minimize)
                    break;
                success = WinQueryWindowRect (hwnd, &rcl);
                if (!success)
                    return 0;
                WinMapWindowPoints (hwnd, HWND_DESKTOP, (PPOINTL)&rcl, 2);
                bx = WinQuerySysValue (HWND_DESKTOP, SV_CXSIZEBORDER);
                by = WinQuerySysValue (HWND_DESKTOP, SV_CYSIZEBORDER);
                cy = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);
                x      = rcl.xLeft + bx;
                y      = cy - rcl.yTop - by;
                Width  = rcl.xRight - rcl.xLeft;
                Height = rcl.yTop - rcl.yBottom;
                VcaiVideoRectValidate (0, 0, 0, 0, (USHORT)x, (USHORT)y,
                                       (USHORT)Width, (USHORT)Height);

                break;
            case WM_MINMAXFRAME :
                pswp = (PSWP)PVOIDFROMMP (mp1);
                if (!(pswp->fl & SWP_MINIMIZE))
                {
                    minimize = FALSE;
                    break;
                }
                minimize = TRUE;
                VcaiVideoRectValidate (0, 0, 0, 0, 0, 0, 0, 0);
                break;

            case WM_BUTTON2CLICK :
                WinPopupMenu (hwnd, hwnd, hwnd_menu,
                              MOUSEMSG (&msg)->x, MOUSEMSG (&msg)->y, 0L,
                              PU_HCONSTRAIN | PU_VCONSTRAIN |
                              PU_NONE | PU_MOUSEBUTTON1 |
                              PU_KEYBOARD);
                return 0;

            case WM_CLOSE :
                VcaiDeviceClose (DevHandle);
                break;

            case WM_COMMAND :
                switch (SHORT1FROMMP (mp1))
                {
                    case IDM_FILE_QUIT :
                        WinDlgBox (HWND_DESKTOP,
                                   HwndFrame,
                                   (PFNWP)QuitDlgProc,
                                   (HMODULE)NULLHANDLE,
                                   IDD_QUIT,
                                   NULL);
                        WinInvalidateRegion (HwndFrame, NULLHANDLE, FALSE);
                        break;
                    case IDM_HELPCONTENTS :
                        HelpContents ();
                        break;
                    case IDM_HELPINDEX :
                        HelpIndex ();
                        break;
                    case IDM_KEYSHELP :
                        HelpKeys ();
                        break;
                    case IDM_GENERALHELP :
                        HelpHelpForHelp ();
                        break;
                    case IDM_HELPPRODUCTINFO :
                        HelpAbout ();
                        break;
                    default :
                        break;
                }
            case HM_QUERY_KEYS_HELP :
                return ((MRESULT)PANEL_KEYSHELP);
            case MSG_UPDATE_WINDOW :
                WinQueryWindowRect (hwnd, &rcl);
                WinInvalidateRect (hwnd, &rcl, TRUE);
                VcaiDeviceConnect (DevHandle);
                WinPostMsg (hwnd, MSG_SIZE_TV, NULL, NULL);
                return 0;
            default :
                break;
        }
        return WinDefWindowProc (hwnd,msg,mp1,mp2);
}

MRESULT EXPENTRY QuitDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
        switch (msg)
        {
            case WM_COMMAND :
                switch (SHORT1FROMMP (mp1))
                {
                    case DID_OK :
                        WinPostMsg (HwndFrame, WM_CLOSE, NULL, NULL);
                        WinDismissDlg (hwnd, TRUE);
                        break;
                    case DID_CANCEL :
                        WinDismissDlg (hwnd, TRUE);
                        break;
                    default :
                        break;
                }
                break;
            default :
                break;
        }
        return WinDefDlgProc (hwnd, msg, mp1, mp2);
}

MRESULT EXPENTRY AboutDlgProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
    HPS     hps;
    RECTL   rcl;
    LONG    x, y;
    CHAR    txt[80];

        switch (msg)
        {
            case WM_PAINT :
                hps = WinBeginPaint (hwnd, NULLHANDLE, &rcl);
                WinQueryWindowRect (hwnd, &rcl);
                WinFillRect (hps, &rcl, CLR_PALEGRAY);
                sprintf (txt, "%30.30s", DevInfo.ProdInfo);
                WinSetDlgItemText (hwnd, IDD_ABOUT_PROD_INFO, txt);
                sprintf (txt, "%30.30s", DevInfo.ManInfo);
                WinSetDlgItemText (hwnd, IDD_ABOUT_MAN_INFO, txt);
                sprintf (txt, "%10.10s", DevInfo.Version);
                WinSetDlgItemText (hwnd, IDD_ABOUT_VERSION, txt);
                WinDrawBorder (hps, &rcl, x, y, 0L, 0L, DB_AREAATTRS |
                               DB_DLGBORDER);
                WinEndPaint (hps);
                break;
            case WM_COMMAND :
                switch (SHORT1FROMMP (mp1))
                {
                    case DID_OK :
                        WinDismissDlg (hwnd, TRUE);
                        break;
                    default :
                        break;
                }
                break;
            default :
                break;
        }
        return WinDefDlgProc (hwnd, msg, mp1, mp2);
}

static void init_colour ()
{
    HDC     hdc;
    DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL,
                        NULL};

        hdc = DevOpenDC (Hab, OD_INFO, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
        DevQueryCaps (hdc, CAPS_COLORS, 1L, &NumColours);
        DevCloseDC (hdc);
}

                        // The colour value for the Video Colour Key
                        // is a physical palette value.
                        // For systems with 256 or less colours in the
                        // palette, you MUST map the physical palette
                        // to PM logical palette first.
                        // If there are more than 256 colours this
                        // step should be ignored.
static LONG get_colour (HPS hps)
{
    LONG index;

        map_pallete (hps);

        index = VcaiColourkeyGet();
        if (index > (ULONG)NumColours)
        {
            index = COLOUR_KEY_DEFAULT;
            VcaiColourkeySet (index);
        }
        return (LONG)index;
}

static void map_pallete (HPS hps)
{
    LONG    rc;
    VCASCREENINFO vs;
    USHORT cx, cy, i;

        if ((ULONG)NumColours <= 256)
        {
            rc = GpiQueryRealColors (hps, 0L, 0L, NumColours, Colours);
            if (rc == GPI_ALTERROR)
            {
                err_msg ("GpiQueryRealColors");
                return;
            }
        }
        cx = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN);
        cy = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);
        vs.ulLength = sizeof (VCASCREENINFO);
        vs.ul_RESV01 = 0L;
        vs.ulWidth = (ULONG)cx;
        vs.ulHeight = (ULONG)cy;
        vs.ulNumColours = (ULONG)NumColours;
        vs.ulHFreq = 0L;
        vs.ulVFreq = 0L;
        if ((ULONG)NumColours <= 256)
        {
            for (i = 0; i < NumColours; i++)
                vs.ulRGB[i] = (ULONG)Colours[i];
        }
        else
        {
            for (i = 0; i < 256; i++)
                vs.ulRGB[i] = 0L;
        }
        VcaiScreenInfoSet (&vs);
        rc = GpiCreateLogColorTable (hps, LCOL_RESET, LCOLF_RGB,
                                     0L, 0L, (PLONG)0L);
        if (!rc)
        {
            err_msg ("GpiCreateLogColorTable");
            return;
        }
}
