
;/*************************************************************************
;*
;* SOURCE FILE NAME = ABS.ASM
;*
;* DESCRIPTIVE NAME = Absolute event processing 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 	01/18/92
;*
;* DESCRIPTION	Absolute event processing routines.
;*
;* FUNCTIONS Process_Absolute() Process an absolute mouse event packet.
;*	     ABSProtEvent()	Process absolute event for protect mode.
;*	     ABSVDMEvent()	Process absolute event for a VDM session.
;*	     MapXY2RowCol()	Map an (x,y) coordinate to the current mode.
;*	     CalcRelative()	Converts absolute points into a relative
;*				motion equivalent.
;*
;* NOTES	This file contains the mouse device independent
;*		absolute event processing routines.  See the linker
;*		control file for location in link list
;*
;*
;* STRUCTURES	NONE
;*
;* EXTERNAL REFERENCES	 Ptr Draw DD, Device Dep DD
;*			 Update_Ptr, IntrSetup, ReportEvent.
;*
;*
;* EXTERNAL FUNCTIONS
;*
;*		NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG	   APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   01/18/92  @V2.0XXX01  DCR 1555
;*   01/18/92  @V2.0RAR01  60273  Fixed typo in code
;*   07/15/93  RAR2	   68850  Added additional check for Xclusive Mode
;*
;*
;*
;*
;**************************************************************************


.386p

.xlist
	include mouse.inc
.list

;*
;*  External Mouse Module Data References
;*

       extrn  FgndSessn 	   : byte
       extrn  MEvent		   : byte
       extrn  VEvent		   : byte
       extrn  DeviceData	   : byte
       extrn  Int_Packet	   : byte
       extrn  Num_Grps		   : byte

       extrn  IntEntry		   : word
       extrn  VDM_Flags 	   : word
       extrn  VDM_Cols		   : word
       extrn  VDM_Rows		   : word

       extrn  MSEVDDEntry	   : fword

       extrn  Calc_Num		   : near
       extrn  IntrSetup 	   : near
       extrn  Update_Ptr	   : near
       extrn  ReportProtectEvent   : near


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

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

       public  Process_Absolute
       public  MapXY2RowCol
       public  CalcRelative
       public  ABSProtEvent
       public  ABSVDMEvent
       public  Security_Hook2		     ; @V2.0XXX01
       public  Security_End2		     ; @V2.0XXX01


;***********************************************************************
;*
;*  FUNCTION NAME  :  Process_Absolute
;*
;*  DESCRIPTION    :  Process an absolute mouse event packet.
;*
;*		 This routine processes absolute event data from
;*		 the attached pointing device.
;*
;*  INPUT	   :  The packet pointed to by SInt_Packet should contain
;*		      the new absolute event. The packet format is
;*
;*			  Abs_Event    dw
;*			  Y_Pos        dw
;*			  X_Pos        dw
;*			  Y_Size       dw
;*			  X_Size       dw
;*
;*		      DS - MOUSE$ data selector
;*
;*  OUTPUT	   :  None.
;*
;*  RETURN-NORMAL  :  Always.
;*
;*  RETURN-ERROR   :  Never.
;*
;*  EFFECTS	   :  Pointer position updated and event saved.
;*
;*  INTERNAL REFERENCES:
;*     ROUTINES:  Update_Ptr, CalcNewPtrPos, IntrSetup,
;*		  ReportEvent.
;*
;*  EXTERNAL REFERENCES:
;*     ROUTINES:  NONE.
;*     DevHelps:  NONE.
;*
;***********************************************************************
;* PSEUDOCODE :
;*
;*     BeginSub  Process_Absolute
;*
;*	IF <fullscreen session>
;*
;*	   call IntrSetup to do common event processing setup
;*	   IF <session has support>
;*	      call ABSProtEvent to process a fullscreen event
;*	   ENDIF	  /* Ignore event if no support available  */
;*
;*	ELSEIF<VMSE ready to accept events>
;*	   call ABSVDMEvent to process this FS VDM event
;*	ENDIF
;*
;*	return
;*
;*     EndSub  Process_Absolute
;*
;************************************************************************

Process_Absolute  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_Hook2: 		     ; @V2.0XXX01

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

Security_End2:			     ; @V2.0XXX01

       .if <FgndSessn lt al> AND     ; If this is a full screen session
       .if <bit VDM_Flags z VDMXMOUSEMODE> ; A windowed VDM does NOT have ;RAR2
					   ; Exclusive mouse access!	  ;RAR2

	  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>		     ; and session has open mse support
	     call ABSProtEvent	     ; process a fullscreen event
	  .endif
	  pop  fs		     ; restore fs to entry value
	  pop  ds		     ; restore our ds

       .else
	  call ABSVDMEvent	     ; process VDM event
       .endif

       dec  IntEntry		     ; decrement entry count

       ret			     ; return to IDC router

Process_Absolute  Endp


