;*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 = VDM.ASM                                                                      
;*                                                                                                           
;* DESCRIPTIVE NAME = Mouse Device Driver, MVDM Support.                        
;*                                                                         
;*                                                                         
;* VERSION      V2.0                                                       
;*                                                                         
;* DATE         02/29/92
;*                                                                         
;* DESCRIPTION  This file contains the routines to support MVDM.                                 
;*              See the linker control file for the locaiton in the                                                           
;*              link list
;*                                                                 
;*              This code resides in a swappable code segment.     
;*              
;* FUNCTIONS    PDDCMD_MSEEntry      Entry point for VDD-PDD IDC communtication
;*              PDDCMD_Register      Register the VMSE entry point.            
;*              PDDCMD_DeRegister    DeRegister the VMSE entry point.          
;*              PDDCMD_QueryType     Query physical mouse device parameters.   
;*              PDDCMD_SetScreenSize Set screen size for a VDM session.        
;*              PDDCMD_XMouseMode    Set exclusive mouse mode on/off.          
;*             
;* STRUCTURES   NONE                                                       
;*                                                                         
;* EXTERNAL REFERENCES                                                     
;*                                                                         
;*              NONE                                                       
;*                                                                         
;* EXTERNAL FUNCTIONS                                                      
;*                                                                         
;*              NONE                                                       
;*                                                                         
;* CHANGE ACTIVITY =                                                       
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION                       
;*   --------  ----------  -----  --------------------------------------   
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx                                  
;**************************************************************************

.xlist
        include mouse.inc
        include emiidc.inc                                            ;emi
.list

.386p

;*
;*    External Mouse Module Data References
;*

       extrn  DeviceData           : byte
       extrn  VEvent               : byte
       extrn  TypeOverRider        : byte
       extrn  SType                : byte
       extrn  EmiFlags             : byte                             ;emi
       extrn  EmiDD                : byte                             ;emi2
       extrn  EmiMvt               : byte                             ;emi2
       extrn  EmiSSI               : byte                             ;emi2
       extrn  FgndSessn            : byte                             ;emi2

       extrn  DDDInit              : word
       extrn  VDM_Flags            : word
       extrn  VDM_Cols             : word
       extrn  VDM_Rows             : word
       extrn  PortBase             : word

       extrn  MSEVDDEntry          : fword
       extrn  GetDeviceParms       : near
       extrn  InitSDevice          : near
       extrn  Emi_Config           : near                             ;emi
       extrn  Emi_far              : far                              ;emi

DSEG   SEGMENT   WORD  PUBLIC  USE16 'DATA'
DSEG   ENDS


CSEG2  SEGMENT   WORD  PUBLIC  USE16 'SWAPCODE'
       ASSUME    CS:CSEG2, SS:nothing, ES:nothing, DS:nothing

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

       public  PDDCMD_MSEEntry
       public  PDDCMD_Register
       public  PDDCMD_DeRegister
       public  PDDCMD_QueryType
       public  PDDCMD_SetScreenSize
       public  PDDCMD_XMouseMode

;*
;*     This is our data segment
;*

