/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = VVPTR.C
 *
 * DESCRIPTIVE NAME = Virtual Video Pointer Routines
 *
 *
 * VERSION = V2.0
 *
 * DATE      11/10/88
 *
 * DESCRIPTION  This module contains the VVD's pointer show/hide code.
 *
 * FUNCTIONS    VVShowPtr()           Show mouse pointer image
 *              VVHidePtr()           Hide mouse pointer image
 *              VVDefineTextPtr()     Text pointer definition
 *              VVDefineGraphPtr()    Pointer definition
 *              VVSetPtrPage()        Set video page on which to display
 *                                    pointer
 *              VVSetLPenEmulation()  Enable/disable light-pen emulation
 *              VVUpdatePtrContext()  Update VDM hardware cursor pointer in
 *                                    context
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/


#define  IO8BIT         /* CL386 Version 6.00.054 FLAG:                */
#include <mvdm.h>
#include <vvd.h>
#include "vvdp.h"

#ifdef   VDDSTRICT
MODNAME = __FILE__;
#endif
#pragma  BEGIN_SWAP_CODE

/***************************************************************************
 *
 * FUNCTION NAME = VVShowPtr()
 *
 * DESCRIPTION   = Show mouse pointer image
 *
 *                 This subroutine is registered with the virtual mouse
 *                 driver during creation of the first VDM, and causes the
 *                 currently defined pointer shape to appear on the screen
 *                 at the specified coordinates.
 *
 * INPUT         = hvdm -> VDM
 *                 xNew == new x-coordinate (always pixels, never cells)
 *                 yNew == new y-coordinate (always pixels, never cells)
 *
 * OUTPUT        = SUCCESS
 *                     TRUE
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL EXPENTRY VVShowPtr(HVDM hvdm,ULONG xNew,ULONG yNew)
{
  BOOL rc = TRUE;
  register PVDMDATA pvd = pVDMData(hvdm);


  if ((pvd->flVDMXVideo&(VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE)) ==
     (VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))
  {                                              /*                         */

    if (!pvd->PtrData.fPtrFrozenVideo)
    {
      RequestMutexSem(pvd->hmxVideoState);

      if (!pvd->PtrData.fPtrFrozenVideo)
        vvPtrDraw(hvdm,
                  xNew,
                  yNew);

      else
        rc = FALSE;
      ReleaseMutexSem(pvd->hmxVideoState);
    }

    if (!(pvd->PtrData.flPtrVideo&PTR_INTERNAL))
    {
      pvd->PtrData.xPtrVideo = xNew;
      pvd->PtrData.yPtrVideo = yNew;
      pvd->PtrData.flPtrVideo |= PTR_ACTIVE;
    }
    return  rc;                                  /*                         */
  }
  return  FALSE;                                 /*                         */
}

/***************************************************************************
 *
 * FUNCTION NAME = VVHidePtr()
 *
 * DESCRIPTION   = Hide mouse pointer image
 *
 *                 This subroutine is registered with the virtual mouse
 *                 driver during creation of the first VDM, and causes the
 *                 currently defined pointer shape to disappear from the
 *                 screen.  If the pointer is already disabled, nothing
 *                 happens.
 *
 * INPUT         = hvdm -> VDM
 *
 * OUTPUT        = SUCCESS
 *                     TRUE
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL EXPENTRY VVHidePtr(HVDM hvdm)
{
  BOOL rc = TRUE;
  register PVDMDATA pvd = pVDMData(hvdm);


  if ((pvd->flVDMXVideo&(VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE)) ==
     (VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))
  {                                              /*                         */

    if (!pvd->PtrData.fPtrFrozenVideo)
    {
      RequestMutexSem(pvd->hmxVideoState);

      if (!pvd->PtrData.fPtrFrozenVideo)
        vvPtrErase(hvdm);

      else
        rc = FALSE;
      ReleaseMutexSem(pvd->hmxVideoState);
    }

    if (!(pvd->PtrData.flPtrVideo&PTR_INTERNAL))
      pvd->PtrData.flPtrVideo &= ~PTR_ACTIVE;
    return  rc;                                  /*                         */
  }
  return  FALSE;                                 /*                         */
}

