/*////////////////////////////////////////////////////////////////////////
//                                                                      //
//              INTEL CORPORATION PROPRIETARY INFORMATION               //
//                                                                      //
//      This software is supplied under the terms of a license          //
//      agreement or nondisclosure agreement with Intel Corporation     //
//      and may not be copied or disclosed except in accordance         //
//      with the terms of that agreement.                               //
//                                                                      //
////////////////////////////////////////////////////////////////////////*/


/*******************************************************************
 *
 *      FILE:            dcientry.c
 *
 *    DESCRIPTION:    GDI entry points and DLL entry points for DCI Provider
 *
 *    AUTHOR:        Davis W. Frank
 *
 *      DATE:            3/18/1994
 *
 *******************************************************************/

#define NOGDI
#define NOGDIOBJ
#define NOGDICAPMASKS
#define WINVER 0x030A
#include <windows.h>
#include <dciddi.h>
#include "dcihdw.h"

#define NOPTRC
#define PTTYPE POINT
#include "gdidefs.inc"

#define QUERYESCSUPPORT         8

#ifdef _DEBUG
#define ODS    OutputDebugString
#else
#define ODS(x)
#endif


/* PDEVICE structure to be passed back to GDI */
typedef struct {
    UINT    type;        // must be != 0
    UINT    count;        // number of people who have my surface.
}   PDEVICE;

/* Globals */
BOOL fHardwareSupport;
WORD Selector;
BYTE gHdwCur=0;


/* DCI Command functions */
int    FAR PASCAL _loadds DCICreatePrimarySurface(LPVOID, LPVOID);
int    FAR PASCAL _loadds DCIEnumSurface(LPVOID, LPVOID);
int    FAR PASCAL _loadds DCICreateOffScreenSurface(LPVOID, LPVOID);


/* Defined in CBLIT.ASM, needed for MakeCode32()  */
void FAR cblitLines( WORD, LPDWORD, DWORD, WORD, LPDWORD, DWORD, CLIPRECTINFO FAR *, DWORD );

/*
 ** Enable()
 *
 *  Parameters:        lpDevice        place holder DWORD for a FAR * PDEVICE
 *                    style            either InquireInfo or EnableDevice
 *                    lpDeviceType    unused
 *                    lpOutput        unused
 *                    lpStuff            unused
 *
 *  Description:    called when GDI loads DCISAMP after DC is created.  Does
 *                    necessary things do GDI will call Control() when Escape is
 *                    called.  Has nothing to do w/ DCI functionality other than
 *                    loading driver.
 *
 *  Returns:        sizeof(GDIINFO) when InquireInfo
 *
 *    Side Effects:    none
 */
UINT FAR PASCAL _loadds Enable( LPVOID  lpDevice, 
                                UINT    style, 
                                LPSTR   lpDeviceType, 
                                LPSTR   lpOutput,
                                LPVOID  lpStuff)
{
    if (style == InquireInfo)
    {
        GDIINFO FAR *pdp = (GDIINFO FAR *)lpDevice;

        pdp->dpVersion            = 0x30A;
        pdp->dpTechnology         = DT_RASDISPLAY;
        pdp->dpHorzSize           = 1;
        pdp->dpVertSize           = 1;
        pdp->dpHorzRes            = 1;
        pdp->dpVertRes            = 1;
        pdp->dpBitsPixel          = 1;
        pdp->dpPlanes             = 1;
        pdp->dpNumBrushes         = -1;
        pdp->dpNumPens            = -1;
        pdp->dpNumFonts           = -1;
        pdp->dpNumColors          = -1;
        pdp->dpDEVICEsize         = sizeof(PDEVICE);
        pdp->dpCurves             = 0; /* CC_NONE */
        pdp->dpLines              = 0; /* LC_NONE */
        pdp->dpPolygonals         = 0; /* PC_NONE */
        pdp->dpText               = 0; /* TC_NONE */
        pdp->dpClip               = 0; /* CC_NONE */
        pdp->dpRaster             = 0; /* RC_NONE */
        pdp->dpAspectX            = 1;
        pdp->dpAspectY            = 1;
        pdp->dpAspectXY           = 1;
        pdp->dpStyleLen           = 1;
        pdp->dpMLoWin.x           = 1;
        pdp->dpMLoVpt.x           = 1;
        pdp->dpMHiWin.x           = 1;
        pdp->dpMHiVpt.x           = 1;
        pdp->dpELoWin.x           = 1;
        pdp->dpELoVpt.x           = 1;
        pdp->dpEHiWin.x           = 1;
        pdp->dpEHiVpt.x           = 1;
        pdp->dpTwpWin.x           = 1;
        pdp->dpTwpVpt.x           = 1;
        pdp->dpMLoWin.y           = 1;
        pdp->dpMLoVpt.y           = 1;
        pdp->dpMHiWin.y           = 1;
        pdp->dpMHiVpt.y           = 1;
        pdp->dpELoWin.y           = 1;
        pdp->dpELoVpt.y           = 1;
        pdp->dpEHiWin.y           = 1;
        pdp->dpEHiVpt.y           = 1;
        pdp->dpTwpWin.y           = 1;
        pdp->dpTwpVpt.y           = 1;
        pdp->dpLogPixelsX         = 1;
        pdp->dpLogPixelsY         = 1;
        pdp->dpDCManage           = DC_IgnoreDFNP;
        pdp->dpCaps1              = 0;

        return sizeof(GDIINFO);
    }
    else /*style == EnableDevice*/
    {
        PDEVICE FAR *pd = (PDEVICE FAR *)lpDevice;

        pd->type = 42;      /* mark as a physical device for GDI */
        pd->count = 0;

        return 1;            /* success */
    }
} /* Enable */


