/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft Corporation, 1989                                 */
/* 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 = VMSYSRQ.C
 *
 * DESCRIPTIVE NAME = Virtual Mouse System Request Processing  
 *
 *
 * VERSION = V2.0
 *
 * DATE      11/03/91
 *
 * DESCRIPTION This module contains the VMSE's DosRequestVDD support. 
 *             
 *
 * FUNCTIONS   
 *
 *             VMSysReqProc()      DosRequestVDD router              
 *             vmSysSetAccess()    Request/release VDM event access  
 *             vmSysSetFocus()     Set/clear focus
 *             vmSysPostMouse()    Post a mouse event to the VDM     
 *
 * ENTRY POINTS: 
 *
 * DEPENDENCIES:  
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/
#include "vmdp.h"

#ifdef   VDDSTRICT
MODNAME = __FILE__;
#endif

#define  INCL_DOSERRORS
#include <bseerr.h>
#define  APIENTRY      _syscall
#define  APIRET        ULONG

#define  INCL_MOU
#include <bsesub.h>
typedef MOUEVENTINFO *PME;
#define  INVALID_HVDM  ((HVDM)-2)

/*
**    External References
*/

/*
** INSTANCE_DATA
*/

extern BOOL fMouseEnabled;
extern ULONG fsstate;
extern LONG ulsgCapture;

/*
** GLOBAL_DATA
*/

extern USHORT usMouExclusive;


#pragma  BEGIN_SWAP_CODE

 /***************************************************************************
 *
 * FUNCTION NAME : VMSysReqProc() 
 *
 * DESCRIPTION   : DosRequestVDD router
 *
 *  This subroutine is registered during VDD initialization via
 *  VDHRegisterVDD, and receives requests from OS/2 applications.
 *
 *  INPUT   :
 *             sgid   == screen group
 *             ulFunc == function code
 *             nbIn   -> input buffer size (0 if none)
 *             pIn    -> input buffer
 *             nbOut  -> output buffer size (0 if none)
 *             pOut   -> output buffer
 *  OUTPUT   :
 *             SUCCESS
 *                 Zero
 *             FAILURE
 *                 Error code (ie, invalid function, etc)
 *  USES     :
 *             32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT  :
 *             Task-time
 *
 *  PSEUDO-CODE                                     REFERENCES
 *      based on function code                          ulFunc
 *        route to appropriate worker function
 *
 ***************************************************************************/

LONG EXPENTRY VMSysReqProc(SGID sgid,ULONG ulFunc,ULONG nbIn,PVOID pIn,ULONG 
                            nbOut,PVOID pOut)
{
  HVDM hvdm = INVALID_HVDM;
  if (sgid)
  {
    hvdm = VDHHandleFromSGID(sgid);
    if (!hvdm)
      hvdm = INVALID_HVDM;
  } 
  switch (ulFunc)
  {
    case  VMSESYSREQ_SETACCESS :
      vmSysSetAccess(hvdm, nbIn, (PVOID)pIn, nbOut, (PVOID)pOut);
      break;
   
    case  VMSESYSREQ_SETFOCUS :
      vmSysSetFocus(hvdm, nbIn, (PVOID)pIn, nbOut, (PVOID)pOut);
      break;
  
    case  VMSESYSREQ_POSTMOUSE :
      vmSysPostMouse(hvdm, nbIn, (PVOID)pIn, nbOut, (PVOID)pOut);
      break;

    default  :
      return  ERROR_INVALID_FUNCTION;
  } 
}                                      /* VMSysReqProc                       */

/***************************************************************************
 *
 *  FUNCTION NAME : vmSysSetAccess() 
 *
 *  DESCRIPTION   : Request/release VDM event access
 *
 *  This subroutine processes the VMSESYSREQ_SETACCESS function, and
 *  establishes (or relinquishes) exclusive access for the caller to
 *  any and all mouse events posted for the specified VDM.
 *
 *  INPUT    :
 *             hvdm -> VDM
 *             fSet == TRUE to request access, FALSE to release
 *  OUTPUT   :
 *             SUCCESS
 *                 Zero
 *             FAILURE
 *                 Error code (ie, access denied, etc)
 *  USES     :
 *             32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT  :
 *             Task-time
 *
 *  PSEUDO-CODE                                     REFERENCES
 ****************************************************************************/