/***************************************************************************
 *
 * FUNCTION NAME = VVDefineTextPtr()
 *
 * DESCRIPTION   = Text pointer definition
 *
 *                 This subroutine is registered with the virtual mouse
 *                 driver during creation of the first VDM, and defines a
 *                 new pointer shape for specified VDM.
 *
 * INPUT         = hvdm      -> VDM
 *                 ulANDMask == the "screen" mask
 *                 ulXORMask == the "pointer" mask
 *                 fHW       == TRUE if hardware cursor to be used,
 *                              FALSE if not
 *
 * OUTPUT        = SUCCESS
 *                     TRUE
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL EXPENTRY VVDefineTextPtr(HVDM hvdm,ULONG ulANDMask,ULONG ulXORMask,BOOL
                               fHW)
{
  PORT port;
  register PVDMDATA pvd = pVDMData(hvdm);


  if (((pvd->flVDMXVideo&(VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE)) !=
     (VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))  /*                         */
#ifdef  GALE                                                            //J-TS00
     || (!pvd->flVDMGale && (pvd->mstateVideo > MEMORY_TEXT))           //J-TS00
     || (pvd->flVDMGale && ((pvd->ulBIOSMode != 0x03) &&                //J-TS00
                            (pvd->ulBIOSMode != 0x73))))                //J-TS00
#else   //GALE                                                          //J-TS00
     || (pvd->mstateVideo > MEMORY_TEXT))        /*                         */
#endif  //GALE                                                          //J-TS00
    return  FALSE;                               /*                         */


  if (fHW)
  {
    ulANDMask &= 0x0f;
    ulXORMask &= 0x0f;

#ifndef  SETDIRECT

    /*
    ** This method is preferable in that it takes cursor emulation
    ** by ROM into account;  the other method (ifdef'ed out) doesn't
    */

    *(PULONG)VDHQueryHookData(pvd->hhookUpdatePtrContext) = ulANDMask|
          ulXORMask << 8;

    if (!vdhBTS(&pvd->flVDMXVideo,
                LOG2(VDMX_PTRHOOK)))
      VDHArmContextHook(pvd->hhookUpdatePtrContext,
                        hvdm);

#else
    pvd->aregCRTData[REG_CRTCURSTSCAN] = (BYTE)ulANDMask;
    pvd->aregCRTData[REG_CRTCURENDSCAN] = (BYTE)ulXORMask;
    RequestMutexSem(pvd->hmxVideoState);

    if (pvd->flVDMVideo&VDM_FGND)
    {

   #ifndef  MONO
      port = PORT_COLRCRTINDX;
   #endif

   #ifdef   EGAVGA

      if (!(pvd->regMiscOut&MISCOUT_COLRPORTS))
   #endif

   #ifndef  CGA
           port = PORT_MONOCRTINDX;
   #endif
      OUTW(port,
           (ulANDMask << 8)|REG_CRTCURSTSCAN);
      OUTW(port,
           (ulXORMask << 8)|REG_CRTCURENDSCAN);
    }
    ReleaseMutexSem(pvd->hmxVideoState);
#endif
    pvd->PtrData.flPtrVideo |= PTR_HARDWARE;
    pvd->PtrData.flPtrVideo &= ~PTR_HWDIRTY;
    vvUpdateCursorData(hvdm);
  }

  else
  {

    if (pvd->PtrData.flPtrVideo&PTR_HARDWARE)    /*                         */
      pvd->PtrData.flPtrVideo &= ~(PTR_HARDWARE|PTR_DRAWN);/*               */
    pvd->PtrData.ulTextANDMaskVideo = ulANDMask;
    pvd->PtrData.ulTextXORMaskVideo = ulXORMask;
  }

  if (pVDMData(hvdm)->PtrData.flPtrVideo&PTR_ACTIVE)
  {
    pVDMData(hvdm)->PtrData.flPtrVideo |= PTR_INTERNAL;
    VVHidePtr(hvdm);
    VVShowPtr(hvdm,
              pVDMData(hvdm)->PtrData.xPtrVideo,
              pVDMData(hvdm)->PtrData.yPtrVideo);
    pVDMData(hvdm)->PtrData.flPtrVideo &= ~PTR_INTERNAL;
  }
  return  TRUE;
}

