
;/*************************************************************************
;*
;* SOURCE FILE NAME = IDC.ASM
;*
;* DESCRIPTIVE NAME = Mouse device independent IDC routines
;*
;* 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 	02/29/92
;*
;* DESCRIPTION	Mouse device independent IDC routines
;*
;* FUNCTIONS	GIDC_Entry()
;*		VDMEvent  ()
;*		ProtectEvent  ()
;*		Process_Packet()
;*		IntrSetup     ()
;*
;* NOTES	This file contains the mouse device independent IDC
;*		entry point and support routines.  These are refe-
;*		renced by the device dependent DD.  See the linker
;*		control file for location in link list
;*
;* STRUCTURES	NONE
;*
;* EXTERNAL REFERENCES
;*
;*		NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*		NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG	   APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   02/29/92  @V2.0XXX01  DCR 1555
;*
;*
;*
;*
;*
;*
;*
;*
;**************************************************************************


.386p

.xlist
	include mouse.inc
	include infoseg.inc
	include singleq.inc
.list


;*
;* External Mouse Module Data References
;*

       extrn  Ptr_Overide	   : byte
       extrn  MEvent		   : byte
       extrn  VEvent		   : byte
       extrn  Int_Packet	   : byte
       extrn  Num_Grps		   : byte
       extrn  FgndSessn 	   : byte
       extrn  SN_Flags		   : byte

       extrn  GDT_Seg		   : word
       extrn  DDDInit		   : word
       extrn  IntEntry		   : word
       extrn  VDM_Flags 	   : word
       extrn  IDC_CB		   : word
       extrn  Last_Event	   : word

       extrn  MSEVDDEntry	   : fword
       extrn  FgndCB		   : dword
       extrn  Process_Absolute	   : near
       extrn  CalcRelative	   : near
       extrn  CalcPixelMvmnt	   : near
       extrn  CalcPtrPos	   : near
       extrn  CalcProtThreshold    : near
       extrn  ReportProtectEvent   : near
       extrn  CollisionChk	   : near
       extrn  Emi_Stock_Revent	   : near			     ; emi
       extrn  Emi_Stock_Aevent	   : near			     ; emi

       extrn  Request_Handler	   : far
       extrn  Monitor_Handler	   : far

;;****************** - Security Begin

       extrn  Security_DS          : word
       extrn  Security_Off         : dword
       extrn  Security_Enable      : byte
       extrn  Security_Open        : word

;;****************** - Security End

CSEG	 SEGMENT   WORD  PUBLIC  USE16 'CODE'
	 ASSUME    CS:CSEG, SS:nothing, ES:nothing, DS:nothing

;*
;* Module Procs made Public for other Mouse Modules
;*

       public  GIDC_Entry
       public  Process_Packet
       public  Disable_Support
       public  IntrSetup
       public  ProtectEvent
       public  VDMEvent
       public  Strat_Entry
       public  Open_Mouse
       public  Close_Mouse
       public  Query_Mouse
       public  Up_Activity
       public  Security_Hook1		     ; @V2.0XXX01
       public  Security_End1		     ; @V2.0XXX01


;*********************************************************************
;*
;*  FUNCTION NAME :  GIDC_Entry
;*
;*  DESCRIPTION   :  Generic mouse device driver IDC entry
;*		     point.
;*
;*		     This routine is the Mouse Device Independent
;*		     device driver IDC entry point router/handler.
;*		     IDC function requests are routed to the specific
;*		     support/worker routines.  The address of this
;*		     routine is returned when an AttachDD DevHelp call
;*		     is issued specifying the mouse device (MOUSE$).
;*
;*
;*  INPUT	  :  AX = Function code
;*		     DS = Our data segment selector
;*		     ES = callers data segment selector
;*		     Other registers used by specific functions
;*
;*  RETURN-NORMAL :  Function performed, carry clear, registers
;*		     modified by specific functions.
;*
;*  RETURN-ERROR  :  Carry set, registers modified.
;*
;*  EFFECTS	  :  Registers modified.  See individual functions for
;*		     other possible effects.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES   :  Process_Packet, Disable_Support.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*     DevHelps:  NONE.
;*
;************************************************************************
;*
;* PSEUDOCODE	:
;*
;*BeginSub  GIDC_Entry	(entry pt for device indpndnt IDC interface)
;*
;* IF <support has not been disabled by DISABLE_SUPPORT call>
;*    IF <requested function is PROCESSPACKET>
;*	 call Process_Packet to process the packet
;*	 set no error code
;*    IF <requested function is DISABLESUPPORT>
;*	 call Disable_Support to disable support
;*	 set no error code
;*    IF <requested function is PROCESSABSOLUTE>
;*	 call Process_Absolute to process the packet
;*	 set no error code
;*    IF <requested function is OPENMOUSE>
;*	 call Start_IDC to check for an available handle
;*    IF <requested function is CLOSEMOUSE>
;*	 call Stop_IDC to free callers handle
;*    IF <requested function is QUERYMOUSE>
;*	 IF <SN support is active>
;*	    call Query_Mouse to return the activity status since last call
;*	 ELSE
;*	    Set carry flag to indicate error
;*	    return unknown command error code
;*	 ENDIF
;*    ELSE
;*	 set error code
;*    ENDIF
;* ELSE
;*    set error code
;* ENDIF
;* return
;*
;*EndSub  GIDC_Entry
;*
;************************************************************************

GIDC_Entry  Proc  FAR

;*
;*	If support is enabled then call the appropriate support routine.
;*

       .if <bit DDDInit z DI_ERROR>	 ; if support has not been disbled

	  .if <ax eq PROCESSPACKET>	 ; Process packet call ?
	     call Emi_Stock_Revent	 ; pre_process packet	      ;emi

	     .if <bit SN_Flags nz SNF_ACTIVE> ; If SN support is active
		call Up_Activity	 ; Update activity status
	     .endif

	     clc			 ; clear carry for no error

	  .elseif <ax eq DISABLESUPPORT> ; Disable support call ?
	     call Disable_Support	 ; go set flag to disable support
	     clc			 ; clear carry for no error

	  .elseif <ax eq PROCESSABSOLUTE>; Process packet call ?
	     call Emi_Stock_Aevent	 ; pre_process packet	      ;emi

	     .if <bit SN_Flags nz SNF_ACTIVE> ; If SN support is active
		call Up_Activity	 ; Update activity status
	     .endif

	     clc			 ; clear carry for no error

	  .elseif <ax eq OPENMOUSE>	 ; Open MOUSE$ call?
	     call Open_Mouse		 ; Try to obtain a handle

	  .elseif <ax eq CLOSEMOUSE>	 ; Close MOUSE$ call?
	     call Close_Mouse		 ; Try to release the handle

	  .elseif <ax eq QUERYMOUSE>	 ; Query mouse activity call?
	     .if <bit SN_Flags nz SNF_ACTIVE> ; If SN support is active.
		call Query_Mouse	 ; Get status since last call
	     .else
		stc			 ; indicate error
		mov ax, 1		 ; unknown command error code
	     .endif

;;****************** - Security Begin

          .elseif <ax eq Security_Open>  ; Are we requesting to Enable Security
              jmp  Security_Call

;;****************** - Security End

	  .else 			 ; un recognized function
	     stc			 ; indicate error
	     mov  ax, 1 		 ; unknown command error code
	  .endif			 ; end

       .else				 ; else support has been disabled
	  mov  ax, 1			 ; set error code
       .endif
       ret				 ; return to Device Dependent DD

;;****************** - Security Begin

Security_Call:
       .if <Security_Enable eq 0>
            push bp
            mov bp, sp
            mov ax, word ptr ss:[bp+8]
            mov Security_DS, ax            ; Data segment
            mov eax, dword ptr ss:[bp+10]
            mov Security_Off, eax          ; Offset
            mov Security_Enable, 1
            mov ax, 0                      ; Completed request
            pop bp
       .endif
       ret

;;****************** - Security End

GIDC_Entry  EndP


;*************************************************************************
;*
;*  FUNCTION NAME :  Process_Packet
;*
;*  DESCRIPTION   :  Process a relative mouse packet.
;*
;*		     This routine processes the interrupt data for the
;*		     mouse device.  A complete interrupt packet has
;*		     been recieved.  Motion is calculated.  If the
;*		     event is reportable then it is sent down the
;*		     monitor chain.  If no monitors are registered
;*		     then it is sent directly to the monitor handler.
;*		     The pointer image is then updated.  If a hot key
;*		     is detected then the event is sent.  This routine
;*		     is called by the IDC router for the indep.  DD.
;*
;*  ENTRY POINT   :  Process_Packet    LINKAGE:  CALL NEAR
;*
;*  INPUT	  :  Int_Packet should be filled by the DDDD
;*
;*			   where Int_Packet is defined as
;*
;*				      Event	  DW
;*				      Col_Mov	  dw
;*				      Row_Mov	  dw
;*
;*  RETURN-NORMAL :  Always.
;*
;*  RETURN-ERROR  :  Never.
;*
;*  EFFECTS	  :  Pointer position updated and event saved.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES   :  CalcNewPtrPos, IntrSetup, ReportEvent
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES   :  NONE.
;*     DevHelps   :  NONE.
;*
;*************************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  Process_Packet  (process an interrupt packet of data)
;*
;*  call IntrSetup to do common event processing setup
;*  IF <session has support>
;*     call CalcNewPtrPos to update row position
;*     call CalcNewPtrPos to update col position
;*     call ReportEvent to report the mouse event if needed.
;*  ENDIF	   /* Ignore event if no support available  */
;*
;*  return
;*
;* EndSub  Process_Packet
;*
;************************************************************************