LONG PRIVENTRY vmSysSetAccess(HVDM hvdm,BOOL fSet,PVOID p1,ULONG ul2,PVOID p2)
{

    /*
    ** If the handle is invalid, we let it slide, because this
    ** call could well have been issued for a VDM that is now dead 
    */


  if (hvdm != INVALID_HVDM)
  {
    if (fSet)
      REFHVDM(hvdm, ULONG, fsstate) |= SESSION_WINDOW;
    else
      REFHVDM(hvdm, ULONG, fsstate) &= ~SESSION_WINDOW;
  } 
  return  NO_ERROR;
}                                      /* vmSysSetAccess                     */

 /**************************************************************************
 *
 *  FUNCTION NAME :  vmSysSetFocus() 
 *
 *  DESCRIPTION   :  Set/clear focus
 *
 *  This subroutine processes the VMSESYSREQ_SETFOCUS function, and
 *  sets or clears focus flag for the specified VDM.
 *
 *  INPUT    :
 *             hvdm -> VDM
 *             fSet == TRUE to set focus, FALSE to clear
 *             p2   -> pointer to screen group ID to capture/release mouse inputs
 *
 *  OUTPUT   :
 *              SUCCESS
 *                  Zero
 *             
 *              Returns ulsgCapture set in vmMouseCapture() which identifies
 *              the setting ON/OFF of mouse capture for a specific screen group.
 *             
 *              FAILURE
 *                  Error code (ie, lock overflow, etc)
 *  USES     :
 *              32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT  :
 *              Task-time
 *
 *  PSEUDO-CODE                                     REFERENCES
 ****************************************************************************/

LONG PRIVENTRY vmSysSetFocus(HVDM hvdm,BOOL fSet,PULONG p1,ULONG ul2,PULONG p2)
{
  if (hvdm == INVALID_HVDM)
    return  ERROR_INVALID_PARAMETER;
  else
  {
    *p2 = ulsgCapture;
    if (fSet)
      REFHVDM(hvdm, ULONG, fsstate) |= SESSION_FGND;
    else
    {
      REFHVDM(hvdm, ULONG, fsstate) &= ~SESSION_FGND;
      if (usMouExclusive == pVDMData(hvdm)->ulSG)
        VMGrabAccess(hvdm, fSet);
    } 
    return  NO_ERROR;
  } 
}                                      /* vmSysSetFocus                      */

 /**************************************************************************
 *
 *  FUNCTION NAME : vmSysPostMouse() 
 *
 *  DESCRIPTION   : Post a mouse event to the VDM
 *
 *  This subroutine processes the VMSESYSREQ_POSTMOUSE function.
 *
 *  INPUT    :
 *              hvdm          = Handle of the VDM that the event is intended 
 *              sizemp        = size of mouse event packet
 *              pmi           = mouse info. packet
 *              ulPMPtrHidden =
 *              p    not used
 *  OUTPUT   :
 *              SUCCESS
 *                  Zero
 *              FAILURE
 *                  Error code (ie, etc)
 *  USES     :
 *             32-bit small-model PASCAL calling/register conventions
 *
 *  CONTEXT  :
 *             Task-time
 *
 *  PSEUDO-CODE                                     REFERENCES
 ***************************************************************************/

LONG PRIVENTRY vmSysPostMouse(HVDM hvdm,ULONG sizemp,PVOID pme,ULONG 
                               ulPMPtrHidden,PULONG p)
{
  LONG rc = NO_ERROR;
  MINFO mi;
  /*
  ** WARNING   - Validate pointers/lock memory!
  */

  if ( sizemp != sizeof( MOUEVENTINFO ) || hvdm == INVALID_HVDM )
    rc = ERROR_INVALID_PARAMETER;
  else
    if ( pVDMData(hvdm)->fScrInit && REFHVDM( hvdm, BOOL, fMouseEnabled ) )
    {
      mi.minfo_nx = ((PME)pme)->col;
      mi.minfo_ny = ((PME)pme)->row;
      mi.minfo_fs = ((PME)pme)->fs;

      if (ulPMPtrHidden && !usMouExclusive  
                        && (REFHVDM(hvdm, ULONG, fsstate)&SESSION_EXCMOUSE))
                           VMGrabAccess(hvdm, TRUE);

      if (!(mi.minfo_fs&MEVSTAT_ABSPIXEVENT))
        vmMickeysToPixels((PMINFO)SSToDS(&mi));

      if (!(REFHVDM( hvdm, ULONG, fsstate)&SESSION_EXCMOUSE) )
        vmAddEvent( hvdm,
                   (PMINFO)SSToDS(&mi),
                   (ULONG)VDHQueryKeyShift(hvdm),
                    FALSE );
    } 
  return  rc;
}                                      /* vmSysPostMouse                     */
#pragma  END_SWAP_CODE