/***************************************************************************
 *
 * FUNCTION NAME = VVDefineGraphPtr()
 *
 * DESCRIPTION   = Pointer definition
 *
 *                 This subroutine is registered with the virtual mouse
 *                 driver during creation of the first VDM, and defines a
 *                 new pointer shape for specified VDM.
 *
 * INPUT         = hvdm   -> VDM
 *                 ausPtr -> 32-word pointer definition block
 *                 xHot   == x-coordinate of hot-spot
 *                 yHot   == y-coordinate of hot-spot
 *
 *                 Example of 32-word pointer definition block:
 *
 *                               +------------------------------+
 *                               |          15-----bits-----0   |
 *                               |Screen Mask                   |
 *                               | Word  0:  0011111111111111   |
 *                               | Word  1:  0001111111111111   |
 *                               | Word  2:  0000111111111111   |
 *                               | Word  3:  0000011111111111   |
 *                               | Word  4:  0000001111111111   |
 *                               | Word  5:  0000000111111111   |
 *                               | Word  6:  0000000011111111   |
 *                               | Word  7:  0000000001111111   |
 *                               | Word  8:  0000000000111111   |
 *                               | Word  9:  0000000000011111   |
 *                               | Word 10:  0000000111111111   |
 *                               | Word 11:  0001000011111111   |
 *                               | Word 12:  0011000011111111   |
 *                               | Word 13:  1111100001111111   |
 *                               | Word 14:  1111100001111111   |
 *                               | Word 15:  1111110001111111   |
 *                               |Pointer Mask                  |
 *                               | Word 16:  0000000000000000   |
 *                               | Word 17:  0100000000000000   |
 *                               | Word 18:  0110000000000000   |
 *                               | Word 19:  0111000000000000   |
 *                               | Word 20:  0111100000000000   |
 *                               | Word 21:  0111110000000000   |
 *                               | Word 22:  0111111000000000   |
 *                               | Word 23:  0111111100000000   |
 *                               | Word 24:  0111111110000000   |
 *                               | Word 25:  0111110000000000   |
 *                               | Word 26:  0110110000000000   |
 *                               | Word 27:  0100011000000000   |
 *                               | Word 28:  0000011000000000   |
 *                               | Word 29:  0000001100000000   |
 *                               | Word 30:  0000001100000000   |
 *                               | Word 31:  0000000000000000   |
 *                               +------------------------------+
 *
 * OUTPUT        = SUCCESS
 *                     TRUE
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 * PSEUDO-CODE
 *                 if pointer active
 *                   erase it
 *                 update shape definition
 *                 if pointer active
 *                   redraw it
 *
 ****************************************************************************/

BOOL EXPENTRY VVDefineGraphPtr(HVDM hvdm,USHORT ausMasks[],ULONG xHot,ULONG
                                yHot)
{

  if (((pVDMData(hvdm)->flVDMXVideo&(VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))
     != (VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))/*                        */
     || (pVDMData(hvdm)->mstateVideo == MEMORY_TEXT))/*                     */
    return  FALSE;                               /*                         */

  pVDMData(hvdm)->PtrData.xHotVideo = xHot;
  pVDMData(hvdm)->PtrData.yHotVideo = yHot;
  vvPtrSetMasks(hvdm,
                ausMasks);

  if (pVDMData(hvdm)->PtrData.flPtrVideo&PTR_ACTIVE)
  {
    pVDMData(hvdm)->PtrData.flPtrVideo |= PTR_INTERNAL;
    VVHidePtr(hvdm);
    VVShowPtr(hvdm,
              pVDMData(hvdm)->PtrData.xPtrVideo,
              pVDMData(hvdm)->PtrData.yPtrVideo);
    pVDMData(hvdm)->PtrData.flPtrVideo &= ~PTR_INTERNAL;
  }
  if (pVDMData(hvdm)->PtrData.flPtrVideo & PTR_HARDWARE)           /* DMH02 */
      pVDMData(hvdm)->PtrData.flPtrVideo &= ~(PTR_HARDWARE);       /* DMH02 */
  return  TRUE;
}