Process_Packet	Proc  Near

;*
;*  First increment the entry flag for use in debugging to see if we are
;*  servicing a mouse event.  Then check if this event is for a full screen
;*  session. If it is a full screen session then call IntrSetup to setup
;*  everything needed to process a protect mode full screen mouse event.
;*  IntrSetup puts the sel:off of the mouse CB affected in DS:SI and
;*  leaves the mouse data selector in FS.  DS should be reset to
;*  the mouse data selector before exiting.
;*

Security_Hook1:      ; @V2.0XXX01

       inc  IntEntry
       mov  al, Num_Grps		; Get number of full screen sessions

Security_End1:	     ; @V2.0XXX01

       .if <FgndSessn lt al> AND	; If this is a full screen session AND
       .if <bit VDM_Flags z VDMXMOUSEMODE> ; A windowed VDM does NOT have
					   ; Exclusive mouse access!
	  push ds
	  push fs
	  call IntrSetup	     ; do common event processing setup

;*
;* If carry is clear then it is OK to process the event.
;*

	  .if <nc>   NEAR	     ; and session has open mse support
	     call ProtectEvent	     ; process a fullscreen event
	  .endif
	  pop  fs		     ; restore fs to entry value
	  pop  ds		     ; restore our ds

       .else
	  call VDMEvent 	     ; process VDM event
       .endif

       dec  IntEntry		     ; decrement entry count

       ret			     ; return to IDC router

