/*static char *SCCSID = "@(#)bmsxxx.c   6.2 91/04/05";*/
/****************************************************************************/
/*                                                                          */
/*                       IBM/Microsoft Confidential                         */
/*                                                                          */
/*                 Copyright (c) IBM Corporation  1987, 1990                */
/*                 Copyright (c) Microsoft Corp.  1987, 1990                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* Source File Name: BMSXXX.C                                                */
/*                                                                           */
/* Descriptive Name: Mouse subsystem                                         */
/*                                                                           */
/* CopyRight: (c) IBM Corp. 1987, 1989                                       */
/*                                                                           */
/* Status: OS/2 Release 2.00                                                 */
/*                                                                           */
/* Function: This module contains the worker routines for the base mouse     */
/*           subsystems. Many mouse functions are routed through the         */
/*           generic mouse function, BMSFunctions, which simply issues       */
/*           an IOCTL to the mouse device driver.                            */
/*                                                                           */
/* Entry Points:                                                             */
/* Internal      BmsFlushQue - Full screen flush mouse event queue           */
/* Internal      ShldFlushQue - Windowed text flush mouse event queue        */
/*                                                                           */
/* External References:                                                      */
/* Routines:   DosOpen                                                       */
/*             DosDevIOCtl                                                   */
/*             DosClose                                                      */
/*             DosFreeSeg                                                    */
/*             Refer to extern calls below prolog                            */
/*                                                                           */
/* Data: Refer to Instance and common data declarations below prolog         */
/*                                                                           */
/* Notes:                                                                    */
/*   Dependencies: Each worker receives 6 parameters since all workers are   */
/*                 called from a single point in BMSMAIN using a dispatch    */
/*                 table using the mouse function code as an index.          */
/*                                                                           */
/*   Restrictions: This source file is compiled with the C compiler default  */
/*                 data segment, _DATA, which becomes the base mouse         */
/*                 subsystem instance data segment.                          */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/*****************************************************************************/
/*******   C H A N G E       H I S T O R Y   *********************************/
/*****************************************************************************/

/*****************************************************************************/
/*******   Defines for inclusion of required typedefs, etc... ****************/
/*                                                                           */
/*@T52  = 01/19/90  TPL  DCR 704 work                                        */
/*B721494 04/03/91  GDW  Fix Shield GETNUMBUTTONS/GETNUMMICKEYS              */
/*@Paul   12/28/92  Paul Forwarding mechanism moucalls kbdcalls viocalls has */
/*                       circular reference. This kills performance and is   */
/*                       not how the forwarding was designed to work.        */
/*060982  03/01/93  GDW  DCAF uses many handles in SG1. When BVS calls       */
/*                       MouOpen during a session switch, it fails because   */
/*                       we are out of handles.  This leaves SG1,(PM), in a  */
/*                       80 by 24 video mode.  Changes were made to open the */
/*                       POINTER$ device driver, set it, and then close it   */
/*                       before opening the MOUSE$ device driver.  This      */
/*                       technique uses one less file handle.                */
/*****************************************************************************/
#define INCL_ERRORS
#define INCL_DOSSEMAPHORES
#define INCL_DOSPROCESS
#define INCL_DOSINFOSEG
#define INCL_DOSMEMMGR
#define INCL_DOSMODULEMGR
#define INCL_DOSDEVICES
#define INCL_MOU
#define INCL_VIO

#include <os2.h>
#include <dos.h>
#include <smrsgcb.h>
#include "bmsmain.h"

/*********************************************************************/
/* @Paul ... Translate back to the original names to allow internal  */
/* resolution instead of a forwarder circular reference.             */
/* Note for post Borg this will be redesigned to resolve the general */
/* problem.                                                          */
/*********************************************************************/
#undef VioGetConfig
APIRET APIENTRY VioGetConfig(USHORT usConfigId, PVIOCONFIGINFO pvioin, HVIO hvio);
/* @Paul ... End of added section. */

char * _cdecl FAR strncpy(void FAR *, void FAR *, USHORT);