;******************************************************************
;*
;* FUNCTION NAME : ABSProtEvent
;*
;* DESCRIPTION	 : Process absolute event for protect mode.
;*
;*  INPUT	 : The packet pointed to by SInt_Packet should contain
;*		   the new absolute event. The packet format is
;*
;*			  Abs_Event    dw
;*			  Y_Pos        dw
;*			  X_Pos        dw
;*			  Y_Size       dw
;*			  X_Size       dw
;*
;*		    DS - MOUSE$ data selector
;*		    SI - pointer to the SGCB
;*
;* OUTPUT	 : Absolute event processed.
;*
;* SIDE EFFECTS  : No registers preserved.
;*
;*******************************************************************
;* PSEUDOCODE	 :
;*
;*	     BeginSub  ABSProtEvent
;*
;*	      return
;*
;*	     EndSub  ABSProtEvent
;*
;***********************************************************************

ABSProtEvent  proc  near

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

       enter 4,0		       ; reserve space for vars

       test [SI].MType, Graphics       ; IF mode is a graphics mode
       .if  nz			       ; then
	  push [si].GCol_Res	       ; push the graphics resolutions
	  push [si].GRow_Res	       ; on stack
       .else			       ; else push the text resolutions
	  push [si].TCol_Res	       ; on stack
	  push [si].TRow_Res	       ;
       .endif			       ; end display mode type test

       call MapXY2RowCol	       ; map the absolute data.

       mov  NewRow, ax
       mov  NewCol, bx

       test [SI].D_Status, MickeyData	 ; check to see if mickey data
       .if  nz				 ; to be reported.  If so

	  push NewCol			 ; put new column on stack
	  push NewRow			 ; and new row
	  call CalcRelative		 ; go calculate a relative event
	  add  sp, 4			 ; clear local variables
	  push 1			 ; report event no matter what.
       .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 the event
       add  sp, 6

;*
;* call update_ptr to update the pointer image.  cx is the new col position
;* and dx is the new row position.  If a VDM is active the device status
;* will be set to disable calling pointer draw.

;<<<<<<<<Is this redundent?
;<<<<<<mov  cx, NewCol
;<<<<<<mov  dx, NewRow
;<<<<<<call Update_Ptr		       ; update the pointer image
;<<<<<<<<End of redundency

       leave
       ret			       ; return to entry routine


ABSProtEvent  endp


;*******************************************************************
;*
;* FUNCTION NAME  : ABSVDMEvent
;*
;* DESCRIPTION	  : Process absolute event for a VDM session.
;*
;*  Now map the (x,y) point to the current (row,col) coordinate.
;*
;*  This is done using the following formula:
;*
;*	       Row = (YPos * Row_Res) / YSize
;*
;*  Where
;*	  Row is the display row
;*	  YPos is the absolute y position
;*	  Row_Res is the display mode row resolution
;*	  YSize is the Y axis size of the absolute device.
;*
;*	  The Column calculation is the same using the X
;*	  and column values.
;*
;*  INPUT	  : The packet pointed to by SInt_Packet should contain
;*		    the new absolute event. The packet format is
;*
;*			       Abs_Event    dw
;*			       Y_Pos	    dw
;*			       X_Pos	    dw
;*			       Y_Size	    dw
;*			       X_Size	    dw
;*
;*			 DS - MOUSE$ data selector
;*
;* OUTPUT	  : Absolute event processed.
;*
;* SIDE EFFECTS   : No registers preserved.
;*
;**********************************************************************
;*  PSEUDOCODE :
;*
;*   BeginSub  ABSVDMEvent
;*
;*    Get X position
;*    Get the number of columns in the X plane
;*    Get X size
;*    Call Calc_Num the get the actual column
;*    Store new column in packet to VMSE
;*
;*    Get Y position
;*    Get the number of rows in the Y plane
;*    Get Y size
;*    Call Calc_Num the get the actual row
;*    Store new row in packet to VMSE
;*
;*    Store current SGID in packet to VMSE
;*    Store current event in packet to VMSE
;*    Turn on bit in event field indicating (ABS event)
;*
;*    IF <VMSE ready for events>
;*	 Send VMSE this event
;*    ENDIF
;*
;*    return
;*
;*   EndSub  ABSVDMEvent
;*
;************************************************************************/

ABSVDMEvent  proc  near

       mov  ax, Int_Packet.X_Pos	; get the X position
       mov  bx, VDM_Cols		; Columns in the X plane.
       mov  cx, Int_Packet.X_Size	; get the X size
       call Calc_Num			; do (ax * bx)/cx
       mov VEvent.ve_X, ax		; New absolute col position.

       mov  ax, Int_Packet.Y_Pos	; get the Y position
       mov  bx, VDM_Rows		; Rows in the Y plane.
       mov  cx, Int_Packet.Y_Size	; get the Y size
       call Calc_Num			; do (ax * bx)/cx
       mov VEvent.ve_Y, ax		; New absolute row position.