Process_Packet	EndP

;***********************************************************************
;*
;*  FUNCTION NAME :  Disable_Support
;*
;*  DESCRIPTION   :  Disabe support support routine.
;*
;*		     This routine disables support for all API level
;*		     requests.	It is issued by the device dependent
;*		     DD when it receives a deinstall request.  It sets
;*		     a flag value that is check on entry to all API
;*		     level requests.
;*
;*  ENTRY POINT   :  Disable_Support   LINKAGE:  CALL NEAR
;*
;*  INPUT	  :  None.
;*
;*  RETURN-NORMAL :  Always.
;*
;*  RETURN-ERROR  :  Never.
;*
;*  EFFECTS	  :  API is disabled.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES   :  NONE
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES   :  None.
;*     DevHelps   :  None.
;*
;***********************************************************************
;*
;* BeginSub  Disable_Support
;*
;*   set flag indicating that support has been disabled
;*   return
;*
;* EndSub  Disable_Support
;*
;************************************************************************

Disable_Support  Proc  Near

	mov  DDDInit, DI_ERROR	       ; flag shut down of all activities
	ret

Disable_Support  EndP

;**********************************************************************
;*
;*  FUNCTION NAME :  Open_Mouse
;*
;*  DESCRIPTION   :  Start an Inter Device Communication link
;*		       with the mouse device independent device
;*		       driver (MOUSE$).
;*
;*		     This function is invoked by another Device
;*		     driver to get a Mouse IDC interface handle.
;*		     This function supports a max of 5 open Mouse
;*		     IDC handles at any one time. If a 6th Mouse IDC
;*		     handle is requested a NO_HANDLES_AVAILABLE error
;*		     code will be returned.
;*
;*  ENTRY POINT  :  Open_Mouse	      LINKAGE:	CALL NEAR
;*
;*  ENTRY	 :  AX = Function code
;*		    Open Mouse = 0004h
;*		    DS = Mouse$ DD DS value
;*		    ES = Calling DD DS value
;*		    All other reqs are undefined
;*
;*  RETURN-NORMAL: Carry Flag clear. Register listed below;
;*
;*		     BX = Mouse IDC handle
;*		     DS = Mouse$ DD DS value
;*		     ES = Calling DD DS value
;*		     All other reqs are undefined
;*
;*  RETURN-ERROR :  Carry set, registers listed below;
;*
;*		    AX = Error return code if carry set
;*		    DS = Mouse$ DD DS value
;*		    ES = Calling DD DS value
;*		    All other reqs are undefined
;*
;*  EFFECTS	 :  Registers modified.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*     DevHelps:  NONE.
;*
;**********************************************************************
;*  PSEUDOCODE :
;*
;* BeginSub  Open_Mouse
;*
;*
;*    Get CB for handle 0
;*    REPEAT
;*	 IF <this handle is free>
;*	    Mark this handle as active in CB
;*	    LEAVE
;*	 ENDIF
;*	 Get CB for next handle
;*    UNTIL <MAXIDCS have been checked>
;*
;*
;*    IF <a new handle has been given>
;*	 Clear carry flag
;*    ELSE
;*	 move into AX register (ERROR_NO_MORE_HANDLES)
;*	 Set carry flag
;*    ENDIF
;*
;*  return
;*
;* EndSub  Open_Mouse
;*
;************************************************************************