;*************************************************************************
;*                                                               
;*  FUNCTION NAME :  PDDCMD_MSEEntry                            
;*                                                               
;*  DESCRIPTION   : Entry point for VDD-PDD IDC communtication.
;*                                                               
;*                  This routine is the router for all VDD-PDD
;*                  function requests.  This entry point is provided   
;*                  during initialization by the RegisterPDD DevHelp   
;*                  call.  Functions are routed to their appropriate   
;*                  service routines.  If a function is invalid this   
;*                  routine will generate the appropriate error return 
;*                  code, otherwise the return code is set by the      
;*                  called service routine.                            
;*                                                               
;*  ENTRY POINT   : PDDCMD_MSEEntry    LINKAGE:  CALL FAR
;*                                                               
;*  INPUT         : Stack frame as follows (called from 32 bit code)      
;*                                                                        
;*                  SS:SP    -->  return address  (4 words)               
;*                  SS:SP+8  -->  Function specific ul2        (2 words)  
;*                  SS:SP+12 -->  Function specific ul1        (2 words)  
;*                  SS:SP+16 -->  Requested function code      (2 words)  
;*                                                               
;*                   ul1 is put in es:bx, ul2 is left on the stack.
;*                                                                              
;*                  Where: ul1 is a pointer to the input data structure AND
;*                         ul2 is a pointer to the output data structure
;*                                                               
;*  RETURN-NORMAL : Function performed AX<>0 (set by requested fct) 
;*                                                               
;*  RETURN-ERROR  :  AX=0  (set by requested function), BX contains  
;*                   the error code.
;*                                                               
;*  EFFECTS       : see individual functions.
;*                                                               
;*  INTERNAL REFERENCES:                                         
;*     ROUTINES:  PDDCMD_Register, PDDCMD_DeRegister,            
;*                PDDCMD_QueryType, PDDCMD_SetVDMParms           
;*                                                               
;*  EXTERNAL REFERENCES:                                         
;*     ROUTINES: None.                                           
;*     DevHelps: None.                                           
;*                                                               
;***********************************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  PDDCMD_MSEEntry
;*
;* IF <IDC initialization required>
;*    call GetDeviceParms to do the IDC initialization
;* ENDIF
;*
;* Get pointer to input packet
;* Get function number
;*
;* IF <device data set up failed>
;*     move into bx error code (DEVICENOTREADY)
;*     zero out AX to indicating error condition
;*
;* ELSEIF <function equals PMSE_REGISTER>
;*     call PDDCMD_Register to get VDDs entry point
;*
;* ELSEIF <function equals PMSE_DEREGISTER>
;*     call PDDCMD_DeRegister to stop IDC between PMSE and VMSE
;*
;* ELSEIF <function equals PMSE_QUERYTYPE>
;*     call PDDCMD_QueryType give VMSE the HW configuration data
;*
;* ELSEIF <function equals PMSE_SETSCREENSIZE>
;*     call PDDCMD_SetScreenSize to store the row and column values
;*
;* ELSEIF <function equals PMSE_XMOUSEMODE>
;*     call PDDCMD_XMouseMode to turn excluse mouse mode on/off
;*
;* ELSE
;*     zero out AX to indicating error condition
;*
;* ENDIF
;*
;* return
;*
;*EndSub  PDDCMD_MSEEntry
;*
;***********************************************************************

PDDCMD_MSEEntry  proc  far

Var2Lo        equ     <(word ptr [bp+10])>
Var2Hi        equ     <(word ptr [bp+12])>
Var1Lo        equ     <(word ptr [bp+14])>
Var1Hi        equ     <(word ptr [bp+16])>
FCodeLo       equ     <(word ptr [bp+18])>
FCodeHi       equ     <(word ptr [bp+20])>

       enter 0,0

       push bx                      ; save required registers
       push si
       push di
       push ds
       push es

       push DSEG
       pop  ds

       .if <bit DDDInit nz DI_IDC>   ; if device initialization is needed
          .if <TypeOverRider eq TRUE>
             call GetDeviceParms     ; go get device parameters
          .endif
          .if <SType eq TRUE>
             call InitSDevice
          .endif
       .endif
       .if <bit EmiFlags nz EMI_NEED_CONFIG>  ; emi configuration needed  ;emi
          call Emi_Config                                                 ;emi
       .endif                                                             ;emi

       mov  bx, Var1Lo                 ; set es:bx to the input packet
       mov  es, Var1Hi
       mov  ax, FCodeLo                ; get requested function

;*
;* First check to see that device data has been set up.  If not then
;* return a device not ready error.
;*

       .if <bit DDDInit nz DI_ERROR>   ; if device data set up failed

          mov  bx, DEVICENOTREADY      ; set device no ready error
          xor  ax, ax                  ; set error code

       .elseif <ax eq PMSE_REGISTER>
          call PDDCMD_Register

       .elseif <ax eq PMSE_DEREGISTER>
          call PDDCMD_DeRegister

       .elseif <ax eq PMSE_QUERYTYPE>
          call PDDCMD_QueryType

       .elseif <ax eq PMSE_SETSCREENSIZE>
          call PDDCMD_SetScreenSize

       .elseif <ax eq PMSE_XMOUSEMODE>
          call PDDCMD_XMouseMode

       .else
          xor  ax, ax
       .endif

       pop  es
       pop  ds
       pop  di
       pop  si
       pop  bx

       leave

       db   66h                     ; make return 32 bit
       ret  12                      ; return, pop 12 bytes of parameter data