;*								     ;RAR2
;* If excluse mouse access mode is ON, then the VEvent.ve_SGID field ;RAR2
;* has already been updated when the VMSE called PDDCMD_XMouseMode.  ;RAR2
;*								     ;RAR2
       .if <bit VDM_Flags z VDMXMOUSEMODE>			     ;RAR2
	  mov  al, fgndsessn		; Foreground FS VDM SGID
	  cbw				; Make into a word
	  mov  VEvent.ve_SGID, ax	; Update input packet.
       .endif							     ;RAR2

       mov  ax, Int_Packet.Event	; Motion/button status.
       mov  VEvent.ve_Event, ax 	; Update input packet.
       or   VEvent.ve_Event, ABSPIXEVENT; This is an ABS event.

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

       ret				     ; return to entry routine

ABSVDMEvent  endp


;***********************************************************************
;*
;* FUNCTION NAME : MapXY2RowCol
;*
;* DESCRIPTION	 : Map an (x,y) coordinate to the current mode.
;*
;* INPUT	 :  stack frame  top ->  return address
;*				 row resolution
;*				 col resolution
;*
;*	     SInt_Packet has the latest event data below;
;*
;*		  Abs_Event    dw
;*		  Y_Pos        dw
;*		  X_Pos        dw
;*		  Y_Size       dw
;*		  X_Size       dw
;*
;*	    DS - MOUSE$ data selector
;*
;* OUTPUT	 : ax = new row, bx = new col
;*
;* SIDE EFFECTS  : No registers preserved.
;*
;**********************************************************************
;*
;*  PSEUDOCODE :
;*
;*	       BeginSub  MapXY2RowCol
;*
;*		return
;*
;*	       EndSub  MapXY2RowCol
;*
;***********************************************************************


MapXY2RowCol  Proc  Near

RowRes	      equ     <(word ptr [bp+4])>
ColRes	      equ     <(word ptr [bp+6])>

       ENTER 0,0

       push RowRes
       push ColRes

;*
;* Now map the (x,y) point to the current display mode space.  This is done
;* using the following formula:
;*
;*		     Row = (YPos * Row_Res) / YSize
;*
;* Where Row is the display row, YPos is the absolute y position, Col_Res
;* is the display mode row resolution and YSize is the Y axis size of
;* the absolute pointing device.  The Column calculation is the same using
;* the X and column values.
;*


       mov  ax, fs:Int_Packet.X_Pos	 ; get the x position
       mov  cx, fs:Int_Packet.X_Size	 ; get the x size
       pop  bx				 ; get the col resolution
       .if <cx a 0>
	 call Calc_Num			; do (ax * bx)/cx
	 dec  bx			; convert col resolution to 0 base
	 .if <ax a bx>			; if new point out of range somehow
	    mov  ax, bx 		; then use the max 0 based resolution
	 .endif 			;
	 pop  bx			; get the row resolution
	 push ax			; save the new point

	 mov  ax, fs:Int_Packet.Y_Pos	; get the y position
	 mov  cx, fs:Int_Packet.Y_Size	; get the y size
	 .if <cx a 0>
	   call Calc_Num		; do (ax * bx)/cx
	   dec	bx			; convert col resolution to 0 base
	   .if <ax a bx>		; if new point out of range somehow
	      mov  ax, bx		; then use the max 0 based resolution
	   .endif			; leave new row in ax
	   pop	bx
	   clc				; indicate NO_ERROR
	 .else
	   pop	bx			; reset stack
	   stc				; set error condition
	   jmp	exit_err		; leave
	 .endif
       .else
	 pop  bx			; reset stack
	 stc				; set error condition
       .endif

exit_err:
       LEAVE
       ret

MapXY2RowCol  EndP


;**********************************************************************
;*
;* FUNCTION NAME : CalcRelative
;*
;* DESCRIPTION	 : Converts absolute points into a relative motion
;*		   equivalent.
;*
;* INPUT	 :  stack frame   top -> return address
;*					 Row position
;*					 Col position
;*
;* OUTPUT	 : relative motion in mickeys put in the mouse event pkt
;*
;* SIDE EFFECTS  : No registers preserved.
;*
;************************************************************************
;* PSEUDOCODE	 :
;*
;*		 BeginSub  CalcRelative
;*
;*		  return
;*
;*		 EndSub  CalcRelative
;*
;************************************************************************/

CalcRelative  Proc  Near

RowPos	      equ     <(word ptr [bp+4])>
ColPos	      equ     <(word ptr [bp+6])>

       ENTER 0,0

       mov  ax, RowPos
       sub  ax, [si].Ptr_Row_Pos
       imul [si].Row_Cell_Size
       imul [si].RowScale_Fact
       mov  cx, 8
       idiv cx
       mov  fs:MEvent.Mon_Row_Pos, ax

;*     mov  ax, NewCol				; @V2.0RAR01
       mov  ax, ColPos				; @V2.0RAR01
       sub  ax, [si].Ptr_Col_Pos
       imul [si].Col_Cell_Size
       imul [si].ColScale_Fact
       mov  cx, 8
       idiv cx
       mov  fs:MEvent.Mon_Col_Pos, ax

       LEAVE

       ret

CalcRelative  EndP

CSEG	 ENDS
	 END