Open_Mouse  proc  near

   lea	si, IDC_CB			 ; Offset to the block of handles.
   xor	bx, bx				 ; Start with handle zero.

   .repeat
      .if <bit [si].IDC_Flags z IDC_ACTIVE>    ; If handle is free.
	 or [si].IDC_Flags, IDC_ACTIVE	 ; This handle is now in use.
	 .leave
      .endif
      inc  bx				 ; Try next handle
      add  si, size IDC_Entry		 ; Get next slot
   .until <bx eq MAXIDCS>		 ; Zero based (6th entry is invalid)


   .if <bx lt MAXIDCS>			 ; If a new handle has been given
      clc
   .else
      mov  ax, 8024h			 ; ERROR_NO_MORE_HANDLES
      stc
   .endif

   ret

Open_Mouse  endp

;**********************************************************************
;*
;*  FUNCTION NAME :  Close_Mouse
;*
;*  DESCRIPTION   :  Shut down the inter device communication
;*		     link between MOUSE$ and the calling
;*		     device driver.
;*
;*		     This function is invoked by another Device
;*		     driver to free a Mouse IDC interface handle.
;*		     This handle value must have been generated using
;*		     the mouse IDC function 0004h (Start_IDC). If
;*		     the handle is invalid then an INVALID_HANDLE
;*		     error code will be returned.
;*
;*  ENTRY POINT   :  Close_Mouse       LINKAGE:  CALL NEAR
;*
;*  ENTRY	  :    AX = Function code
;*			    Close Mouse = 0005h
;*		       BX = Mouse IDC handle
;*		       DS = Mouse$ DD DS value
;*		       ES = Calling DD DS value
;*		       All other reqs are undefined
;*
;*  RETURN-NORMAL : Carry Flag clear. Register listed below;
;*
;*			DS = Mouse$ DD DS value
;*			ES = Calling DD DS value
;*			All other reqs are undefined
;*
;*  RETURN-ERROR :  Carry set, registers listed below;
;*
;*			AX = Error return code if carry set
;*			DS = Mouse$ DD DS value
;*			ES = Calling DD DS value
;*			All other reqs are undefined
;*
;*  EFFECTS	 :  Registers modified.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*     DevHelps:  NONE.
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  Close_Mouse
;*
;*
;*  IF <callers handle le MAXIDCS>
;*     Get a pointer to the CB for this handle
;*     Mark this handle as inactive in CB
;*     Bring status back to idle state. (Set to zero)
;*     Clear the carry flag
;*  ELSE
;*     Move into AX register (ERROR_MOUSE_INVALID_HANDLE)
;*     Set carry flag
;*  ENDIF
;*
;*  return
;*
;* EndSub  Close_Mouse
;*
;*************************************************************************

Close_Mouse  proc  near

   .if <bx lt MAXIDCS>
      lea  si, IDC_CB			  ; Offset to the block of handles
      imul bx, size IDC_Entry		  ; Get offset to this entry
      add  si, bx			  ; We now point to the handle entry
      and  [si].IDC_Flags, NOT IDC_ACTIVE ; This handle is now in use
      mov  [si].IDC_Status, 0		  ; Bring status back to idle state.
      clc
   .else
      mov  ax, 502			  ; ERROR_MOUSE_INVALID_HANDLE
      stc
   .endif

   ret

Close_Mouse  endp