PDDCMD_MSEEntry  endp


;**********************************************************************************
;*                                                               
;*  FUNCTION NAME : PDDCMD_Register         Function 0         
;*                                                               
;*  DESCRIPTION   : Register the VMSE entry point.
;*                                                               
;*                  This routine registers the VMSE entry point for
;*                  the PDD (us).  Until this function is invoked no   
;*                  VDM support is available.  (ie no events will be   
;*                  reported to the VMSE).  Other PMSE functions will  
;*                  be excuted, however.                               
;*                                                               
;*  ENTRY POINT   : PDDCMD_Register
;*  LINKAGE       : CALL NEAR
;*                                                               
;*  INPUT         : Var2Lo = low order 16 bits of EIP for VDD
;*                  Var2Hi = high order 16 bits of EIP for VDD
;*                  BX = CS of VDD entry point                   
;*                                                               
;*  RETURN-NORMAL : VMSE entry point is registered. AX=1            
;*                                                               
;*  RETURN-ERROR  : N/A                                             
;*                                                               
;*  EFFECTS       : GP Registers not preserved.
;*                                                               
;*                                                               
;**********************************************************************************
;*  PSEUDOCODE :
;*
;* BeginSub  PDDCMD_Register  (register the VMSE entry point)
;*
;* get VDD entry point address from parameter list
;* MSEVDDEntry <- VMSE entry point address
;* turn on bit indicating we can now call VMSE
;* set no error
;* return
;*
;* EndSub  PDDCMD_Register
;*
;***********************************************************************

PDDCMD_Register  proc  near

       mov  ax, Var2Lo                   ; get lo EIP of VDD entry point
       mov  word ptr MSEVDDEntry, ax     ; save it
       mov  ax, Var2Hi                   ; get hi part of VDD entry point
       mov  word ptr MSEVDDEntry+2, ax   ; save it
       mov  word ptr MSEVDDEntry+4, bx   ; save it
       or   VDM_Flags, VDMREGISTERED     ; We have an entry point to VMSE
       mov  ax, 1                        ; set no error
       ret

PDDCMD_Register  EndP

;**********************************************************************************
;*                                                               
;*  FUNCTION NAME : PDDCMD_DeRegister       Function 1         
;*                                                               
;*  DESCRIPTION   : DeRegister the VMSE entry point.
;*                                                               
;*                  This routine de-registers the VMSE entry point
;*                  for the PDD (us).                                  
;*                                                               
;*  ENTRY POINT   : PDDCMD_DeRegister
;*  LINKAGE       : CALL NEAR
;*                                                               
;*  INPUT         : Var2Lo = low order 16 bits of EIP for VDD
;*                  Var2Hi = high order 16 bits or EOI for VDD
;*                  BX = CS of VDD entry point
;*                                                               
;*  RETURN-NORMAL : VMSE entry point is registered. AX=1            
;*                                                               
;*  RETURN-ERROR  :  N/A                                             
;*                                                               
;*  EFFECTS       : GP Registers not preserved.
;*                                                               
;*
;**********************************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  PDDCMD_DeRegister  (de-register the VMSE entry point)
;*
;*
;*  turn off bit indicating we can no longer call VMSE
;*  set no error
;*  return
;*
;* EndSub  PDDCMD_DeRegister
;*
;***********************************************************************

PDDCMD_DeRegister  proc  near

       and  VDM_Flags, NOT VDMREGISTERED     ; No VMSE entry point for events
       mov  ax, 1                            ; always pass this call
       ret                                   ; return

PDDCMD_DeRegister  EndP