/*
 ** Control()
 *
 *  Parameters:     lpDevice    PDEVICE passed from DC -- not used
 *                    function    the constant DCICOMMAND
 *                    lParam1        FAR pointer to Input structure
 *                    lParam2        FAR pointer to FAR pointer to DCI Provider's return
 *                                    structure
 *
 *  Description:     This function is called whenever a DCI Client or Manager calls the
 *                    GDI Escape call for the DCI device context. It routes
 *                     to other DCI Provider commands based on the dwCommand field of the
 *                     lpInput passed in as lParam1.
 *
 *  Returns:         Control passes up the DCI Status code returned from the DCI command 
 *                     functions.
 *
 *    Side Effects:    lParam2 is a FAR pointer to a DWORD. It is the responsibility 
 *                    of the DCI Provider to return, in this DWORD, a FAR pointer to 
 *                    a structure that contains the appropriate DCI structure plus 
 *                    any instance information needed at Callback time by the Provider.
 * 
 */
LONG FAR PASCAL _loadds Control( LPVOID lpDevice, 
                                 UINT   function,  
                                 LPVOID lParam1,  
                                 LPVOID lParam2 )
{                
   int  rval;
    
    
    switch (function)
    {
        case QUERYESCSUPPORT:
            
            switch (*((UINT FAR *)lParam1))
            {
                case QUERYESCSUPPORT:
                    return TRUE;        

                case DCICOMMAND:                
                    return TRUE;
        
                default:
                    return FALSE; 
            }
            
        case DCICOMMAND:
        
            if (((LPDCICREATEINPUT)lParam1)->cmd.dwVersion != 0x0100L)
                return (LONG)DCI_FAIL_UNSUPPORTED;
        
            switch (((LPDCICREATEINPUT)lParam1)->cmd.dwCommand)
            {
                case DCICREATEPRIMARYSURFACE:    
                    rval = DCICreatePrimarySurface(lParam1,lParam2);
                    break;

                case DCICREATEOFFSCREENSURFACE:     
                    rval = DCICreateOffScreenSurface(lParam1,lParam2);
                    break;
                       
                case DCIENUMSURFACE:
                    rval = DCIEnumSurface(lParam1,lParam2);
                    break;

                case DCIESCAPE:                     
                case DCICREATEOVERLAYSURFACE:
                default:
                    return (LONG)DCI_FAIL_UNSUPPORTED;                
            }
            break;
            
        default:
            return FALSE;
    }
    
    return (LONG)rval;
} /* Control */

/*
 ** Disable()
 *
 *  Parameters:        lpDevice    PDEVICE from DC -- not used
 *
 *  Description:    Needed for Provider as Display Driver model. Does nothing
 *
 *  Returns:        TRUE
 *
 *    Side Effects:    none
 */
DWORD FAR PASCAL _loadds Disable( LPVOID  lpDevice )
{          
    PDEVICE FAR *pd = (PDEVICE FAR *)lpDevice;

    return TRUE;
}

/* */
void MarkCode32(short selCode16)
{
    BYTE    desc[8];

#define DSC_DEFAULT     0x40
#define dsc_access      6

    _asm
    {
        /* int 3 */
        mov     bx, selCode16       ; bx = selector

        lea     di, word ptr desc   ; ES:DI --> desciptor
        mov     ax,ss
        mov     es,ax

        mov     ax, 000Bh           ; DPMI get descriptor
        int     31h

        ; set DEFAULT bit to make it a 32-bit code segment
        or      desc.dsc_access,DSC_DEFAULT

        mov     ax,000Ch            ; DPMI set descriptor
        int     31h
    }
}

void MakeCode32(short selCode16)
{
    GlobalReAlloc((HGLOBAL)selCode16, 0, GMEM_MODIFY|GMEM_MOVEABLE);

    MarkCode32(selCode16);
}


/******************************************************************************
   FUNCTION: LibMain(HANDLE, WORD, WORD, LPSTR)

   ALL dll initializations happen here; we have nothing to do.
******************************************************************************/
int FAR PASCAL LibMain (HANDLE hModule, WORD wDataSeg, WORD cbHeapSize,
                         LPSTR lpszCmdLine)
{
   ODS("dcisamp.dll: LibMain()\n");

   if (cbHeapSize > 0)
      UnlockData(0);

   MakeCode32(SELECTOROF(cblitLines));
   // Initialize the video hardware support
   fHardwareSupport = VidInitialize ();
   return 1;
}


/******************************************************************************
    FUNCTION:   WEP(int)

    ALL cleanups here.
******************************************************************************/
int CALLBACK _WEP (int bSystemExit);
#pragma alloc_text(WEP_TEXT, _WEP)

int CALLBACK _WEP (int bSystemExit)
{
   // Allow hardware support cleanup
   VidWEP ();

   return 1;
}