;***********************************************************************
;*
;*  FUNCTION NAME :  Query_Mouse
;*
;*  DESCRIPTION   :  Query for mouse activity since last call.
;*
;*  FUNCTION	  :  This function is invoked by another Input Device
;*		     driver to get the current mouse activity status.
;*
;*		     The activity status word shows any activity that
;*		     went on since the last time this function was
;*		     called or since the caller's handle was opened.
;*
;*		     The activity status word also shows any buttons
;*		     that are currently in use (down).
;*
;*		     A return value of zero in the BX register,
;*		     without an error condition, means no mouse device
;*		     activity has been recorded since the last call
;*		     and no buttons are currently down.
;*
;*		     In addition, the return status is on a system
;*		     wide basis. Meaning, there is no evaluation for a
;*		     particular session's activity.
;*
;*		     If the input mouse IDC handle in invalid then an
;*		     INVALID_HANDLE error code is returned.	   .
;*
;*  NOTES	 :   This function is valid only when OS/2 Special
;*		     needs support is enabled. If SN support is
;*		     disabled an UNKNOWN_COMMAND error code is
;*		     returned to the caller.
;*
;*
;*  ENTRY POINT  : Query_Mouse		 LINKAGE: CALL NEAR
;*
;*  ENTRY	 :	   AX = Function code
;*				Query Mouse = 0006h
;*			   BX = Mouse IDC handle
;*			   DS = Mouse$ DD DS value
;*			   ES = Calling DD DS value
;*			   All other reqs are undefined
;*
;*  RETURN-NORMAL : Carry Flag clear. Register listed below;
;*
;*			   BX = Mouse Activity Status
;*			   DS = Mouse$ DD DS value
;*			   ES = Calling DD DS value
;*			   All other reqs are undefined
;*
;*  RETURN-ERROR  :  Carry set, registers listed below;
;*
;*			   AX = Error return code if carry set
;*			   DS = Mouse$ DD DS value
;*			   ES = Calling DD DS value
;*			   All other reqs are undefined
;*
;*  EFFECTS	  :  Registers modified.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*     DevHelps:  NONE.
;*
;***********************************************************************
;* PSEUDOCODE :
;*
;*  BeginSub  Query_Mouse
;*
;*   IF <handle is in valid range>
;*	Get pointer to the CB for this handle
;*	Move the mouse activity status into the BX register
;*	Bring status back to idle state. (Set to zero)
;*	Clear the carry flag
;*   ELSE
;*	Move into the AX register (ERROR_MOUSE_INVALID_HANDLE)
;*	Set the carry flag
;*   ENDIF
;*
;*  return
;*
;* EndSub  Query_Mouse
;*
;************************************************************************

Query_Mouse  proc  near

   .if <bx lt MAXIDCS>		      ; If handle is in valid range AND
      lea  si, IDC_CB		      ; Offset to the block of handles
      imul bx, size IDC_Entry	      ; Get offset to this entry
      add  si, bx		      ; We now point to the handle entry
      mov  bx, [si].IDC_Status	      ; MSE activity status since last call

      mov  ax, Int_Packet.Event       ; Get current mouse state
      and  ax, NOT 1		      ; We want button status only

      or   bx, ax		      ; Return activity since last call +
				      ; current buttons in use.
      mov [si].IDC_Status, ax	      ; Bring status back to current state.
      clc
   .else
      mov  ax, 502		      ; ERROR_MOUSE_INVALID_HANDLE
      stc
   .endif

   ret

Query_Mouse  endp


;**********************************************************************
;*
;* FUNCTION NAME :  ProtectEvent
;*
;* FUNCTION	 :  This routine processes a protect mode session mse
;*		    event.
;*
;* INPUT	 : none
;*
;* OUTPUT	 : none
;*
;**********************************************************************
;* PSEUDOCODE  :
;* BeginSub  ProtectEvent
;*
;*
;* EndSub  ProtectEvent
;*
;************************************************************************


ProtectEvent  proc  near

NewRow	   equ	 <(word ptr [bp-2])>   ; local var for new row coord
NewCol	   equ	 <(word ptr [bp-4])>   ; local var for new col coord

       enter 4,0		       ; reserve space for vars

;*
;*	Put the current row/column resolution on the stack to be pulled off
;*	later for use in motion calcs.
;*
       test [SI].MType, Graphics      ; Test for Disp Mode Resolution
       .if  nz			      ; If in Graphics Mode then
	 push [si].GCol_Res	      ; push the graphics resolutions
	 push [si].GRow_Res	      ; on stack for use by CalcNewPtrPos
       .else			      ; else push the text resolutions
	 push [si].TCol_Res	      ; on stack for use by CalcNewPtrPos
	 push [si].TRow_Res	      ;
       .endif			      ; end display mode type test

;*
;*   Calculate the row motion.	First determine the number of pixels moved
;*   by calling CalcPixelMvmnt.  If there was motion then apply the
;*   thresholding algorithm and calculate the new pointer position.  If there
;*   was no motion then the current row position is used.
;*
       push [si].RowScale_Fact	      ; row scale factor
       push fs:Int_Packet.Row_Mov     ; raw row motions (mickeys)
       push [si].Row_Remain	      ; row mickey motion remainder
       call CalcPixelMvmnt	      ; calculate number of pixels moved
       pop  [si].Row_Remain	      ; save remainder
       add  sp, 4		      ; remove parameters from stack

       .if <ax ne 0>		      ; if there was pixel movement
	  push fs:Int_Packet.Row_Mov  ; push raw motion
	  call CalcProtThreshold      ; do a protect mode threshold calc
	  add  sp, 2		      ; remove parameter from stack

	  push [si].Ptr_Row_Pos       ; ptr row pos (row res already there)
	  push [si].Row_Cell_Size     ; row cell size
	  push [si].Row_Cell_Remain   ; row cell motion remainder
	  call CalcPtrPos	      ; calculate new pointer position
	  pop  [si].Row_Cell_Remain   ; save cell remainder for later use
	  add  sp, 6		      ; remove parameters from stack
	  mov  NewRow, ax	      ; this is the new row
       .else			      ; else no screen movement
	  add  sp, 2		      ; remove row resolution from stack
	  mov  ax, [si].Ptr_Row_Pos   ; get current row
	  mov  NewRow, ax	      ; the new row is the old row
       .endif