;**********************************************************************************
;*                                                               
;*  FUNCTION NAME :  PDDCMD_QueryType        Function 2         
;*                                                               
;*  DESCRIPTION   : Query physical mouse device parameters.
;*                                                               
;*                  This function returns the configuration data of
;*                  the physical mouse supported.  The data orginates  
;*                  in the device dependent DD.  The same data format  
;*                  used by QueryConfig call to the device dependent   
;*                  DD is used here.  The configuration data is copied 
;*                  to a buffer specified by the caller.               
;*                                                               
;*  ENTRY POINT   : PDDCMD_MSEQueryType
;*  LINKAGE       :  CALL NEAR
;*                                                               
;*  INPUT         : Var2Hi = Selector of user buffer                      
;*                  Var2Lo = Offset of user buffer                        
;*                                                               
;*  RETURN-NORMAL : Always, config data copied to callers buffer    
;*                  AX=1
;*                                                               
;*  RETURN-ERROR  :  N/A                                             
;*                                                               
;*  EFFECTS       : GP Registers not preserved.
;*                                                               
;*                                                               
;***********************************************************************************
;*
;*BeginSub  PDDCMD_QueryType  (query mouse configuration data)
;*
;* copy mouse config data to callers buffer
;* return
;*
;*EndSub  PDDCMD_QueryType
;*
;***********************************************************************

PDDCMD_QueryType  Proc  Near

       mov  es, Var2Hi                     ; get selector of where to return
       mov  di, Var2Lo                     ; data offset

       mov  cx, word ptr es:[di]           ; get length of user data area

       .if <cx eq <SIZE Dev_Data>>

          mov  si, offset DeviceData.DDLen ; offset of source of data
          cld                              ; go forward
          rep  movsb                       ; copy data
          mov  ax, 1                       ; show no error

       .else
          xor  ax, ax
       .endif

       ret                                 ; return to router

PDDCMD_QueryType  EndP

;**********************************************************************************
;*                                                               
;*  FUNCTION NAME : PDDCMD_SetScreenSize        Function 3     
;*                                                               
;*  DESCRIPTION   : Set screen size for a VDM session.
;*                                                               
;*                  This routine is called to inform us of the new
;*                  row and column resolution for the foreground       
;*                  fullscreen VDM.                                    
;*                                                               
;*  NOTES         : This function is called at the following times;
;*                  - A new FS VDM has been created.
;*                  - We are switching into a FS VDM
;*                  - A windowed VDM has been zoomed into a FS VDM
;*                  - A screen mode change has occurred in the
;*                   foreground FS VDM.
;*                                                               
;*                  This routine is needed for absolute device support    
;*                  in a fullscreen VDM.                                  
;*                                                                        
;*                  This routine also serves as a key as to when the      
;*                  VMSE is ready to accept events for the foreground     
;*                  fullscreen VDM screen group.                          
;*                                                               
;*  ENTRY POINT   : PDDCMD_SetScreenSize
;*  LINKAGE       :     CALL NEAR
;*                                                               
;*  INPUT         : ES:BX points to the SetScreenSize input structure.    
;*                        See the mode data structure in mouse.inc        
;*                                                                        
;*  RETURN-NORMAL : AX=1, New screen size saved.                    
;*                                                               
;*  RETURN-ERROR  :  N/A.                                            
;*                                                               
;*  EFFECTS       : GP Registers not preserved.
;*                                                               
;**********************************************************************************
;* PSEUDOCODE :
;*
;* BeginSub  PDDCMD_SetScreenSize
;*
;* IF <the Input packet length is correct>
;*    store number of columns for this FS VDM session
;*    store number of rows for this FS VDM session
;*    send starting video mode packet to the EMI driver
;*    send a ending video mode packet to the EMI driver
;*    turn on bit in VDM_Flags to indicate we can now send events
;*    indicate no error in AX
;* ELSE
;*    indicate an error in AX
;* ENDIF
;*
;* return
;*
;*EndSub  PDDCMD_SetScreenSize
;*
;***********************************************************************

PDDCMD_SetScreenSize  proc  near