/*****************************************************************************/
/* External Procedures                                                       */
/*****************************************************************************/
extern USHORT APIENTRY BVSGETPTRDRAWNAME(USHORT, USHORT, CHAR FAR *);
extern USHORT pascal   Bms_Set_Pointer_Draw(CHAR FAR *,CHAR FAR *,PDrawData );
extern USHORT pascal   MouseOpen(USHORT FAR *);
extern USHORT (APIENTRY *WINCONSOLEFLUSHPOINTEREVENTS)(USHORT);
extern USHORT (APIENTRY *WINCONSOLEQUEUEDPOINTEREVENTS)(USHORT,PMOUQUEINFO);
extern USHORT (APIENTRY *WINCONSOLEREADPOINTEREVENT)(USHORT,USHORT,USHORT,PMOUEVENTINFO);
extern USHORT (APIENTRY *WINCONSOLEGETPOINTERFILTERMASK)(USHORT,USHORT FAR *);
extern USHORT (APIENTRY *WINCONSOLESETPOINTERFILTERMASK)(USHORT,USHORT);
extern USHORT (APIENTRY *WINCONSOLEGETPTRPOS)(USHORT,USHORT FAR *,USHORT FAR *);
extern USHORT (APIENTRY *WINCONSOLESETPTRPOS)(USHORT,USHORT,USHORT);
extern USHORT (APIENTRY *WINCONSOLEATTACHMOUSEUSER)(USHORT);
extern USHORT (APIENTRY *WINCONSOLEDETACHMOUSEUSER)(USHORT);