;*
;*     Repeat the same steps for the column position (motion).
;*

       push [si].ColScale_Fact	      ; col scale factor
       push fs:Int_Packet.Col_Mov     ; raw col motions (mickeys)
       push [si].Col_Remain	      ; col mickey motion remainder
       call CalcPixelMvmnt	      ; calculate number of pixels moved
       pop  [si].Col_Remain	      ; save last remainder
       add  sp, 4		      ; remove parameters from stack

       .if <ax ne 0>		      ; if there was pixel movement
	  push fs:Int_Packet.Col_Mov  ; push raw motion
	  call CalcProtThreshold      ; do a protect mode threshold calc
	  add  sp, 2		      ; remove parameter from stack

	  push [si].Ptr_Col_Pos       ; ptr row pos (col res already there)
	  push [si].Col_Cell_Size     ; coc cell size
	  push [si].Col_Cell_Remain   ; coc cell motion remainder
	  call CalcPtrPos	      ; calculate new pointer position
	  pop  [si].Col_Cell_Remain   ; save cell remainder for later use
	  add  sp, 6		      ; remove parameters from stack
	  mov  NewCol, ax	      ; save new col
       .else			      ; else no screen movement
	  add  sp, 2		      ; remove col resolution from stack
	  mov  ax, [si].Ptr_Col_Pos   ; get the current col
	  mov  NewCol, ax	      ; the new col is the old col
       .endif

;*
;*	Now check to see if we need to constrain the movement to a
;*	particular region.  Well, actually we ALWAYS constrain but the
;*	default constraint region is the video mode size.
;*
;*
       test [SI].MType, Graphics      ; Test for Disp Mode Resolution
       .if  nz			      ; If in Graphics Mode then
	 mov  ax,NewCol
	 cmp  ax,[si].ConstrX0
	 jge  notleft
	 mov  ax,[si].ConstrX0
notleft: cmp  ax,[si].ConstrX1
	 jle  notrght
	 mov  ax,[si].ConstrX1
notrght: mov  NewCol,ax
	 mov  ax,NewRow
	 cmp  ax,[si].ConstrY0
	 jge  nottop
	 mov  ax,[si].ConstrY0
nottop:  cmp  ax,[si].ConstrY1
	 jle  notbot
	 mov  ax,[si].ConstrY1
notbot:  mov  NewRow,ax
       .endif			      ; end display mode type test

;*
;*	Now build the mouse event.  If mickey data is to be reported then
;*	put the raw motion in the event and push the uncondintional report flag.
;*	Otherwise put the row/col position in the event and push the conditional
;*	report flag.  Then call ReportProtectEvent to route the event to the
;*	appropriate place.
;*

	test [SI].D_Status, MickeyData	 ; check to see if mickey data
       .if  nz				 ; to be reported.  If so
	  mov  ax, fs:Int_Packet.Row_Mov ; raw motion motion reported
	  mov  cx, fs:Int_Packet.Col_Mov ; for both row and col
	  mov  fs:MEvent.Mon_Row_Pos, ax ; and put in the event record
	  mov  fs:MEvent.Mon_Col_Pos, cx ;
	  push 1			 ; undonditionaly report the event
       .else				 ; Else report type pointer pos.
	  mov  ax, NewRow		 ; get new row
	  mov  cx, NewCol		 ; get new col
	  mov  fs:MEvent.Mon_Row_Pos, ax ; put in event record
	  mov  fs:MEvent.Mon_Col_Pos, cx
	  push 0			 ; report event if not a duplicate
       .endif				 ; Mickey Data Report Test

       push NewRow
       push NewCol
       call ReportProtectEvent		 ; go report a protect mode event
       add  sp, 6			 ; clear parameters from stack

       leave				 ; clear stack
       ret

ProtectEvent  endp


