/**************************************************************************
 *
 * SOURCE FILE NAME = VMBOUND.C
 *
 * DESCRIPTIVE NAME = Virtual Mouse Device Driver Int 33h Boundary Services
 *
 * Copyright : COPYRIGHT IBM CORPORATION, 1991, 1992
 *             Copyright Microsoft Corporation, 1990
 *             LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
 *             REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
 *             RESTRICTED MATERIALS OF IBM
 *             IBM CONFIDENTIAL
 *
 * VERSION =   V2.0
 *
 * DATE        07/18/91
 *
 * DESCRIPTION This module contains the VMD's Int 33h boundary services.
 *
 *
 * FUNCTIONS
 *
 *   vmInt33SetHorizontal()  Int 33h Set Horizontal Bounds (function 7)
 *   vmInt33SetVertical()    Int 33h Set Vertical Bounds (function 8)
 *   vmInt33SetConditional() Int 33h Set Conditional-Off Bounds (function 16)
 *
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
 * CHANGE ACTIVITY =
 *  DATE      FLAG        APAR   CHANGE DESCRIPTION
 *  --------  ----------  -----  --------------------------------------
 *  mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
 *  01/31/89  @V2.0JTP01  JTP     Created.
 *  (7/18/91) @V2.0JCI01  JC      SPECIAL NOTE
 *
 ************************************************************************/

#include "vmdp.h"

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

/****************************************************************************
 *
 * FUNCTION NAME = vmInt33SetHorizontal()
 *
 * DESCRIPTION   = Int 33h Set Horizontal Bounds (function 7)
 *
 *
 * INPUT         = pcrf -> VDM register frame
 *
 * OUTPUT        = EMULATED
 *                     TRUE
 *                 NOT EMULATED
 *                     FALSE (pass control to next VDD and/or ROM)
 *
 * RETURN-NORMAL = NONE
 *
 * RETURN-ERROR  = NONE
 *  SPECIAL NOTE: If the application tries to set a boundary to a value
 *                that is greater then what we perceive to be the upper
 *                limit, we will LET the app do it. If we don't let this
 *                happen, then applications like Flight Simulater and
 *                PC Paint would have their mouse pointer restricted to
 *                some area of the workspace. The reason is that these
 *                applications program the video by directly manipulating
 *                the hardware and can set the mode without VMOUSE ever
 *                knowing. VMOUSE gets mode change information via VVID.
 *                VVID only knows about INT 10H mode changes. I think at
 *                some point VVID should become smarter about direct
 *                hardware manipulation. @V2.0JCI01
 *
 *
 *
 ***************************************************************************
 *  PSEUDO-CODE                                     REFERENCES
 *      if min > max
 *          swap min and max;
 *      convert virtual coordinates to screen coordinates;
 *      make sure min and max are within screen size;
 *      round down min to cell boundary;
 *      round down max to cell boundary;
 *      if 320x200 mode
 *          make min and max even values;
 *      store min and max value;
 *      call vmSetPosition to make sure cursor is in new boundaries;
 *
 **************************************************************************/

BOOL PRIVENTRY vmInt33SetHorizontal(register PCRF pcrf)
{
  register LONG xMin,xMax;

  if ( (SHORT)CX(pcrf) > (SHORT)DX(pcrf) )
  {
    xMin = (SHORT)DX(pcrf);
    xMax = (SHORT)CX(pcrf);
  }
  else
  {
    xMin = (SHORT)CX(pcrf);
    xMax = (SHORT)DX(pcrf);
  }

  xMin >>= VDMData.fShiftX;
  xMax >>= VDMData.fShiftX;
  VDMData.mstates.xMin = xMin > 0?xMin:0;

 /*
 **  if ( xMax >= VDMData.vmss.vmss_ulWidth )
 **      xMax = VDMData.vmss.vmss_ulWidth - 1;
 */

  VDMData.mstates.xMax = xMax;

  vmSetPosition(CURRENT_VDM, vmBoundedX(CURRENT_VDM,
                             VDMData.mstates.xCur),
                             vmBoundedY(CURRENT_VDM,
                             VDMData.mstates.yCur),
                             TRUE                    );

  return  TRUE;

}                                      /* vmInt33SetHorizontal               */