/*****************************************************************************/
/* External Shared Data                                                      */
/*****************************************************************************/
extern USHORT InitFlag;
extern BYTE   IoctlTable[];
extern CHAR   MouseFileName[];
extern USHORT MouseVer;
extern USHORT NumButtons;                     /* Number of buttons on mouse  */
extern USHORT NumMickeys;                     /* Number of mickeys for mouse */
#pragma same_seg(WINCONSOLEFLUSHPOINTEREVENTS,\
                 WINCONSOLEQUEUEDPOINTEREVENTS,\
                 WINCONSOLEREADPOINTEREVENT,\
                 WINCONSOLEGETPOINTERFILTERMASK,\
                 WINCONSOLESETPOINTERFILTERMASK,\
                 WINCONSOLEGETPTRPOS,\
                 WINCONSOLESETPTRPOS,\
                 WINCONSOLEATTACHMOUSEUSER,\
                 WINCONSOLEDETACHMOUSEUSER,\
              InitFlag,IoctlTable,MouseFileName,MouseVer,NumButtons,NumMickeys)

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: BmsClose                                                 */
/*                                                                           */
/* DESCRIPTIVE NAME: Close the mouse device driver                           */
/*                                                                           */
/* FUNCTION: Close the mouse device driver and if the current PID has        */
/*           established a pointer draw device, reinitialize to allow        */
/*           another process to register a pointer draw device driver.       */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: BmsClose                                                     */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: Handle - Mouse device driver handle returned by MOUOPEN            */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from DosClose                                 */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* BmsClose(Function,Handle,parm1ptr,parm2ptr)                               */
USHORT pascal BmsClose(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
PUSHORT *parm1ptr;                      /* Dummy place holder on stack       */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{
   USHORT RC = 0;
   if (sgdata_el->BMS_BvsMouHandle == Handle)
     sgdata_el->BMS_BvsMouHandle = 0;
   if (Handle != 0)
     {
       /****************************************/
       /* Close the mouse device driver handle */
       /****************************************/
       RC = DosClose(Handle);
       if (RC == NO_ERROR)
         {
           if ((currPID == sgdata_el->BMS_OwnerPID) &&
                          (Handle == sgdata_el->BMS_OwnerHandle))
             {
               sgdata_el->BMS_OwnerPID = 0;
             }
         }
     }
   return(RC);
}  /* END BMS CLOSE Routine */

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: BmsFlushQue                                              */
/*                                                                           */
/* DESCRIPTIVE NAME: Flush mouse event queue                                 */
/*                                                                           */
/* FUNCTION: Issue IOCTL to mouse device driver to flush the event queue     */
/*           for the current screen group.                                   */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: BmsFlushQue                                                  */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: Handle - Mouse device driver handle returned by MOUOPEN            */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from DosDevIOCtl                              */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* BmsFlushQue(Function,Handle,parm1ptr,parm2ptr)         */

USHORT pascal BmsFlushQue(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
PUSHORT *parm1ptr;                      /* Dummy place holder on stack       */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{

   return(DosDevIOCtl(0L,0L,1,0xB,Handle));

}  /* END BMSFLUSHQUE Routine */

/*****************************************************************************/
/*                                                                           */
/* SUBROUTINE NAME:   BmsOpen                                                */
/*                                                                           */
/* DESCRIPTIVE NAME:  Base Mouse Subsystem Open Function                     */
/*                                                                           */
/* FUNCTION:   Process the MouOpen API for both fullscreen and windowed text */
/*             screen group.                                                 */
/*                                                                           */
/* NOTES: Since, MOUOPEN returns a mouse handle it has a unique stack frame. */
/*        Consequently, the pointer to the entire stack frame is passed in   */
/*        where parm1ptr is passed in for most other calls.                  */
/*                                                                           */
/* ENTRY POINT: BmsOpen                                                      */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: Handle   - Mouse device driver handle NOT used by BmsOpen, the     */
/*                   handle address is accessed by using the OPEN stack frame*/
/*        openstack - a pointer to the stackframe passed to BMSMAIN by the   */
/*                   base mouse subsystem router                             */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from MouseOpen(DosOpen)                       */
/*                  Error code from WINCONSOLEATTACHMOUSEUSER                */
/*                  Error code from Bms_Get_Config                           */
/*                  Error code from BVSGETPTRDRAWNAME                        */
/*                  Error code from Bms_Set_Pointer_Draw                     */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*****************************************************************************/
/* BmsOpen(Function,Handle,openstack,parm2ptr)            */

USHORT pascal BmsOpen(Function,Handle,openstack,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
struct OPENPROT FAR *openstack;         /* Pointer to the BMSMAIN stackframe */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{
   USHORT             TempConfig[3];    /* Temporary config data work area   */
   USHORT             MouseHandle;      /* Temp storage for mouse handle     */
   CHAR               WorkPtrName[14];  /* Pointer draw name string          */
   CHAR FAR           *TempPtrDrawName; /* Pointer to pointer draw work area */
   USHORT             RC = 0;           /* Return code                       */
   USHORT             WhoIsCaller = 0;  /* Used to indicate base video call  */
   USHORT             ConfigNumber= 0;  /* Display configuration number      */
   USHORT FAR         *parmptr;         /* Address to return mouse handle    */
   VIOCONFIGINFO      ConfigStructure;  /* Temporary display config structure*/
   PVIOCONFIGINFO     ConfigPtr;        /* Pointer to display config data    */
   DrawData           DrawRoutine;      /* Pointer Draw entry and DS struct  */
   PDrawData          PDrawRoutine;     /* Pointer Draw entry and DS struct  */

   /**********************************/
   /* Address to return mouse handle */
   /**********************************/
   parmptr = (USHORT FAR *)openstack->HandleAddress;
   PDrawRoutine = &DrawRoutine;

   /**************************************************************************/
   /* 0:# is used by BVS to indicate the currently active video display      */
   /* The offset portion of the pointer draw address contains the display    */
   /* configuration BVS is establishing pointer draw for                     */
   /**************************************************************************/
   if ((FP_SEG(openstack->DrawNamePtr) == 0) &&
       (FP_OFF(openstack->DrawNamePtr) != 0)) {
     WhoIsCaller = 1;
     ConfigNumber = FP_OFF(openstack->DrawNamePtr);
   }

   /********************************************/
   /* Windowed text screen group open request? */
   /********************************************/
   if (currTYPE == PT_WINDOWABLEVIO) {
     /*********************************************************************/
     /* First open for windowed text screen group should physically open  */
     /* the mouse device driver                                           */
     /*********************************************************************/
     if (MouOpenCnt == 0)
       RC = MouseOpen(&WTMouseHandle);

     /************************************************************************/
     /* Attach to the windowed text screen group console. The console handle */
     /* will be returned as the handle to be used for all future MOU calls   */
     /************************************************************************/
     if (RC == NO_ERROR) {
       RC = WINCONSOLEATTACHMOUSEUSER(hConsole);
       if (RC == NO_ERROR) {
         MouOpenCnt++;
         *parmptr = hConsole;
       }
       else {
         /****************************************************/
         /* Close the mouse device driver handle if the Open */
         /* failed and no other opens are outstanding        */
         /****************************************************/
         if (MouOpenCnt == 0)
           DosClose(WTMouseHandle);
       }
     }
   }  /* ENDIF currTYPE == WINDOWABLEVIO */

   /**************************************************************************/
   /* Full screen session open                                               */
   /**************************************************************************/
   else {
     /********************************************/
     /* Base video subsystem not issuing MouOpen */
     /********************************************/
     if (WhoIsCaller != 1) {
       /******************************************************************/
       /* Get the configuration number for the currently active display  */
       /******************************************************************/
       ConfigPtr = &ConfigStructure;
       ConfigPtr->cb = 12;
       RC = VioGetConfig(ConfigNumber,(PVIOCONFIGINFO)ConfigPtr,0);
       if (RC == NO_ERROR)
         ConfigNumber = ConfigPtr->Configuration;
     }

     /******************************************************************/
     /* If previous process established pointer draw, use previously   */
     /* registered pointer draw name                                   */
     /******************************************************************/
     if (sgdata_el->BMS_OwnerPID != 0)
       TempPtrDrawName = (char FAR *)(sgdata_el->BMS_AppPtrDrawName);
     else {
       if ((WhoIsCaller == 1) || (openstack->DrawNamePtr == 0L)) {
         /***************************************************************/
         /* Request pointer draw name for specified display if the base */
         /* video subsystem is calling MouOpen                          */
         /***************************************************************/
         RC = BVSGETPTRDRAWNAME(ConfigNumber, 1,(CHAR FAR *)&TempPtrDrawName);
       }
       else {
         /***************************************************************/
         /* Use the user specified pointer draw name if no user         */
         /* specified pointer draw device established prior to this open*/
         /***************************************************************/
         TempPtrDrawName = (char FAR *)openstack->DrawNamePtr;
       }
     }

     if (RC == NO_ERROR) {
       if (MouseVer == 0)
         ConfigPtr = 0L;
       else {
         ConfigPtr = (PVIOCONFIGINFO)TempConfig;
         TempConfig[0] = 6;
         TempConfig[1] = ConfigNumber;
         TempConfig[2] = WhoIsCaller;
       }

       /******************************************************************/
       /* Establish a pointer draw procedure for the mouse device driver */
       /* to call at interrupt time for the current or specified video   */
       /* display.                                                       */
       /******************************************************************/
       RC = Bms_Set_Pointer_Draw(TempPtrDrawName, WorkPtrName, PDrawRoutine);
       if (RC == NO_ERROR) {
         /********************************/
         /* Open the mouse device driver */
         /********************************/
         RC = MouseOpen(&MouseHandle);                         /* 060982 */
         if (RC == NO_ERROR) {
           /**************************************************************/
           /* Establish the protect mode pointer draw for current SG     */
           /**************************************************************/
           PDrawRoutine->Reserved = 0;
           RC = DosDevIOCtl(ConfigPtr, &PDrawRoutine->DrawAddress, SETDRAW,
                                                MOUSECONTROL, MouseHandle);

           if (RC == NO_ERROR) {
             /***********************************************/
             /* Register handle for base video subsystem so */
             /* so future calls can be detected             */
             /***********************************************/
             if (WhoIsCaller == 1)
               sgdata_el->BMS_BvsMouHandle = MouseHandle;
             else {
               /****************************************************/
               /* Register process ID and mouse handle of the open */
               /* that registered the pointer draw procedure for   */
               /* the current screen group                         */
               /****************************************************/
               if (sgdata_el->BMS_OwnerPID == 0 &&
                    openstack->DrawNamePtr != 0L) {

                 strncpy((void FAR *)sgdata_el->BMS_AppPtrDrawName,
                         (void FAR *)&(WorkPtrName[5]),8);
                 sgdata_el->BMS_OwnerPID = currPID;
                 sgdata_el->BMS_OwnerHandle = MouseHandle;
               }
             }

             *parmptr = MouseHandle; /* Handle for future MOU calls*/
           }
         }
         else {  /* MouseOpen ERROR */
           if (RC == ERROR_FILE_NOT_FOUND)
             RC = ERROR_MOUSE_NO_DEVICE;
         }
       }
     }
     if (RC != NO_ERROR)
       DosClose(MouseHandle);
   }

   return(RC);

}  /* END BMSOPEN Routine */

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: BmsReadEventQue                                          */
/*                                                                           */
/* DESCRIPTIVE NAME: Read the next mouse event queue element                 */
/*                                                                           */
/* FUNCTION: Read the next mouse event queue elememt for full screen and     */
/*           windowed text screen groups.                                    */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: BmsFunctions                                                 */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: Handle - Mouse device driver handle returned by MOUOPEN            */
/*        SgNumber - used to isolate full screen from text windowed screen   */
/*                   group open request.                                     */
/*        parm1ptr - address of a word indicating read with wait or nowait   */
/*        parm2ptr - Address to return event data                            */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from DosDevIOCtl                              */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* BmsReadEventQue(Function,Handle,parm1ptr,parm2ptr)     */

USHORT pascal BmsReadEventQue(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Pointer to Wait Flag              */
PMOUEVENTINFO  parm2ptr;                /* Pointer to Structure Address      */
{
   USHORT RC;

   if (*parm1ptr <= WAIT)
     {
     /************************************************************************/
     /* Call the PM Shield for windowed text sessions and the mouse device   */
     /* driver for full screen sessions                                      */
     /************************************************************************/
       if (currTYPE == PT_WINDOWABLEVIO)
         RC = WINCONSOLEREADPOINTEREVENT(hConsole,*parm1ptr,1,parm2ptr);
       else
         RC = DosDevIOCtl((PVOID)parm2ptr,(PVOID)parm1ptr,
                                   IoctlTable[Function],MOUSECONTROL,Handle);
     }
   else
     RC = ERROR_MOUSE_INVALID_IOWAIT;
   return(RC);

}  /* END BMSREADEVENTQUE Routine */

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldAlwaysGood                                           */
/*                                                                           */
/* DESCRIPTIVE NAME: Always return successful return code                    */
/*                                                                           */
/* FUNCTION: Some MOU APIs in a windowed text session will return a return   */
/*           code that indicates success even though the API was a NOP       */
/*                                                                           */
/* NOTES: Called for DrawPtr, RemovePtr, SetScaleFact, and SetDevStatus      */
/*                                                                           */
/* ENTRY POINT: ShldAlwaysGood                                               */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: None                                                               */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: None                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldAlwaysGood(Function,Handle,parm1ptr,parm2ptr)      */

USHORT pascal ShldAlwaysGood(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
PUSHORT *parm1ptr;                      /* Dummy place holder on stack       */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{
   return(0);                           /* Always return successful          */
}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldClose                                                */
/*                                                                           */
/* DESCRIPTIVE NAME: Mouse close for windowed text sessions                  */
/*                                                                           */
/* FUNCTION: Detach from the PM console for windowed text sessions.          */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldClose                                                    */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: None                                                               */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from WINCONSOLEDETACHMOUSEUSER                */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldClose(Function,Handle,parm1ptr,parm2ptr)           */

USHORT pascal ShldClose(Function,Handle,parm1ptr, parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Console handle from MOUOPEN       */
PUSHORT *parm1ptr;                      /* Dummy place holder on stack       */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{
   USHORT RC = 0;

   /**************************************************************************/
   /* Detach from the PM console                                             */
   /**************************************************************************/
   RC = WINCONSOLEDETACHMOUSEUSER(hConsole);
   if (RC == 0)
     {
       /*****************************************************/
       /* Decrement open count and if this is the last open,*/
       /* close handle tophysical mouse device driver       */
       /*****************************************************/
       MouOpenCnt--;
       if (MouOpenCnt == 0)
         {
           DosClose(WTMouseHandle);
           hConsole = 0;
         }
     }
   return(RC);
}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldFlushQue                                             */
/*                                                                           */
/* DESCRIPTIVE NAME: Flush mouse event queue                                 */
/*                                                                           */
/* FUNCTION: Flush mouse event queue for windowed text session               */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldFlushQue                                                 */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: None                                                               */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from WINCONSOLEFLUSHPOINTEREVENTS             */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldFlushQue(Function,Handle,parm1ptr,parm2ptr)        */

USHORT pascal ShldFlushQue(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
PUSHORT *parm1ptr;                      /* Dummy place holder on stack       */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{

  return(WINCONSOLEFLUSHPOINTEREVENTS(hConsole));

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetNumButt                                           */
/*                                                                           */
/* DESCRIPTIVE NAME: Get number of Mouse buttons                             */
/*                                                                           */
/* FUNCTION: Return the number of buttons retrieved at Globalinit time.      */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldGetNumButt                                               */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: None                                                               */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: NONE                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetNumButt(Function,Handle,parm1ptr,parm2ptr)        */

USHORT pascal ShldGetNumButt(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Number of Buttons                 */
USHORT FAR *parm2ptr;                   /* Dummy place holder on stack       */
{

   *parm1ptr = NumButtons;
   return(NO_ERROR);

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetNumMick                                           */
/*                                                                           */
/* DESCRIPTIVE NAME: Get number of Mouse buttons                             */
/*                                                                           */
/* FUNCTION: Return the number of mickeys retrieved at Globalinit time.      */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldGetNumMick                                               */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: None                                                               */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: NONE                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetNumMick(Function,Handle,parm1ptr,parm2ptr)        */

USHORT pascal ShldGetNumMick(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Number of Mickeys                 */
USHORT FAR *parm2ptr;                   /* Dummy place holder on stack       */
{

   *parm1ptr = NumMickeys;
   return(NO_ERROR);

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetDevStatus                                         */
/*                                                                           */
/* DESCRIPTIVE NAME: Return mouse device status                              */
/*                                                                           */
/* FUNCTION: Return mouse device status for windowed text session.           */
/*                                                                           */
/* NOTES: A 0 is always returned for device status with a successful return  */
/*        code.                                                              */
/*                                                                           */
/* ENTRY POINT: ShldGetDevStatus                                             */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: parm1ptr - User specified address to return device status in       */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: None                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetDeviceStatus(Function,Handle,parm1ptr,parm2ptr) */

USHORT pascal ShldGetDevStatus(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Device Status Pointer             */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{

   *parm1ptr = 0;
   return(NO_ERROR);

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetEventMask                                         */
/*                                                                           */
/* DESCRIPTIVE NAME: Return mouse event mask                                 */
/*                                                                           */
/* FUNCTION: Return mouse event mask for windowed text sessions.             */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldGetEventMask                                             */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: parm1ptr - User specified address to return event mask in          */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from WINCONSOLEGETPOINTERFILTERMASK           */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetEventMask(Function,Handle,parm1ptr,parm2ptr)    */

USHORT pascal ShldGetEventMask(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Address to return event mask      */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{

   return(WINCONSOLEGETPOINTERFILTERMASK(hConsole,parm1ptr));

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetNumQueEl                                          */
/*                                                                           */
/* DESCRIPTIVE NAME: Return number of mouse queue elements                   */
/*                                                                           */
/* FUNCTION: Return number of queue elements on mouse event queue for        */
/*           windowed text sessions.                                         */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldGetNumQueEl                                              */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: parm1ptr - User specified address to return number of queue        */
/*                   elements                                                */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from WINCONSOLEQUEUEDPOINTEREVENTS            */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetNumQueEl(Function,Handle,parm1ptr,parm2ptr)     */

USHORT pascal ShldGetNumQueEl(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
PMOUQUEINFO parm1ptr;                   /* Address to return # queue elements*/
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{

   return(WINCONSOLEQUEUEDPOINTEREVENTS(hConsole,parm1ptr));

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetPtrPos                                            */
/*                                                                           */
/* DESCRIPTIVE NAME: Return mouse pointer position                           */
/*                                                                           */
/* FUNCTION: Return mouse pointer position for windowed text sessions.       */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldGetPtrPos                                                */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: parm1ptr - User specified address to return pointer position in    */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: None                                                          */
/*                                                                           */
/* SIDE EFFECTS: AX = Error code from WINCONSOLEGETPTRPOS                    */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetPtrPos(Function,Handle,parm1ptr,parm2ptr)       */

USHORT pascal ShldGetPtrPos(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
PPTRLOC parm1ptr;                       /* Address to return pointer position*/
PUSHORT parm2ptr;                       /* Dummy place holder on stack       */
{

   return(WINCONSOLEGETPTRPOS(hConsole, &parm1ptr->row, &parm1ptr->col));

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetScaleFact                                         */
/*                                                                           */
/* DESCRIPTIVE NAME: Return mouse scaling factors                            */
/*                                                                           */
/* FUNCTION: Return mouse device scale factors for windowed text sessions.   */
/*                                                                           */
/* NOTES: Always returns a 1 for row/column scale factor with a successful   */
/*        return code.                                                       */
/*                                                                           */
/* ENTRY POINT: ShldGetScaleFact                                             */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: parm1ptr - User specified address to return scale factor data      */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: None                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetScaleFact(Function,Handle,parm1ptr,parm2ptr)    */

USHORT pascal ShldGetScaleFact(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Address to return scale factor    */
PUSHORT *parm2ptr;                      /* Dummy place holder on stack       */
{

   *parm1ptr = 1;
   parm1ptr++;
   *parm1ptr = 1;

   return(0);

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetSetPtrShape                                       */
/*                                                                           */
/* DESCRIPTIVE NAME: Return mouse Pointer Shape                              */
/*                                                                           */
/* FUNCTION: Return mouse Pointer Shape for windowed text session.           */
/*                                                                           */
/* ENTRY POINT: ShldGetSetPtrShape                                           */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: Function - Identifies a Get or Set request                         */
/*        parm1ptr - User specified address of the pointer definition record */
/*        parm2ptr - User specified address containing the pointer bit image */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: None                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetSetPtrShape(Function,Handle,parm1ptr,parm2ptr)  */

USHORT pascal ShldGetSetPtrShape(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Pointer definition record         */
USHORT FAR *parm2ptr;                   /* Pointer bit image                 */
{
   USHORT RC = 0;
   USHORT i;

   /*****************************/
   /* Get pointer shape request */
   /*****************************/
   if (Function == MOUGETPTRSHAPE)
     {
       /*****************************************************************/
       /* Verify user specified buffer contains proper structure length */
       /*****************************************************************/
       if (*parm1ptr < MAX_SHAPE_STRUCT_LEN)
         {
           *parm1ptr = MAX_SHAPE_STRUCT_LEN;    /* Return structure length   */
           RC = ERROR_MOUSE_INV_PARMS;
         }

     /************************************************************************/
     /* Copy default or last set pointer information into user specified     */
     /* buffers                                                              */
     /************************************************************************/
       else
         {
           for (i=0; i < 5 ; i++,parm1ptr++)
             {
               *parm1ptr = sgdata_el->BMS_TextCB->PtrDefRec[i];
             }
           *parm2ptr = sgdata_el->BMS_TextCB->PtrBuffer[0];
           parm2ptr++;
           *parm2ptr = sgdata_el->BMS_TextCB->PtrBuffer[1];
         }
     }

   /**************************************************************************/
   /* Set pointer shape request                                              */
   /**************************************************************************/
   else
     {

     /************************************************************************/
     /* Verify user specified buffer contains proper structure length        */
     /************************************************************************/
       if (*parm1ptr != MAX_SHAPE_STRUCT_LEN)
         RC = ERROR_MOUSE_INV_PARMS;

     /************************************************************************/
     /* Save user specified pointer information for future retrieval by      */
     /* GetPtrShape API                                                      */
     /************************************************************************/
       else
         {
            for (i=0; i < 5 ; i++,parm1ptr++)
              {
                sgdata_el->BMS_TextCB->PtrDefRec[i] = *parm1ptr;
              }
            sgdata_el->BMS_TextCB->PtrBuffer[0] = *parm2ptr;
            parm2ptr++;
            sgdata_el->BMS_TextCB->PtrBuffer[1] = *parm2ptr;
         }
     }

   return(RC);

}  /* END SETPTRSHAPE Routine */

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldSetEventMask                                         */
/*                                                                           */
/* DESCRIPTIVE NAME: Set new mouse event mask                                */
/*                                                                           */
/* FUNCTION: Set new mouse event mask for windowed text sessions.            */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldSetEventMask                                             */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: parm1ptr - User specified address containing new mouse event mask  */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from WINCONSOLESETPOINTERFILTERMASK           */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldSetEventMask(Function,Handle,parm1ptr,parm2ptr)    */

USHORT pascal ShldSetEventMask(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
PUSHORT *parm1ptr;                      /* Null pointer (0)                  */
USHORT *parm2ptr;                       /* Event Mask Address                */
{

   return(WINCONSOLESETPOINTERFILTERMASK(hConsole,(USHORT)*parm2ptr));

}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldSetPtrPos                                            */
/*                                                                           */
/* DESCRIPTIVE NAME: Set pointer position                                    */
/*                                                                           */
/* FUNCTION: Set the pointer position for a windowed text session.           */
/*                                                                           */
/* NOTES:                                                                    */
/*                                                                           */
/* ENTRY POINT: ShldSetPtrPos                                                */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: parm2ptr - Address of user specified row and column data           */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: AX = Error code from WINCONSOLESETPTRPOS                      */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldSetPtrPos(Function,Handle,parm1ptr,parm2ptr)       */

USHORT pascal ShldSetPtrPos(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT *parm1ptr;                       /* Dummy place holder on stack       */
PPTRLOC parm2ptr;                       /* Address of row/column data        */
{
   return(WINCONSOLESETPTRPOS(hConsole, parm2ptr->row, parm2ptr->col));
}

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: ShldGetSetThreshold                                      */
/*                                                                           */
/* DESCRIPTIVE NAME: Return mouse Threshold Values                           */
/*                                                                           */
/* FUNCTION: Return mouse Threshold Values in Text Windowed session.         */
/*                                                                           */
/* ENTRY POINT: ShldGetSetThreshold                                          */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: Function - Identifies a Get or Set request                         */
/*        parm1ptr - Addr of User Threshold Structure                        */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: None                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* ShldGetSetThreshold(Function,Handle,parm1ptr,parm2ptr) */

USHORT pascal ShldGetSetThreshold(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* Pointer Threshold Get             */
USHORT FAR *parm2ptr;                   /* Pointer Threshold Set             */
{
   USHORT RC = 0;
   USHORT  i = 0;
   USHORT length;
   USHORT FAR *tempptr;

   tempptr = parm1ptr;
   if (Function == MOUSETTHRESHOLD)
     tempptr = parm2ptr;

   /**********************************************************************/
   /* Get the remainder for checking the length parameter; must be even. */
   /**********************************************************************/
   length = *tempptr;

   /*****************************************************************/
   /* Verify user specified buffer contains proper structure length */
   /* 2 < length < 10 AND (length = EVEN)                           */
   /*****************************************************************/
   if (*tempptr > MAX_THRESH_STRUCT_LEN ||
       *tempptr < MIN_THRESH_STRUCT_LEN || (length & 1))
     {
      *tempptr = MAX_THRESH_STRUCT_LEN;  /*   Return MAX structure length   */
       RC = ERROR_MOUSE_INV_PARMS;     /* Flag error in structure length    */
     }

   else
     {
       if (Function == MOUGETTHRESHOLD)
         {
           length >> 1;                   /* Divide by two */
           /************************************************/
           /* Return saved Threshold Information to caller */
           /************************************************/
           for (i=0; i < length; i++,tempptr++)
              *tempptr = sgdata_el->BMS_TextCB->Threshold[i];

         }
       /*************************/
       /* Set Threshold request */
       /*************************/
       else
         {
           /*************************************************/
           /* Save user specified Threshold Information for */
           /* future retrieval by GetThreshold API          */
           /*************************************************/
           for (i=0; i < 5 ; i++,tempptr++)
             sgdata_el->BMS_TextCB->Threshold[i] = *tempptr ;
         }
     }

   return(RC);

}  /* END SHLD GET/SET THRESHOLD Routine */

/*********************** START OF SPECIFICATIONS *****************************/
/*                                                                           */
/* SUBROUTINE NAME: BmsGetSetThreshold                                       */
/*                                                                           */
/* DESCRIPTIVE NAME: Return mouse Threshold Values                           */
/*                                                                           */
/* FUNCTION: Return mouse Threshold Values in Full Screen session.           */
/*                                                                           */
/* ENTRY POINT: BmsGetSetThreshold                                           */
/*     LINKAGE: CALL NEAR                                                    */
/*                                                                           */
/* INPUT: Function - Identifies a Get or Set request                         */
/*        parm1ptr - Addr of User Threshold Structure                        */
/*                                                                           */
/* EXIT-NORMAL: AX = NO_ERROR                                                */
/*                                                                           */
/* EXIT-ERROR: None                                                          */
/*                                                                           */
/* SIDE EFFECTS:                                                             */
/*                                                                           */
/*********************** END OF SPECIFICATIONS *******************************/
/* BmsGetSetThreshold(Function,Handle,parm1ptr,parm2ptr)  */

USHORT pascal BmsGetSetThreshold(Function,Handle,parm1ptr,parm2ptr)
USHORT Function;                        /* Mouse function requested          */
USHORT Handle;                          /* Mouse device driver handle        */
USHORT FAR *parm1ptr;                   /* 1st user parameter (GetThreshold) */
USHORT FAR *parm2ptr;                   /* 1st user parameter (SetThreshold) */
{
   USHORT FAR *tempptr;
   USHORT RC = 0;
   tempptr = parm1ptr;
   if (Function == MOUSETTHRESHOLD)
     tempptr = parm2ptr;

   /************************************************************************/
   /* Verify user specified buffer contains proper structure length        */
   /************************************************************************/
   if (*tempptr > MAX_THRESH_STRUCT_LEN || *tempptr < MIN_THRESH_STRUCT_LEN)
     {
      *tempptr = MAX_THRESH_STRUCT_LEN;  /*   Return MAX structure length   */
       RC = ERROR_MOUSE_INV_PARMS;   /* Flag error in structure length    */
     }
   else
     return(DosDevIOCtl((PVOID)parm1ptr,(PVOID)parm2ptr,
                                 IoctlTable[Function], MOUSECONTROL,Handle));

   return(RC);

}  /* END GET/SET THRESHOLD Routine */