/***************************************************************************
 *
 * FUNCTION NAME = VVSetPtrPage()
 *
 * DESCRIPTION   = Set video page on which to display pointer
 *
 *                 This subroutine is registered with the virtual mouse
 *                 driver during creation of the first VDM, and allows the
 *                 mouse driver to select the video page on which the
 *                 pointer should be drawn.
 *
 *                 Rather interesting the DOS driver didn't architect this
 *                 function to to move the pointer if it was no longer on the
 *                 selected page....
 *
 * INPUT         = hvdm -> VDM
 *                 ulPage == video page #
 *
 * OUTPUT        = SUCCESS
 *                     TRUE
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL EXPENTRY VVSetPtrPage(HVDM hvdm,ULONG ulPage)
{

  if ((pVDMData(hvdm)->flVDMXVideo&(VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))
     != (VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))/*                        */
    return  FALSE;                               /*                         */

  pVDMData(hvdm)->PtrData.ulPtrPage = ulPage;
  return  TRUE;
}

/***************************************************************************
 *
 * FUNCTION NAME = VVSetLPenEmulation()
 *
 * DESCRIPTION   = Enable/disable light-pen emulation
 *
 *                 This subroutine is registered with the virtual mouse
 *                 driver during creation of the first VDM, and allows the
 *                 mouse driver to turn light pen emulation on/off.
 *
 * INPUT         = hvdm -> VDM
 *                 fEnable == TRUE to enable, FALSE to disable
 *
 * OUTPUT        = SUCCESS
 *                     TRUE
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

BOOL EXPENTRY VVSetLPenEmulation(HVDM hvdm,BOOL fEnable)
{

  if ((pVDMData(hvdm)->flVDMXVideo&(VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))
     != (VDMX_DEVOWNER|VDMX_DSPOWNER|VDMX_ACTIVE))/*                        */
    return  FALSE;                               /*                         */

  SETBIT(pVDMData(hvdm)->PtrData.flPtrVideo,
         PTR_LPENEM,
         fEnable);
  return  TRUE;
}

/***************************************************************************
 *
 * FUNCTION NAME = VVUpdatePtrContext()
 *
 * DESCRIPTION   = Update VDM hardware cursor pointer in context
 *
 * INPUT         = pulCursor == cursor type
 *                 pcrf      -> VDM register frame
 *
 * OUTPUT        = None
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

VOID HOOKENTRY VVUpdatePtrContext(register PULONG pulCursor,PCRF pcrf)
{

  if (!((PVVSTRING)(VDMData.pInt10ReturnData))->vva_nChars)
  {
    VDHPushRegs(VDHREG_AX|VDHREG_CX|VDHREG_BP);
    AH(pcrf) = INT10_SETCURSORTYPE;
    CH(pcrf) = (BYTE)(*pulCursor&0xff);
    CL(pcrf) = (BYTE)(*pulCursor >> 8);
    VDHPushInt(BIOSINT_VIDEO);
    ((PVVSTRING)(VDMData.pInt10ReturnData))->vva_nChars = -INT10_SETCURSORTYPE
       ;
    VDHArmReturnHook(VDMData.hhookInt10Return,
                     VDHARH_NORMAL_IRET);
  }
  VDMData.flVDMXVideo &= ~VDMX_PTRHOOK;
}

#pragma  END_SWAP_CODE

