;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/

;/*************************************************************************
;*
;* SOURCE FILE NAME = IDC.ASM
;*
;* DESCRIPTIVE NAME = Mouse device independent IDC routines
;*
;*
;* 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              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


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                ;           
       public  Security_End1                 ;           


;*********************************************************************
;*
;*  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

          .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

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:      ;           

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

Security_End1:       ;           

       .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 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