;***********************************************************************
;*
;* FUNCTION NAME : VDMEvent
;*
;* DESCRIPTION	 : This routine processes a VDM session mouse event.
;*
;*		   This routine processes the mouse event for a
;*		   full screen VDM. The PMSE calls the VMSE with
;*		   the NOTIFYEVENT function of the PMSE-VMSE IDC.
;*		   The event is reported in relative mickeys moved.
;*		   The packet passed to the VMSE is listed below;
;*
;*		   This structure is used when the PMSE
;*		   sends an event to the VMSE.
;*
;*	      VDMEvent_        struc
;*		 ve_SGID       dw	?   ; Screen group number.
;*		 ve_Event      dw	?   ; Button/motion status bits.
;*		 ve_DeltaX     dw	?   ; Column motion in mickeys.
;*		 ve_DeltaY     dw	?   ; Row motion in mickeys.
;*	      VDMEvent_        Ends
;*
;*  ENTRY POINT  :  VDMEvent	      LINKAGE:	CALL NEAR
;*
;*  INPUT	 :  DS:SI = offset to interrupt packet data.
;*
;*  RETURN-NORMAL:  Always.
;*
;*  RETURN-ERROR :  Never.
;*
;*  EFFECTS	 :  All regs may be modified.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES  :  CalcNewPtrPos, IntrSetup, ReportEvent
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES  :  NONE.
;*     DevHelps  :  NONE.
;*
;***********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  VDM_Event
;*
;*   Store current SGID in input packet to VMSE
;*
;*   Store current event in input packet to VMSE
;*   Store column movement in mickeys in the input packet to VMSE
;*   Store row movement in mickeys in the input packet to VMSE
;*
;*   IF <the VDM interface is enabled>
;*	send off the event to VMSE
;*   ENDIF
;*
;*  return
;*
;* EndSub  VDM_Event
;*
;************************************************************************

VDMEvent  proc	near

;*
;* If excluse mouse access mode is ON, then the VEvent.ve_SGID field
;* has already been updated when the VMSE called PDDCMD_XMouseMode.
;*

       .if <bit VDM_Flags z VDMXMOUSEMODE>
	  mov  al, fgndsessn		; Foreground FS VDM SGID
	  cbw				; Make into a word
	  mov  VEvent.ve_SGID, ax	; Update input packet.
       .endif

       mov  ax, Int_Packet.Event	; Motion/button status.
       mov  VEvent.ve_Event, ax 	; Update input packet.

       mov  ax, Int_Packet.Col_Mov	; Column movement in mickeys.
       mov  VEvent.ve_X, ax		; Update input packet.

       mov  ax, Int_Packet.Row_Mov	; Row movement in mickeys.
       mov  VEvent.ve_Y, ax		; Update input packet.

       .if <bit VDM_Flags nz VDMREGISTERED> ; if VDM interface enabled
	  push dword ptr VMSE_EVENT	    ; event notify function
	  push ds			    ; selector of input packet
	  push offset VEvent		    ; offset of input packet
	  push dword ptr 0		    ; output packet selector (N/A)
	  call MSEVDDEntry		    ; go notify the VDD


       .endif

       ret

VDMEvent  EndP


;***********************************************************************
;*
;*  FUNCTION NAME :  IntrSetup
;*
;*  DESCRIPTION   :  This routine performs all setup required to
;*		     process a mouse event.  It sets the session
;*		     type, checks to see that the session is active,
;*		     then gets the system time.  It returns carry set
;*		     if it is not OK to proceed, clear if it is OK to
;*		     proceed.
;*
;*  INPUT	  :  none.
;*
;*  OUTPUT	  :   carry clear if OK to proceed, set otherwise.
;*
;***********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  IntrSetup
;*
;*  return
;*
;* EndSub  IntrSetup
;*
;************************************************************************

IntrSetup  proc  near

;*
;*	First determine if the mouse is disabled.  If not then continue, if so
;*	set the carry flag and get out.
;*

       .if <Ptr_Overide eq OFF>
	  mov  es, word ptr GDT_Seg	     ; Get GDT Bi-Modal Info Seg Selector
	  sub  bx, bx			     ; Clear Base GDT Offset

;*
;*	   Mouse event has the following format:
;*	    for motion only, bit 0 is set
;*	    for button x, bit 2x-1 is set if button x is down with motion
;*	    for button x, bit 2x   is set if button x is down w/o motion
;*	   put the event in the event buffer for use later.
;*

	   mov	cx, Int_Packet.Event
	  mov  MEvent.Mon_EMask, cx	     ; Save event

;*
;*	    Now go find the CB sel:offset for the interrupting session.  If
;*	    it is found then check to see if the session is setup for mouse
;*	    support.
;*

	  push ds			  ; save mouse ds
	  lds  si, FgndCB		  ; get foreground session CB
	  pop  fs			  ; put mouse ds in fs

	  mov  bl, fs:FgndSessn 	  ; Get Current Foreground SG ID
	  test [si].D_Status, USS_Mode	  ; see if the mode is supported
	  .if <z>	     AND	  ; if it is and
	  test [si].Ptr_Flags, SM_WinFlag ; if we not are in the middle of
	  .if z 	     AND	  ; setting the display mode and
	  .if <[si].Hdle_Cntr gt 0>	  ; and session has open mse support
	     jmp  short SetTime 	  ; go set event time
	  .endif