;*
;* es:bx = data
;*

  .if <<word ptr es:[bx].Len> eq 12>         ; If length is correct   ;emi2

     mov  ax, word ptr es:[bx].New_GCol_Res  ; Get number of columns
     mov  VDM_Cols, ax                       ; Store for later use
     mov  EmiSSI.Ssi_GCol_Res, ax            ;                        ;emi2
     mov  ax, word ptr es:[bx].New_GRow_Res  ; Get number of rows
     mov  VDM_Rows, ax                       ; Store for later use
     mov  EmiSSI.Ssi_GRow_Res, ax            ;                       start emi2
                                             ;                       ^    c
     mov  al, es:[bx].M_Type                 ;                       |    h
     mov  EmiSSI.Ssi_Mtype, al               ;                       |    a
     mov  al, es:[bx].M_Color                ;                       |    n
     mov  EmiSSI.Ssi_Color, al               ;                       |    g
     mov  ax, es:[bx].New_TCol_Res           ;                       |    e
     mov  EmiSSI.Ssi_TCol_Res, ax            ;                       |    s
     mov  ax, es:[bx].New_TRow_Res           ;                       |
     mov  EmiSSI.Ssi_TRow_Res, ax            ;                       |
     xor  ah,ah                              ;                       |
     mov  al,FgndSessn                       ;                       |
     mov  EmiSSI.Ssi_Current, ax             ;                       |
     mov  EmiSSI.Ssi_Future, ax              ;                       |
                                             ;                       |
     mov  ah,SSI_START_VM_CHANGE             ;                       |
     mov  al,TRUE                            ;                       |
     mov  EmiSSI.Ssi_Command,ah              ;                       |
     mov  EmiSSI.Ssi_InfoValid, al           ;                       |

;*                                           ;                       |
;*  inform EMI driver                                                |
;*  ax = function is EMI_SYSEVENT                                    |
;*  ds:di = Sesssion Info                                            |
                                             ;                       |
     push di                                 ;                       |
     mov  ax,EMI_SYSEVENT                    ;                       |
     lea  di, EmiSSI                         ;                       |
     call Emi_far                            ;                       |
                                             ;                       |
     mov  ah, SSI_END_VM_CHANGE              ;                       |
     mov  al,TRUE                            ;                       |
     mov  EmiSSI.Ssi_Command,ah              ;                       |
     mov  EmiSSI.Ssi_InfoValid, al           ;                       |
                                             ;                       |
     mov  ax,EMI_SYSEVENT                    ;                       |
     lea  di, EmiSSI                         ;                       |
     call Emi_far                            ;                       V
     pop  di                                 ;                       end emi2

     mov  ax, 1                              ; indicate no error
  .else
    xor  ax, ax                              ; indicate error condition
  .endif

  ret

PDDCMD_SetScreenSize  endp

;**********************************************************************************
;*                                                               
;*  FUNCTION NAME :  PDDCMD_XMouseMode           Function 4     
;*                                                               
;*  DESCRIPTION   : Set exclusive mouse mode on/off.
;*                                                               
;*                  This routine is called to inform us of the that
;*                  the advanced property (exclusive mouse mode) is    
;*                  being either turned on or off for a particular     
;*                  DOS window.                                        
;*                                                               
;*  NOTES         : When exclusive mouse mode is ON events will be
;*                  sent directly to the VMSE even though we are in       
;*                  the PM screen group. If exclusive mouse mode is       
;*                  OFF it is business as usual.                          
;*                                                               
;*  ENTRY POINT   : PDDCMD_XMouseMode
;*  LINKAGE       :     CALL NEAR
;*                                                               
;*  INPUT         : ES:BX points to the XMouseMode (xmm_) structure.
;*                                                               
;*             xmm_             struc                                       
;*                xmm_len       dw       ?  ; Length of packet in (8 bytes )
;*                xmm_sgid      dw       ?  ; DOS window session id number  
;*                xmm_flags     dd       ?  ; Flags                         
;*             xmm_             ends                                        
;*                                                                          
;*  RETURN-NORMAL : AX=TRUE                                         
;*                                                               
;*  RETURN-ERROR  :  AX=FALSE                                        
;*                                                               
;*  EFFECTS: GP Registers not preserved.                         
;*                                                               
;*                                                               
;**********************************************************************************

PDDCMD_XMouseMode  proc  near

       .if <<word ptr es:[bx].xmm_len> eq 8>      ; If length is correct

          .if <bit <dword ptr es:[bx].xmm_flags> nz 1>
             or  VDM_Flags, VDMXMOUSEMODE         ; XMM mode is ON
             mov  ax, word ptr es:[bx].xmm_sgid   ; DOS window session ID #
             mov  VEvent.ve_SGID, ax              ; Update input packet.
          .else
             and VDM_Flags, NOT VDMXMOUSEMODE     ; XMM mode os OFF
          .endif

          mov  ax, 1                              ; indicate no error

       .else
         xor  ax, ax                              ; indicate error condition
       .endif

       ret

PDDCMD_XMouseMode  endp

CSEG2 ENDS
      END