/****************************************************************************
 *
 * FUNCTION NAME = vmInt33SetVertical()
 *
 * DESCRIPTION   = Int 33h Set Vertical Bounds (function 8)
 *
 *
 * INPUT         = Entry - pcrf -> VDM register frame
 *
 * OUTPUT        = Exit -  EMULATED
 *                             TRUE
 *                         NOT EMULATED
 *                             FALSE (pass control to next VDD and/or ROM)
 *
 *
 * RETURN-NORMAL = NONE
 *
 * RETURN-ERROR  = NONE
 *
 *
 *  USES
 *      32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT
 *      VDM Task-time
 *
 *  SPECIAL NOTE: Same as in vmInt33SetHorizontal
 *
 ****************************************************************************
 *  PSEUDO-CODE                                     REFERENCES
 *      if min > max
 *          swap min and max;
 *      convert virtual coordinates to screen coordinates;
 *      make sure min and max are within screen size;
 *      round down min to cell boundary;
 *      round down max to cell boundary;
 *      store min and max value;
 *      call vmSetPosition to make sure cursor is in new boundaries;
 ****************************************************************************/

BOOL PRIVENTRY vmInt33SetVertical(register PCRF pcrf)
{
  register LONG yMin,yMax;

  if ( (SHORT)CX(pcrf) > (SHORT)DX(pcrf) )
  {
    yMin = (SHORT)DX(pcrf);
    yMax = (SHORT)CX(pcrf);
  }
  else
  {
    yMin = (SHORT)CX(pcrf);
    yMax = (SHORT)DX(pcrf);
  }
  if ( VDMData.vmss.vmss_ulCellHeight != 1 )
  {                                   /* text mode                           */
    yMin = (LONG)(yMin *VDMData.vmss.vmss_ulCellHeight)/8;
    yMax = (LONG)(yMax *VDMData.vmss.vmss_ulCellHeight)/8;
  }
  VDMData.mstates.yMin = yMin > 0?yMin:0;

  /*
  **  if ( yMax >= VDMData.vmss.vmss_ulHeight )
  **      yMax = VDMData.vmss.vmss_ulHeight - 1;
  */

  VDMData.mstates.yMax = yMax;

  vmSetPosition( CURRENT_VDM, vmBoundedX ( CURRENT_VDM,
                              VDMData.mstates.xCur ),
                              vmBoundedY( CURRENT_VDM,
                              VDMData.mstates.yCur ),
                              TRUE                     );
  return  TRUE;

}                                      /* vmInt33SetVertical                 */



/****************************************************************************
 *
 * FUNCTION NAME = vmInt33SetConditional()
 *
 * DESCRIPTION   = Int 33h Set Conditional-Off Bounds (function 16)
 *
 *
 * INPUT         = Entry  pcrf -> VDM register frame
 *
 * OUTPUT        = Exit EMULATED
 *                          TRUE
 *                      NOT EMULATED
 *                          FALSE (pass control to next VDD and/or ROM)
 *
 *
 * RETURN-NORMAL = NONE
 *
 * RETURN-ERROR  = NONE
 *
 *
 *          FALSE (pass control to next VDD and/or ROM)
 *  USES
 *      32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT
 *      VDM Task-time
 *
 ************************************************************************
 *  PSEUDO-CODE                                     REFERENCES
 *      convert virtual coordinates to screen coordinates;
 *      store conditional off coordinates;
 *      enable conditional off and init. flags;
 *      call vmSetPosition to determine if we should hide the cursor;
 *************************************************************************/

BOOL PRIVENTRY vmInt33SetConditional(register PCRF pcrf)
{
  VDMData.mstates.xMinOff = (SHORT)CX(pcrf) >> VDMData.fShiftX;
  VDMData.mstates.xMaxOff = (SHORT)SI(pcrf) >> VDMData.fShiftX;

  if ( VDMData.vmss.vmss_ulCellHeight == 1 )
  {                                   /* graphics mode                       */
    VDMData.mstates.yMinOff = (SHORT)DX(pcrf);
    VDMData.mstates.yMaxOff = (SHORT)DI(pcrf);
  }
  else
  {                                   /* text mode                           */
    VDMData.mstates.yMinOff =
       (LONG)( (SHORT)DX(pcrf) * VDMData.vmss.vmss_ulCellHeight )/8;
    VDMData.mstates.yMaxOff =
       (LONG)( (SHORT)DI(pcrf) * VDMData.vmss.vmss_ulCellHeight )/8;
  }

  VDMData.mstates.fOffEnable = TRUE;
  VDMData.mstates.fInOffRegion = FALSE;
  vmSetPosition ( CURRENT_VDM,
                  VDMData.mstates.xCur,
                  VDMData.mstates.yCur,
                  TRUE                  );

  return  TRUE;
}                                     /* vmInt33SetConditional               */
#pragma  END_SWAP_CODE