;*
;*	   will fall through to here is session does not have support setup.
;*	   The carry flag will be set and this routine will be exited.	If
;*	   the session has support then the time will be set, carry flag
;*	   cleared and control returned to the caller.
;*
	   stc
	   jmp	short exit

SetTime:

;*
;* emi	    setting of the timestamp moved to emi.asm
;*

;*
;*  emi      xor  bx, bx
;*  emi      mov  ax, word ptr es:[bx].SIS_MsCount   ; Milli-Second Time
;*  emi      mov  word ptr fs:MEvent.Mon_Time, ax    ; Low Word Value
;*  emi      mov  ax, word ptr es:[bx].SIS_MsCount+2 ; Milli-Second Time
;*  emi      mov  word ptr fs:MEvent.Mon_Time+2, ax  ; High Word Value
;*

	 clc					     ; session has support

	.else
	  stc
       .endif

exit:
       ret

IntrSetup  Endp

;***********************************************************************
;*
;*  FUNCTION NAME :  Up_Activity
;*
;*  DESCRIPTION   :  Update all active SN entries.
;*
;*		     This function will update the activity status
;*		     word field for all open IDC handle entries.
;*
;*		     This field is returned to the caller when the
;*		     Query_Mouse function is issued.
;*
;*		     This function will only be called when OS/2
;*		     Special needs support is enabled (SNF_ACTIVE
;*		     bit is on in the SN_Flags byte).
;*
;*  ENTRY POINT   : Up_Activity 	  LINKAGE: CALL NEAR
;*
;*  ENTRY	  : DS = MOUSE$ data selector
;*
;*  RETURN-NORMAL : Always.
;*
;*  RETURN-ERROR  : None
;*
;*  EFFECTS	  : The IDC_Status field will be updated for all
;*		    open IDC handle entries.
;*
;*		    NO REGISTERS MODIFIED.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES   :  NONE.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES   :  NONE.
;*     DevHelps   :  NONE.
;*
;***********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  Up_Activity
;*
;*
;*   Put this event mask in AX
;*
;*   Get pointer to CB for handle zero
;*   REPEAT
;*	IF <handle is active>
;*	   Update the activity status field for this handle with new mask in AX
;*	ENDIF
;*	Get pointer to CB for next handle
;*   UNTIL <we have gone thru the CB for every handle>
;*
;*  return
;*
;* EndSub  Up_Activity
;*
;************************************************************************

Up_Activity  proc  near

   push ax			    ; AX will hold the current event
   push bx
   push si

   mov	ax, Int_Packet.Event	    ; Get this event.

   lea	si, IDC_CB		    ; Offset to the block of handles.
   xor	bx, bx			    ; Start with handle zero.

   .repeat

      .if <bit [si].IDC_Flags nz IDC_ACTIVE> ; If handle is active.
	 or [si].IDC_Status, ax 	 ; Or in this event.
      .endif

      inc  bx				 ; Next handle.
      add  si, size IDC_Entry		 ; Next IDC entry for this handle.

   .until <bx eq MAXIDCS>		 ; Zero based (6th entry is invalid)

   pop	si
   pop	bx
   pop	ax

   ret

Up_Activity  endp


;**********************************************************************
;*
;*  FUNCTION NAME :  Strat_Entry
;*
;*  DESCRIPTION   :  Entry point for all strategy requests.
;*
;*		     This routine is just a stub that immediatly
;*		     routes the call to Request_Handler. This stub
;*		     is needed because the strategy entry point must
;*		     be in the same segment as the interrupt entry
;*		     point. Since all strategy time code can be in
;*		     swappable memory this stub simply exists in the
;*		     low fixed non-swappable memory and does a far
;*		     call to the real strategy request handler which
;*		     resides in a swappable code segent.
;*
;*  ENTRY POINT   :  Strat_Entry	(PROTECT MODE ONLY)
;*		      LINKAGE:	CALL FAR
;*
;*  INPUT	  :  ES:BX points to the request packet.
;*
;*  RETURN-NORMAL :  Request Block status field set to indicate
;*		     function complete, no error.
;*
;*  RETURN-ERROR  :  Error codes set in Request Block status fiel
;*
;*  EFFECTS	  :  Stack is clean on return, Registers not preserved.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES   :  None.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES   : Request_Handler.
;*     DevHlps	  :  None.
;*
;**********************************************************************

Strat_Entry  Proc  Far
	 call  Request_Handler
	 ret
Strat_Entry  endp

CSEG	 ENDS
	 END
