home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ddkx86v5.zip
/
DDKX86
/
SRC
/
DEV
/
MOUSE
/
IOSET.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-04-14
|
124KB
|
2,606 lines
;*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 = IOSET.ASM
;*
;* DESCRIPTIVE NAME = Mouse Device Driver, Protect Mode IOCtls.
;*
;*
;* VERSION V2.0
;*
;* DATE 01/23/92
;*
;* DESCRIPTION Mouse Device Driver, Protect Mode IOCtls.
;*
;* FUNCTIONS IOMW_MM (Cat 0Ah, Function 40h)
;* SGControl (Cat B - function 41h)
;* IOMW_SM (51h)
;* IOMW_SS (53h)
;* IOMW_EM (54h)
;* IOMW_TH (55H)
;* IOMW_PS (56h)
;* IOMW_DP (57h)
;* IOMW_RP (58h)
;* IOMW_SP (59h)
;* IOMW_SD (5A)
;* IOMW_DS (5C)
;* IOMW_MD (5Dh)
;*
;* NOTES This file contains Mouse DD Protect Mode IOCtl
;* Set worker routines.
;*
;* STRUCTURES NONE
;*
;* EXTERNAL REFERENCES
;*
;* NONE
;*
;* EXTERNAL FUNCTIONS
;*
;* NONE
;*
;* CHANGE ACTIVITY =
;* DATE FLAG APAR CHANGE DESCRIPTION
;* -------- ---------- ----- --------------------------------------
;* mm/dd/yy @Vr.mpppxx xxxxx xxxxxxx
;* 01/23/92 B736749
;*
;**************************************************************************
.386p
INCL_WINPROGRAMLIST equ 1 ; define for pmshl.inc defines
INCL_ERRORS equ 1 ; define for pmshl.inc defines
SESMGR equ 1 ; define for pmshl.inc defines
.xlist
include mouse.inc
include singleq.inc
include pmshl.inc
include basemaca.inc
include osmaca.inc
.list
CPUMODE 386
;*
;* External Mouse Module Data References
;*
extrn Num_Grps : byte
extrn CallSessn : byte
extrn FgndSessn : byte
extrn Modes : byte
extrn DeviceData : byte
extrn DDD : byte
extrn SQDDName : byte
extrn SQDD : byte
extrn Detach_Proc : byte
extrn Ptr_Overide : byte
extrn SN_Flags : byte
extrn Ptr_Rec : byte
extrn Sem_PID : word
extrn Eq_Length : word
extrn CallPID : word
extrn SQ_Pid : word
extrn VDM_Flags : word
extrn EMaskMax : word
extrn Device_Help : dword
extrn FgndCB : dword
extrn FlushMonChain : near
extrn GetExtModeData : near
extrn PtrDrawCheck : near
extrn Monitor_Handler : near
extrn AllocCB : near
extrn EnableMouse : near
extrn DisableMouse : near
extrn InitFSCB : near
extrn FindCB : near
extrn FreeCB : near
extrn SGSwitchStart : near
extrn SGSwitchEnd : near
extrn SGCreate : near
extrn SaveCfgData : near
extrn GetCfgDataOffset : near
extrn SaveExtModeData : near
extrn Emi_BegVMChange : near ;emi
extrn Emi_EndVMChange : near ;emi
extrn Emi_BegSesSwitch : near ;emi
extrn Emi_EndSesSwitch : near ;emi
EXTRNFAR Calc_Num
CSEG SEGMENT WORD PUBLIC USE16 'CODE'
CSEG 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 IOMW_MM ; Cat A - func 40h
public SGControl ; Cat B - func 41h
public IOMW_SM ; Cat 7 - func 51h
public IOMW_SS ; Cat 7 - func 53h
public IOMW_EM ; Cat 7 - func 54h
public IOMW_TH ; Cat 7 - func 55h
public IOMW_PS ; Cat 7 - func 56h
public IOMW_DP ; Cat 7 - func 57h
public IOMW_RP ; Cat 7 - func 58h
public IOMW_SP ; Cat 7 - func 59h
public IOMW_SD ; Cat 7 - func 5ah
public IOMW_DS ; Cat 7 - func 5ch
public IOMW_MD ; Cat 7 - func 5dh
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_MM (Cat 0Ah, Function 40h)
;*
;* DESCRIPTION : Performs Mouse Monitor Registration
;* for a Generic IOCtl request block that
;* is generated by a DosMonReg function
;* call.
;*
;* The data address field points to a monitor
;* register packet. This packet has four fields:
;* 1. word - placement in the chain.
;* 2. word - index field.
;* 3. dword - address of input buffer.
;* 4. word - offset to ouput buffer.
;* A DevHlp is used to add the monitor to the
;* requested session's chain.
;*
;* ENTRY POINT : IOMW_MM LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* DS:SI has offset to current session control block
;* FS Mouse data selector
;*
;* NOTES : A detached process cannot register a monitor for
;* its own session. It can however register a monitor
;* for a different session, as long as that session
;* is a valid full screen session.
;*
;* RETURN-NORMAL : Monitor is added to caller's session monitor
;* chain.
;*
;* RETURN-ERROR : Error code set in Request Block status field.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: NONE.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: NONE.
;* DevHlps: Register.
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_MM (register a mouse monitor)
;*
;* get user register parameters
;* disable system ints
;* get requested session number
;* IF <current process is DETACHED AND
;* request is for current session>
;* set requested session to Max_Session to cause failure
;* ENDIF
;* IF <requested session is gt -1 AND
;* lt Max_Session>
;* IF <specific session requested>
;* get MSCB of requested session
;* ENDIF
;* IF <monitor session does not have SQ mode active>
;* call Device_Help(Register) to register the monitor
;* IF <Register worked>
;* increment session monitor chain size
;* ELSE
;* set General Failure error code
;* ENDIF
;* ELSE
;* set parameter error
;* ENDIF
;* ELSE
;* set parameter error
;* ENDIF
;* enable system ints
;* return
;*
;* EndSub IOMW_MM
;*
;************************************************************************
IOMW_MM PROC near
TempES equ <(word ptr [bp-2])> ; Request packet selector
TempBX equ <(word ptr [bp-4])> ; Reguest packet offset
TempSI equ <(word ptr [bp-6])> ; CB offset of foreground session
TempDS equ <(word ptr [bp-8])> ; CB selector of foreground session
OtherSI equ <(word ptr [bp-10])> ; CB offset of SG to be monitored
OtherDS equ <(word ptr [bp-12])> ; CB selector of SG to be monitored
ErrorCode equ <(word ptr [bp-14])> ; 0 = no error, other is error code
Enter 14,0
mov TempES, es ; Save RP selector
mov TempBX, bx ; Save RP offset
mov TempSI, si ; Save foreground SG CB Offset
mov TempDS, ds ; Save foreground SG CB Selector
mov OtherSI, si ; Init to current SGs CB Offset
mov OtherDS, ds ; Init to current SGs CB Selector
mov ErrorCode, 0
les bx, es:[bx].GIODataPack ; Get Addr of Data Packet
cli ; Disable interrupts for Mon register
mov ax, es:[bx].Index ; Get Requested SG for MonChain
.if <ax eq -1> ; If current SG ID
.if <fs:Detach_Proc eq ON> OR ; If this is a detached proc (OR)
.if <bit [si].D_Status nz SQ_Mode>; If we are in the PM SG
mov ErrorCode, MNS ; then no_monitor_support
.endif
.else ; Caller specificed a SG #
.if <ax lt -1> OR ; If Index is less then -1 (OR)
.if <ah gt 0> OR ; If high byte is not 0 (OR)
.if <al ge fs:Num_Grps> ; if Index is greater= 16
mov ErrorCode, INVALIDPARMS ; then caller has invalid parms
.elseif <ax eq 2> ; Old 3X box SG # then return
mov ErrorCode, MNS ; error no_monitor_support
;*
;* We should check the calling session (CallSessn)
;* instead of foreground session (FgndSession) because the application
;* can call from a background or detached process.
;*
;** .elseif <al ne fs:FgndSessn> ; Index valid and not fgnd
.elseif <al ne fs:CallSessn> ; Index valid and not fgnd
;*
;* At this point we know that we are about to register a
;* monitor for a session that is not in the foreground. If
;* this session has not been created yet we must create the CB
;* for this screen group.
;*
mov bl, al ; get session #
xor bh, bh
push fs
pop ds
call FindCB ; ds:si -> CB if created already
.if <c> ; if not found, create the CB
mov cx, SIZE ScrGp_Data ; size of the full screen CB
add cx, Eq_Length ; add on event queue size
call AllocCB ; returns ds:si -> new CB allocated
.if <c>
mov ErrorCode, GENERALFAILURE
.else
call InitFSCB
.endif
.endif
mov OtherDS, ds ; Sel of the CB to be monitored
mov OtherSI, si ; Off of the CB to be monitored
.endif
;*
;* DCAF CHANGE - We should check the SQ_Mode flag instead of
;* Shell_Session when the application is trying to register a
;* monitor. DCAF temporarily disables the singleq before registering
;* a monitor for screen group 1.
;*
;** .elseif <ax eq Shell_Session> OR ; Else if Index equals PM SG (OR)
.if <bit [si].D_Status nz SQ_Mode>
mov ErrorCode, MNS ; error no_monitor_support
.endif
.endif
;*
;* At this point DS:SI points to the CB for the requested screen group ID
;*
;*
;* If no errors where encountered we will create the monitor chain if
;* this hasn't been done yet.
;*
.if <ErrorCode eq 0>
mov al, [si].Chain_Size ; # of Monitors in chain
.if <al eq 0> ; If none so far
; Create the Monitor chain
mov [si].MB_Len, 14 ; This must always be set
add si, MB_Len ; add in offset to MOB
mov es, OtherDS ; SG CB selector
push cs
pop ds ; Notify Rtn Address
mov di, offset Monitor_Handler
xor ax, ax ; Specify Create Chain
mov dl, DevHlp_MonitorCreate ; Specify function num
call fs:Device_Help ; Invoke MonitorCreate
mov si, OtherSI ; Restore CB offset
mov ds, OtherDS ; Restore CB selector
.if <nc>
mov [si].Chain_Hdle, ax ; Store handle returned
.else
mov ErrorCode, GENERALFAILURE
.endif
.endif
.endif
.if <ErrorCode eq 0>
mov cx, fs:Sem_PID ; Get caller's PID
mov ax, [si].Chain_Hdle ; Load SG Mon Chain Handle
mov es, TempES ; Restore RP selector
mov bx, TempBX ; Restore RP offset
les bx, es:[bx].GIODataPack ; Access Data Parm Record
mov dh, byte ptr es:[bx].P_Flag ; Get placement flag
mov dl, DevHlp_Register ; Register function
mov di, es:[bx].Output_Buff ; Load Output Buf Offset
mov si, word ptr ES:[BX].Input_Buff ; Load Input Buf Offset
mov es, word ptr ES:[BX].Input_Buff[2] ; Load Input Buf Selector
call fs:Device_Help ; do the register
mov si, OtherSI
.IF nc ; Normal return from Register?
inc [SI].Chain_Size ; Update monitor chain counter
.ELSE
mov ErrorCode, GENERALFAILURE
.ENDIF
.endif
mov es, TempES
mov bx, TempBX
mov si, TempSI
mov ds, TempDS
.if <ErrorCode ne 0>
mov ax, ErrorCode
mov es:[bx].PktStatus, ax
.endif
sti ; Enable interrupts DevHlp Complete
Leave ; Clear local vars off stack
ret ; Return to Request Handler Rtn
IOMW_MM ENDP
;**********************************************************************
;*
;* FUNCTION NAME : SGControl (Cat B - function 41h)
;*
;* DESCRIPTION : This routine handles all notifications that we
;* registered for with the session manager via the
;* DOSSMREGISTERDD call at init time.
;*
;* ENTRY POINT : SGControl LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX -> request packet
;* FS,DS -> mouse data segment
;*
;* The parameter packet has the following format
;*
;* SC_Length - WORD - Varies according to action
;* SC_Action - WORD - Could be any action below
;* SC_Data - BYTES - Varies according to action
;*
;* If action is The data is
;*
;* 08h TERMINATION TN_TypeOut - WORD
;* TN_SIDOut - WORD
;*
;*
;* 10h CREATION CN_SIDIn - WORD
;* CN_TypeIn - WORD
;*
;* 20h PRESWITCH OR PS_SIDIn - WORD
;* 40h POSTSWITCH PS_TypeIn - WORD
;* PS_SIDOut - WORD
;* PS_TypeOut - WORD
;*
;*
;* 100h AIMPOSTSAVE AIM_Errors - DWORD
;* AIM_Active - WORD
;* AIM_TimeOut - WORD
;* AIM_FKAccept - DWORD
;* AIM_FKRate - DWORD
;* AIM_FKDelay - DWORD
;*
;* RETURN-NORMAL : Always
;*
;* Carry Flag clear
;* ES:BX preserved
;* All other registers are undefined
;*
;* EFFECTS : Registers modified
;*
;* INTERNAL REFERENCES:
;* ROUTINES: SGSwitchStart, SGSwitchEnd, FreeCB, SGCreate
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: None
;* DEVHLPS: None
;*
;**********************************************************************
;*
;* PSEUDOCODE :
;*
;* BeginSub SGControl
;*
;* Save the request packet pointer.
;* Load a pointer to the parameter packet
;*
;* IF <Action eq PRESWITCH>
;* IF <Outgoing Type eq PROG_FULLSCREEN>
;* Get SG number going out.
;* call SGSwitchStart to initiate the SG switch
;* ELSE
;* Do nothing
;* ENDIF
;*
;*
;* ELSEIF <Action eq POSTSWITCH>
;* IF <Incoming Type eq PROG_FULLSCREEN>
;* Get SG number coming in.
;* call SGSwitchEnd to end the SG switch
;* ELSE
;* Clear carry, no error ignored operation
;* Zero pointer to fgnd CB
;* Shut down processing mouse data
;* Get SG number coming in.
;* .endif
;*
;* Store fgndsessn
;*
;*
;* ELSEIF <Action eq TERMINATION>
;* IF <Outgoing Type eq PROG_FULLSCREEN>
;* Get Outgoing SGID
;* IF <SGID eq FgndSessn>
;* Zero out pointer to foreground CB
;* Shut down processing data
;* ENDIF
;* Get CB for this SG
;* IF <no monitors registered>
;* call FreeCB to de-allocate to memory for the CB
;* ENDIF
;* ELSEIF <Outgoing Type eq PROG_VDM>
;* AND off VDMREADY bit to stop sending events to VMSE
;* ELSE
;* clear carry and ignore operation
;* ENDIF
;*
;*
;* ELSEIF <Action eq CREATION>
;* IF <Incoming type eq PROG_FULLSCREEN>
;* get incoming SG number
;* call SGCreate to allocate memory for the CB
;* ELSEIF <Incoming Type eq PROG_VDM>
;* AND off VDMREADY (VMSE is not ready for events yet)
;* ELSE
;* clear carry and ignore operation
;* ENDIF
;* ENDIF
;*
;* ELSEIF <Action eq AIMPOSTSAVE>
;* IF <AIM_Active eq 0>
;* Turn off SN_ACTIVE bit in SN_Flags byte
;* ELSE
;* Turn on SN_ACTIVE bit in SN_Flags byte
;* ENDIF
;*
;* ELSE
;* Clear carry (operation is ignored)
;* ENDIF
;*
;* Point ES:BX back to RP
;* return
;*
;*
;* EndSub SGControl
;*
;************************************************************************
public SGControl ;whswhs deleteme
SGControl proc near
?frame = 0 ; Get Local/Temp Stack Frame
LocalVar TempES, WORD ; For ES register
LocalVar TempBX, WORD ; For BX register
LocalVar TempDS, WORD ; For DS register
EnterProc
;*
;* First save the request packet pointer. Then get the pointer to the
;* switch control input.
;*
mov TempES, es
mov TempBX, bx
mov TempDS, ds
les bx, es:[bx].GIOParaPack
;*
;* If it is a PRESWITCH operation then get the current screen group
;* number. If it is a fullscreen session then start a switch. If not
;* a fullscreen clear the carry flag to show no error (operation ignored).
;* In both cases the call may return an error, if so the carry flag is
;* propagated to the end of the routine and returned to the caller
;*
.if <es:[bx].SC_Action eq PRESWITCH>
mov cx, es:[bx].PS_SIDIn ;emi
.if <es:[bx].PS_TypeOut eq PROG_FULLSCREEN>
mov bx, es:[bx].PS_SIDOut ;emi
mov ax, TRUE ;emi
push bx
call Emi_BegSesSwitch ; cx = caller's session ;emi
; bx = future session ;emi
pop bx ; ax = TRUE = fullscreen ;emi
call SGSwitchStart
.else
mov bx, es:[bx].PS_SIDOut ;emi
mov ax, FALSE ;emi
call Emi_BegSesSwitch ; cx = caller's session ;emi
; bx = future session ;emi
; ax = FALSE = not full screen ;emi
clc
.endif
;*
;* Now see if this is a POSTSWITCH operation. This operation is done
;* after the switch is complete. The SC_Incomming field is the new
;* screen group that is in the foreground. If the new screen group is
;* not a recognized type then the foreground control block pointer is
;* zero'd so that no one will try to access it. In all cases store the
;* new foreground session number.
;*
.elseif <es:[bx].SC_Action eq POSTSWITCH>
.if <es:[bx].PS_TypeIn eq PROG_FULLSCREEN>
mov bx, es:[bx].PS_SIDIn ; get affected session
mov ax, TRUE ;emi
push bx ;emi
call Emi_EndSesSwitch ; bx = session ;emi
; ax = TRUE = fullscreen ;emi
pop bx ;emi
call SGSwitchEnd ; end a screen group switch
.else ; Other session type
mov word ptr FgndCB+2, 0 ; zero pointer
mov Ptr_Overide, ON ; shut down processing mouse data
mov bx, es:[bx].PS_SIDIn ; get affected session
mov ax, FALSE ;emi
call Emi_EndSesSwitch ; bx = session ;emi
; ax = FALSE = not full screen;emi
clc ; no error, ignored operation ;emi
.endif
mov fs:FgndSessn, bl
;*
;* If the operation is a TERMINATION, then the SC_Current field has the
;* session number that is being terminated. If the session type is
;* supported then we go get the CB pointer. If the session has no
;* monitors in its chain then the CB is freed by calling FreeCB, otherwise
;* some process in another session has registered a monitor in this
;* session. The CB remains so that when the session is created again the
;* monitor will be present.
;*
.elseif <es:[bx].SC_Action eq TERMINATION>
.if <es:[bx].TN_TypeOut eq PROG_FULLSCREEN>
mov bx, es:[bx].TN_SIDOut
.if <bl eq FgndSessn> ; If the session is the
mov word ptr FgndCB+2, 0 ; foreground then zero ptr.
mov Ptr_Overide, ON ; shut down processing data
.endif
call FindCB ; Get the current ptr.
.if <[si].Chain_Size eq 0> ; monitors registered
mov ds, TempDS ; Re-load base DS
call FreeCB ; then free the CB
.endif
.else
clc
.endif
;*
;* If operation is a CREATION, then SC_Incomming is the new session
;* number. If it is a full screen session type then check to see if
;* the CB has already been allocated. The only way that a CB could
;* already be allocated before this CREATION notification is if an
;* app has already registered a monitor for this new SG ID.
;*
;* If the the TypeIn is a VDM the simply init the VDMREADY bit and
;* and return.
;*
;* All CREATION notifications for other SG types are ignored.
;*
.elseif <es:[bx].SC_Action eq CREATION>
.if <es:[bx].CN_TypeIn eq PROG_FULLSCREEN>
mov bx, es:[bx].CN_SIDIn
call FindCB ; Check if CB already alloced
.if <c> ; If not
call SGCreate ; Alloc CB
.endif
.else
clc
.endif
;*
;* If operation is a AIMPOSTSAVE check the AIM_Active word of the
;* parameter packet. If upported session type then call SGCreate to
;* create the control block.
;*
.elseif <es:[bx].SC_Action eq AIMPOSTSAVE>
.if <es:[bx].AIM_Active eq 0>
and SN_Flags, NOT SNF_ACTIVE
.else
or SN_Flags, SNF_ACTIVE
.endif
;*
;* Otherwise the operation is not recognized. The carry flag is left
;* clear to show the operation is not an error. It is ignored.
;*
.else
clc
.endif
mov bx, TempBX ; restore request packet address
mov es, TempES
LeaveProc
ret
SGControl Endp
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_SM (51h)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_SM, start a display mode change.
;*
;* The parameter list field points to a VIOSetMode
;* record. The data list field points to the
;* displays configuration data. If the current
;* session is in the FG and the set mode window flag
;* is not set then the pointer is hidden. This is
;* maintain compatibility with old mouse subsystems.
;* The set mode window flag is always set if the
;* mode data is valid. The flag may have been set
;* by the ptr draw register IOCtl. The Pointer
;* Draw DD is then called to validate the new mode
;* data. If supported then Point DD will fill in
;* the session control block with the mode data.
;* If unsupported then mouse support for that session
;* is disabled. IOCtl IOMW_MD is used to finish the
;* mode switch. Status word on stack is used to
;* flag intermediate errors so processing can be
;* halted. 0 indicates no errors.
;*
;* ENTRY POINT : IOMW_SM LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* DS:SI has offset to current session control block.
;*
;* RETURN-NORMAL : Mouse pointer is hidden, session control block
;* mode data fields are updated.
;*
;* RETURN-ERROR : session CB fields unchanged. Device status
;* flags set to indicate mode unsupported. Ptr
;* Draw functions are disabled until a supported
;* mode is set.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES : Calc_Num, SaveCfgData, SaveExtModeData,
;* GetCfgDataOffset, CheckAccess
;*
;* EXTERNAL REFERENCES:
;* ROUTINES : Ptr Draw(RemovePointer, CheckModeProtect)
;* DDDD(Enable_Device, Disable_Device)
;* DevHelps: NONE.
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_SM (set display mode)
;*
;* call DDDD(Disable_Device) to disable the mouse
;* IF <setmode window is not active>
;* remove the pointer if needed
;* set setmode window as active
;* ENDIF
;* IF <selector to config data is not NULL>
;* IF <length of config data is valid>
;* call SaveCfgData to save the config data
;* IF <error saving config data>
;* set error status
;* ENDIF
;* IF <status indicates no error so far>
;* call GetCfgDataOffset to get config data offset
;* IF <offset returned>
;* store selector:offset in MSCB
;* ELSE
;* 0 out sel:off in MSCB to show no cfg data available
;* ENDIF
;* ENDIF
;* ENDIF
;* ENDIF
;*
;* IF <status indicates no errors so far>
;* IF <current mode data available AND
;* mode is supported>
;* set flag indicating previous mode data exists
;* save current display mode type resolutions
;* ENDIF
;* call PtrDraw(CheckModeProt) to check new display mode
;*
;* IF <new display mode is supported>
;* set device status to supported display mode
;* IF <previous mode data exists>
;* map old ptr position to new screen resolution
;* ELSE
;* set ptr position to center of screen
;* ENDIF
;* ELSE
;* set parameter error (display mode not supported)
;* ENDIF
;* ENDIF
;*
;* call DDDD(Enbale_Device) to enable the mouse
;*
;* return
;*
;* EndSub IOMW_SM
;*
;************************************************************************
IOMW_SM proc near
TempES equ <(word ptr [bp-2])> ; For ES register
TempBX equ <(word ptr [bp-4])> ; For BX register
TempSI equ <(word ptr [bp-6])> ; for SI register
Old_Col_Res equ <(word ptr [bp-8])> ; for old mode data
Old_Row_Res equ <(word ptr [bp-10])> ; for old mode data
Status equ <(word ptr [bp-12])> ; For error status
;*
;* These equates are use for the status word.
;*
SM_ERROR equ 1 ; error detected
SM_PREVMODE equ 2 ; previous mode data was available
Enter 12,0
mov TempES, es ; Save Request Block Address
mov TempBX, bx
mov TempSI, si ; save session CB offset
mov Status, 0 ; no error so far
call DisableMouse ; Hold Mouse Interrupts
test [si].Ptr_Flags, SM_WinFlag ; see if set mode window active now
.if z ; if not then we must handle the
mov bl, fs:FgndSessn ; compatibility case. FG session
call PtrDrawCheck
.IF <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; set foregrnd session
push cx ; Save current reg value
mov cx, 0 ; Flag Remove Ptr Required
RemovePointer ; Hide Mouse Pointer Image
pop cx ; restore cx
.endif ; Collision Area Test
or [si].Ptr_Flags, SM_WinFlag ; set mode window active
.endif
mov bx, TempBX ; restore offset to packet
;*
;* Check access to set mode data and config data. We must be able to access
;* the mode data. If we cannot access the config data it is not an error from
;* the mouse's view. The config data address is passed in session CB to ptr
;* draw. If config data does not exist then this field is zero'd out. If ptr
;* draw needs to access the config data then he must return an error on the
;* check mode call.
;*
test word ptr es:[bx].GIODataPack+2, 0fff8h
.if <nz> ; valid selector(area valid)
les di, es:[bx].GIODataPack
.if <<word ptr es:[di]> ae 14>
; looks like valid data
mov bx, es:[di]+CfgNumOff ; get this config data's number
push ds
push es ; save cfg data selector
mov si, di ; put cfg data offset in si
pop ds ; DS:SI -> new config data
call SaveCfgData ; try to save the config data
pop ds
mov si, TempSI ; restore session CB offset
.if <c> ; if an error saving data
or Status, SM_ERROR ; set error code
.else ;
call GetCfgDataOffset ; get offset to config data
.if <nc> ; offset of cfg data returned
mov [si].CfgSelector, fs ; save sel to config data
mov [si].CfgOffset, dx ; save offset fo config data
.else ; error retrieveing offset
mov [si].CfgSelector, 0 ; zero out he config data
mov [si].CfgOffset, 0 ; pointer in the session CB
.endif ; end cfg offset returned test
.endif
.endif
.endif
;*
;* Config data has been stored, if given, and the session CB has been set up
;* to point to it. Now if there were no previous errors then continue.
;* First set up the address to the mode data. Then call ptr draw.
;*
test Status, SM_ERROR ; Is everything cool so far?
.if <z> NEAR ; yes so continue
mov es, TempES ; restore packet selector
mov bx, TempBX ; and packet offset
les di, es:[bx].GIOParaPack ; get mode data pointer
;*
;* We are now set up to call pointer draw to check the mode data. Ptr draw
;* should only validate the mode data. We sill save the mode data.
;* Save the extended mode data before calling ptr draw. This is to avoid
;* having to reload addresses in case ptr draw destroys them.
;*
.if <[si].MLength ne 0> AND ; Is there current mode data?
test [si].D_Status, USS_Mode ; and is it supported ? if so
.if <z> ; then remap old position
or Status, SM_PREVMODE ; Set previous mode flag
test [si].MType, Graphics ; Is mode a graphics mode ?
.if <nz> ; If so then save the
mov ax, [si].GRow_Res ; graphics row and column
mov bx, [si].GCol_Res ; resolutions.
.else ; Else it's a text mode so
mov ax, [si].TRow_Res ; save the text row and
mov bx, [si].TCol_Res ; column resolutions
.endif ; end mode type test
mov Old_Row_Res, ax ; Save old resolutions in
mov Old_Col_Res, bx ; the save area
.endif ; end mode data available test
push es ; save mode data address
push di ;
mov al, fs:CallSessn ; calling session
CheckModeProtect ; call ptr draw
pop di ; restore set mode address
pop es
.if <ax eq 0> ; if mode supported
and [si].D_Status, NOT USS_Mode ; Reset Disp Mode Flag Bit
;*
;* This section will if center the pointer if no previous mode data was
;* available, or map the old position to the new mode if there was old mode data.
;*
test Status, SM_PREVMODE ; was there old mode data
.if <nz> ; yes so map old to new
test es:[di].M_Type, Graphics ; is new mode graphics ?
.if <nz> ; yes
mov bx, es:[di].New_GRow_Res ; so get the graphics
push es:[di].New_GCol_Res ; resolutions
.else ; else text mode
mov bx, es:[di].New_TRow_Res ; so get the text
push es:[di].New_TCol_Res ; resolutions
.endif ; end mode type tests
mov ax, [si].Ptr_Row_Pos ; current row position
mov cx, Old_Row_Res ; old row resolution
CALLFAR Calc_Num ; map to new
mov [si].Ptr_Row_Pos, ax ; store new row position
pop bx ; get new col resolution
mov ax, [si].Ptr_Col_Pos ; current col position
mov cx, Old_Col_Res ; old col resolution
CALLFAR Calc_Num ; map to new
mov [si].Ptr_Col_Pos, ax ; store new col position
.else
test es:[di].M_Type, Graphics ; Check current Disp Mode
.if nz ; If in Graphics Mode then
mov ax, es:[di].New_GRow_Res ; Get row resolution
mov bx, es:[di].New_GCol_Res ; Get col resolution
.else ; If in Text Mode then
mov ax, es:[di].New_TRow_Res ; Get row resolution
mov bx, es:[di].New_TCol_Res ; Get col resolution
.endif ; Display Mode Tests
shr ax, 1 ; Get half row resolution
mov [si].Ptr_Row_Pos, ax ; to center ptr position
shr bx, 1 ; Get half col resolution
mov [si].Ptr_Col_Pos, bx ; to center ptr position
.endif
xor ch, ch ;emi
mov cl, fs:CallSessn ;emi
xor bh, bh ;emi
mov bl, fs:FgndSessn ;emi
push si ;emi
call Emi_BegVMChange ; cx = caller's session ;emi
; bx = future session ;emi
; es:di = video data ;emi
;emi
pop si ;emi
.else ; new Mode is not supported
ParmErr
or [si].D_Status, USS_Mode ; Set Unsupported Mode Bit
.endif ; end supported mode test
.else ; intermediate error det.
ParmErr ; set parameter error
or [si].D_Status, USS_Mode ; Set Unsupported Mode Bit
.endif ; end error detection
;*
;* Now copy the base mode data to the session CB, regardless of return code.
;* Access to mode data is OK here. 1st load address to mode data.
;*
mov es, TempES ; restore sel to req packet
mov bx, TempBX ; restore off to req packet
les di, es:[bx].GIOParaPack ; get ptr to mode data
add si, MLength ; pt to mode data fields
mov cx, BaseModeLen ; move only base mode data
mov al, fs:CallSessn ; current session
xor ah, ah ; convert to word
push ds ; exchange es and ds
push es ; ds -> mode data
pop ds ; es -> our data seg
pop es ;
xchg si, di ; switch si and di
push ds:[si] ; save length of mode data
cld ; go forward
rep movsb ; copy the mode data
pop cx ; get saved mode data len
sub cx, BaseModeLen ; calc ext mode data len
.if <cx gt 0> ; if there is ext mode data
call SaveExtModeData ; save the ext mode data
.endif
push es ; mouse cb from es
pop ds
mov si, TempSI ; restore session CB off
call EnableMouse ; allow mouse interrupts
mov es, TempES ; Restore request packet address
mov bx, TempBX ; in es:bx
Leave ; Clear Local Var Stack Frame
ret ; Return to IOCtl Handler Rtn
IOMW_SM ENDP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_SS (53h)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_SS, set scaling factors for current
;* session.
;*
;* The parmlist field in the request block points to
;* a 2 word structure. The 1st word is the new row
;* scaling factor. The 2nd word is the new column
;* scaling factor. The input values must be > 0 and
;* <= Max_Scale. A parameter error is set if any
;* value is out of range.
;*
;* ENTRY POINT : IOMW_SS LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's scaling factors are updated.
;*
;* RETURN-ERROR : Session's scaling factors are unchanged, the
;* Request Block status field set to error code.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: NONE.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: NONE.
;* DevHelps: NONE.
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_SS (set session scaling factors)
;*
;* get new scale factors
;* IF <new scale factors are in range>
;* disable system ints
;* assign new scale factors to MSCB
;* enable system ints
;* ELSE
;* set parameter error
;* ENDIF
;* return
;*
;* EndSub IOMW_SS
;*
;************************************************************************/
IOMW_SS proc near
TempES equ <(word ptr [bp-2])> ; local var for saving es
TempBX equ <(word ptr [bp-4])> ; local var for saving bx
Enter 4,0
mov TempES, es ; Save Request Block Address
mov TempBX, bx
les di, es:[bx].GIOParaPack ; load selector to data area
mov dx, es:[di].Parm1 ; Get input Row Scale Factor
mov cx, es:[di].Parm2 ; Get input Col Scale Factor
.if <dx gt 0> AND ; Check to make sure that the
.if <dx le Max_Scale> AND ; new scaling factors are both
.if <cx gt 0> AND ; in the valid range. If so
.if <cx le Max_Scale> ; then assign the new factors
cli ; Hold interrupts for data update
mov [si].RowScale_Fact, dx ; Assign new Scaling factors
mov [si].ColScale_Fact, cx
xor ax, ax ; Setup to Clear fields
mov [si].Row_Remain, ax ; Clear row remainder field
mov [si].Col_Remain, ax ; Clear col remainder field
mov [si].Row_Cell_Remain, ax ; Clear row pixel remainder
mov [si].Col_Cell_Remain, ax ; Clear col pixel remainder
sti ; restore system ints
.else ; If invalid Scaling Factor(s) then
ParmErr ; Flag Invalid Parm Error
.endif ; Input Scaling Factor Tests
mov es, TempES
mov bx, TempBX
Leave
ret ; Return to IOCTL Handler Rtn.
IOMW_SS EndP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_EM (54h)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_EM, set session's event mask.
;*
;* The parmlist field in the request block points to
;* the new 1 word event mask. The event mask must
;* be in range. Ints disabled while event mask is
;* updated.
;*
;* ENTRY POINT : IOMW_EM LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's event mask is updated.
;*
;* RETURN-ERROR : Session's event mask is unchanged, the
;* request block status field set to error code.
;*
;* EFFECTS : Stack is clean on return. AX, CX, DX, DI, and
;* SI registers contents are destroyed.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: NONE.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: NONE.
;* DevHelps: NONE.
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_EM (set session event mask)
;*
;* calculate max event mask from number of mouse buttons
;* IF <new event mask is lt max event mask>
;* disable system ints
;* set new event mask in MSCB
;* enable system ints
;* ELSE
;* set parameter error
;* ENDIF
;* return
;*
;* EndSub IOMW_EM
;*
;************************************************************************
IOMW_EM PROC near
?frame = 0 ; Define Local Stack frame
LocalVar TempES, WORD
LocalVar TempBX, WORD
EnterProc
mov TempES, es ; Save Request Block address
mov TempBX, bx
les di, es:[bx].GIOParaPack ; load selector to data area
mov ax, es:[di] ; Get new event mask
.if <ax le fs:EMaskMax> ; If new event mask is valid then
cli ; Hold interrupts for Data Updates
mov [si].E_Mask, ax ; Save event mask in SG CB
sti ; SG CB updated, allow interrupts
.else ; If new event mask is invalid then
ParmErr ; Set Parm Error Return code
.endif ; Event Mask Tests
mov bx, TempBX ; Restore Request Block address
mov es, TempES
LeaveProc ; Clear Local Stack frame
ret ; Return to Generic IOCtl Handler Rtn
IOMW_EM ENDP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_TH (55H)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_TH, set session threshold values.
;*
;* The parameter address field points to a 5 word
;* structure. The 1st word is the length and should
;* be 10 for this IOCtl. The 2nd word is the 1st
;* level movement rate. The 3rd word is the 1st
;* level multiplier. The 4th and 5th words are the
;* second level movement rate and multipliers re-
;* spectively. All values are legal.
;*
;* ENTRY POINT : IOMW_TH LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session threshold vlaues updated.
;*
;* RETURN-ERROR : Invalid Parameter error returned.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: NONE
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: DDDD(Disable_Device, Enable_Device)
;* DevHlps: NONE.
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_TH (Set session threshold values)
;*
;* call DDDD(Disable_Device) to disable the mouse
;* IF <length of new threshold data OK>
;* assign new threshold values and multipliers to session CB
;* ELSE
;* set PARAMETER ERROR
;* ENDIF
;*
;* call DDDD(Enable_Device) to enable the mouse
;* return
;*
;* EndSub IOMW_TH
;*
;************************************************************************
IOMW_TH proc near
call DisableMouse ; disable the mouse
push es ; save es
les di, dword ptr es:[bx].GioParapacx ; get address of ne values
.if <es:[di].THLength eq 10> and ; if data length is ok and
.if <es:[di].THLevel1 ne 0> and ; Level 1 is non 0 and
.if <es:[di].THLevel2 ne 0> and ; Level 2 is non 0 and
.if <es:[di].THLvl1Mplr ne 0> and ; 1st level mply is non 0 and
.if <es:[di].THLvl2Mplr ne 0> and ; 1st level mply is non 0 and
mov cx, es:[di].THLevel1 ; (get 1st level)
mov dx, es:[di].THLvl1Mplr ; (get 1st multiplier)
.if <<word ptr es:[di].THLevel2> ge cx> and ; 2nd lvl >= 1st lvl and
.if <<word ptr es:[di].THLvl2Mplr> ge dx> ; 2nd mplr >= 1st Mplr
mov [si].Level1, cx ; put in MSCB
mov ax, es:[di].THLevel2 ; get 2nd level
mov [si].Level2, ax ; put in MSCB
mov [si].Lvl1Mplr, dx ; put in MSCB
mov ax, es:[di].THLvl2Mplr ; get 2nd level multiplier
mov [si].Lvl2Mplr, ax ; put in MSCB
.else
pop es ; restore es
mov es:[bx].PktStatus, INVALIDPARMS ; Invalid Parm Error
push es ; save es again
.endif
pop es ; restore es
call EnableMouse ; enable the mouse
ret
IOMW_TH EndP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_PS (56h)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_PS, set pointer image shape.
;*
;* Builds a pointer image definition record from
;* user input data. Parmlist address points to the
;* new pointer image buffer. Data address field
;* points to the new pointer definition record.
;* The new record is passed to the Pointer Draw DD.
;* If the new pointer is valid then Pointer Draw
;* will update the session control block with the
;* new pointer image data.
;*
;* ENTRY POINT : IOMW_PS LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's pointer image is changed. Foreground
;* pointer image on the display will change.
;*
;* RETURN-ERROR : Session's pointer image data is unchanged,
;* Request Block Status field set to error code.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: None.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: Ptr Draw(RemovePointer, DrawPointer,
;* GetPointerMem, FreePointerMem) DDDD(Enable_-
;* Device, Disable_Device)
;*
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_PS (set session pointer shape)
;*
;* call DDDD(Disable_Device) to disable the mouse
;* IF <current display mode is supported>
;* IF <caller is foreground AND
;* ptr draw routines used AND
;* ptr overide flag is off AND
;* there is no ptr collision>
;* call Ptr Draw(RemovePointer) to do unconditional remove
;* set flag for redraw required
;* ENDIF
;* call Ptr Draw(FreePointerMem) to release current pointer image
;* set up ptr definition record from user input image and definition
;* data areas
;* call Ptr Draw(GetPointerMem) to allocate new pointer image
;* IF <new pointer image allocated OK>
;* IF <redraw required>
;* call Ptr Draw(DrawPointer) to draw new ptr image
;* ENDIF
;* ELSE
;* set parameter error
;* ENDIF
;* ELSE
;* set parameter error
;* ENDIF
;* call DDDD(Enable_Device) to enable the mouse
;* return
;*
;* EndSub IOMW_PS
;*
;************************************************************************
IOMW_PS PROC near
TempES equ <(word ptr [bp-2])> ; For ES register
TempBX equ <(word ptr [bp-4])> ; For BX register
Enter 4,0
mov TempES, es ; Save Request Block
mov TempBX, bx ; Address
call DisableMouse ; Hold Mouse Interrupts for update
test [si].D_Status, USS_Mode ; See if display mode is supported.
.if <z> NEAR ; If so then OK to continue
mov bl, fs:FgndSessn ; Get forground screen group #
call PtrDrawCheck
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; Get forground screen group #
push cx ; Save current reg value
mov cx, 0 ; Flag Remove Ptr Required
RemovePointer ; Hide Mouse Pointer Image
pop cx ; Restore previous reg value
.endif ; Collision Area Test
mov al, fs:CallSessn ; Get forground screen group #
FreePointerMem ; Call Ptr Draw DD to free buffers
lea di, fs:Ptr_Rec ; Setup DI to point to Ptr_Rec in DS
; Load Ptr Rec for Ptr Draw DD call
mov bx, TempBX ; Restore Request Block Offset
; Ptr Rec Addr1 = Pointer Image Buf
mov ax, es:[bx.GIOParaPacx] ; Get caller's Parmlist Parm addr
mov word ptr fs:[di].Addr1, ax ; High word, & put in Ptr Rec
mov ax, es:[bx.GIOParaPacx+2] ; Get caller's ParmList Parm addr
mov word ptr fs:[di].Addr1[2], ax ; Low word, & put in Ptr Rec
; Ptr Rec Addr2 = Ptr Def Record
mov ax, es:[bx.GIODataPacx] ; Get caller's Data Parm address
mov word ptr fs:[di].Addr2, ax ; High word, & put in Ptr Rec
mov ax, es:[bx.GIODataPacx+2] ; Get caller's Data Parm address
mov word ptr fs:[di].Addr2[2], ax ; Low word, & put in Ptr Rec
push fs
pop es ; Set ES:DI to point to Ptr_Rec
mov al, fs:CallSessn ; Get foreground screen group #
GetPointerMem ; Call Ptr Draw DD to get memory
.if <ax eq 0> ; If GetPointerMem worked then
mov bl, fs:FgndSessn ; Get forground screen group #
call PtrDrawCheck ; see ptr drawing OK
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; Get forground screen group #
DrawPointer ; Ensure Mouse Ptr is visible
.endif ; New Ptr Collision Test
.else ; If GetPointerMem failed then
ParmErr ; Set ParmErr in Status field
.endif ; GetPointerMem test
.else
ParmErr
.endif
call EnableMouse ; Update done, Allow mouse interrupts
mov es, TempES ; Restore Local Var's
mov bx, TempBX ; Original Contents
Leave ; Clear local Stack variables
ret ; Return to IOCTL Handler Rtn
IOMW_PS ENDP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_DP (57h)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_DP, reset a session's collision area
;* and draw the pointer.
;*
;* Clears the session's collision area definition
;* fields. If the caller is the FG session then the
;* pointer is drawn. Ints are disabled during
;* access to the collision area definition fields.
;*
;* NOTE : This function requires no input/output parameters.
;*
;* ENTRY POINT : IOMW_DP LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's collision area is cleared. (always)
;*
;* RETURN-ERROR : N/A
;*
;* EFFECTS: Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: NONE.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: Ptr Draw(DrawPointer), DDDD(Enable_Device,
;* Disable_Device)
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_DP (remove session collision area and draw pointer)
;*
;* call DDDD(Disable_Device) to disable the mouse
;* set collision area flags to NO collision area defined
;* IF <ptr draw routines used AND
;* display mode supported AND
;* caller is foreground AND
;* ptr overide is OFF>
;* call Ptr Draw(DrawPointer) to draw pointer image
;* ENDIF
;* call DDDD(Enable_Device) to enable the mouse
;* return
;*
;* EndSub IOMW_DP
;*
;************************************************************************
IOMW_DP proc near
push bx
call DisableMouse ; Hold Mouse Interrupts
mov [si].Area_Flags, 0000h ; Clear collision area field flags
mov bl, fs:FgndSessn ; Get forground screen group #
call PtrDrawCheck
.if <ax eq 0> ; if draws are OK
mov al, fs:CallSessn ; Get forground screen group #
DrawPointer ; Draw Mouse Pointer image
.endif
call EnableMouse ; Update done, Allow mouse interrupts
pop bx
ret ; Return to IOCTL Handler Rtn
IOMW_DP ENDP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_RP (58h)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_RP, define a collision area.
;*
;* The parmlist field in the request block points to
;* a 4 word structure which defines the collision
;* area. 1st two words is the upper left coordinates
;* 2nd two words is the lower right coordinates.
;* If the two points are in reversed order then they
;* are swapped. The defined collision are must be
;* in the display coordinate space. The pointer
;* image will be removed if the caller is the FG and
;* the pointer is in the new collision area. It will
;* be redrawn if the pointer position is outside the
;* new collision area.
;*
;* ENTRY POINT : IOMW_RP LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's collision area definition fields
;* are updated, and FG pointer image may be
;* removed or restored.
;*
;* RETURN-ERROR : The screen group's collision area data remains
;* unchanged, an error return code is set in the
;* Request Block Status field.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: None.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: Ptr Draw(RemovePointer, DrawPointer),
;* DDDD(Disable_Device, Enable_Device)
;* DevHelps: VerifyAccess.
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_RP (define session collision area)
;*
;* IF <user defined values in reverse order>
;* switch user defined coordinates
;* ENDIF
;*
;* IF <user defined coords are inside display mode type limits>
;* call DDDD(Disable_Device) to disable the mouse
;* IF <ptr draw routines are used AND
;* display mode is supported AND
;* caller is foreground AND
;* ptr overide is OFF>
;* set flag that drawing is OK
;* IF <there is no ptr collision>
;* call Ptr Draw(RemovePointer) to unconditionally remove ptr
;* ENDIF
;* ENDIF
;* define collsion area with user defined collision area
;* IF <drawing is OK AND
;* there is no collision>
;* call Ptr Draw(DrawPointer) to draw the pointer
;* ENDIF
;* call DDDD(Enable_Device) to enable the mouse
;* ELSE
;* set parameter error
;* ENDIF
;*
;* return
;*
;* EndSub IOMW_RP
;*
;***********************************************************************
IOMW_RP PROC near
TempES equ <(word ptr [bp-2])> ; For ES register
TempBX equ <(word ptr [bp-4])> ; For BX register
Enter 4,0
mov TempES, es ; Save Request Block Address
mov TempBX, bx
les di, es:[bx].GIOParaPack ; load selector to data area
test [si].MType, Graphics
.if nz ; If display in Graphics mode
mov cx, [si].GRow_Res ; Get Graphics resolution values
mov dx, [si].GCol_Res ; for parm checking
.else ; If display in Text mode then
mov cx, [si].TRow_Res ; Get Text resolution values
mov dx, [si].TCol_Res ; for parm checking
.endif ; Display mode test
dec cx ; Get Resolution Values as
dec dx ; Base: 0 thru (Res - 1)
mov ax, es:[di].R_Pos ; Get Input Row Coords
mov bx, es:[di].R_End ; For Collision Area
.if <ax a bx> ; If 1st Row coord larger
mov es:[di].R_Pos, bx ; Than 2nd Row coord then
mov es:[di].R_End, ax ; Reverse the defined order
.endif ; Of the Row coordinates
mov ax, es:[di].C_Pos ; Get Input Col Coords
mov bx, ES:[di].C_End ; For Collision Area
.if <ax a bx> ; If 1st Col coord larger
mov es:[di].C_Pos, bx ; Than 2nd Col coord then
mov es:[di].C_End, ax ; Reverse the defined order
.endif ; Of the Col coordinates
;*
;* Check the defined collision area for valid screen coordinates
;*
.if <es:[di].R_Pos be cx> NEAR AND ; Check starting row & col pos
.if <es:[di].C_Pos be dx> NEAR AND
.if <es:[di].R_End be cx> NEAR AND ; Check Ending row & col pos
.if <es:[di].C_End be dx> NEAR
call DisableMouse ; Hold Mouse Interrupts
mov bl, fs:FgndSessn ; Get forground screen group #
call PtrDrawCheck
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; Get forground screen group #
push cx ; Save current reg value
mov cx, 0 ; Flag Remove Ptr Required
RemovePointer ; Hide Mouse Pointer Image
pop cx ; Restore previous reg value
.endif ; Collision Area Test
mov [si].Area_Flags, 0001H ; Update SG CB Collision Area
mov ax, es:[di].R_Pos ; With caller's record values
mov [si].Area_Top, ax
mov ax, es:[di].C_Pos
mov [si].Area_Left, ax
mov ax, es:[di].R_End
mov [si].Area_Bot, ax
mov ax, es:[di].C_End
mov [si].Area_Right, ax
mov bl, fs:FgndSessn ; Get forground session #
call PtrDrawCheck ; see it ptr draws OK
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; Get forground screen group #
DrawPointer ; Ensure Mouse Ptr is visible
.endif ; New Ptr Collision Test
call EnableMouse ; Update done, Allow Mouse Intrpts
.else ; If Collision Area Parms Invalid
ParmErr ; Set Error Return in Status field
.endif ; Collision Area Parm tests
mov bx, TempBX ; Restore ES:BX to Request
mov es, TempES ; Block Address
sti ; Data updated, allow interupts
Leave
ret ; Return to IOCTL Handler Rtn
IOMW_RP ENDP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_SP (59h)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_SP, set pointer position.
;*
;* The parmlist field address field in the requset
;* block points to a 2 word structure. The 1st word
;* is the new X coordinate, 2nd word is the new
;* column coordinate. The new pointer position must
;* within the display coordinate space. If the
;* caller is the foreground then the pointer is
;* hidden and redrawn. Ints disabled while updating.
;*
;* ENTRY POINT : IOMW_SP LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's pointer position is updated.
;*
;* RETURN-ERROR : Session pointer position unchanged, request
;* block status field set to error code.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: None.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: Ptr Draw(RemovePointer, DrawPointer), DDDD(
;* Disable_Device, Enable_Device)
;* DevHelps: None
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_SP (set session pointer position)
;*
;* get new pointer pos
;* IF <new pointer pos is inside current display mode resolution>
;* call DDDD(Disable_Device) to disable the mouse
;* IF <ptr draw routines are used AND
;* current display mode supported AND
;* caller is foreground AND
;* session switch not in progress AND
;* there is no ptr collision>
;* call Ptr Draw(RemovePointer) to unconditionally remove the ptr
;* ENDIF
;* set new pointer pos in MSCB
;* IF <ptr draw routines are used AND
;* current display mode supported AND
;* caller is foreground AND
;* session switch not in progress AND
;* there is no ptr collision>
;* call Ptr Draw(DrawPointer) to draw the ptr at the new position
;* ENDIF
;* call DDDD(Enable_Device) to enable the mouse
;* ELSE
;* set parameter error
;* ENDIF
;* return
;*
;*EndSub IOMW_SP
;*
;***********************************************************************
IOMW_SP proc near
TempES equ <(word ptr [bp-2])> ; temp storage for es
TempBX equ <(word ptr [bp-4])> ; temp storage for bx
Enter 4,0
mov TempES, es ; Save Request Block Address
mov TempBX, bx
les di, es:[bx].GIOParaPack ; load selector to data area
mov cx, es:[di].Parm1 ; Get new Row coordinate
mov dx, es:[di].Parm2 ; Get new Col coordinate
test [si].Mtype, Graphics ; Check current Display Mode
.if z ; If in Text Mode then
mov ax, [si].TRow_Res ; Get text mode row resolution
mov di, [si].TCol_Res ; Get text mode col resolution
.else ; If in Graphics Mode then
mov ax, [si].GRow_Res ; Get graphics mode row resolution
mov di, [si].GCol_Res ; Get graphics mode col resolution
.endif ; Display Mode Tests
;*
;* Now check the new position to make sure that it is in the current
;* display mode limits. If so then if the old pointer position is visible
;* it is removed. Then the new position is set and the image drawn if
;* it should be visible.
;*
.if <cx ge 0> AND ; Validate new Ptr Row coordinate
.if <cx lt ax> AND ; X >= 0 AND X < current row res
.if <dx ge 0> AND ; Validate new Ptr Col coordinate
.if <dx lt di> ; Y >= 0 AND Y < current col res
call DisableMouse ; Hold Mouse Interrupts
mov bl, fs:FgndSessn ; Get current foreground SG #
call PtrDrawCheck ; see if pointer draw op is OK
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; Get forground screen group #
push cx ; Save current reg value
mov cx, 0 ; Flag Remove Ptr Required
RemovePointer ; Hide Mouse Pointer Image
pop cx ; Restore previous reg value
.endif ; Collision Area Test
mov [si].Ptr_Row_Pos, cx ; Update pointer position
mov [si].Ptr_Col_Pos, dx ; Fields in SG CB
mov bl, fs:FgndSessn ; Get current foreground SG #
call PtrDrawCheck
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; Get forground screen group #
DrawPointer ; Ensure Mouse Ptr is visible
.endif ; New Ptr Collision Test
call EnableMouse ; Data Updated, Allow Mouse Ints
.else ; If input values are invalid then
ParmErr ; Set Invalid Parm Error
.endif ; Input Ptr Coord Tests
mov bx, TempBX ; Restore ES:BX to Request
mov es, TempES ; Block Address
Leave
ret ; Return to IOCTL Handler Rtn.
IOMW_SP ENDP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_SD (5A)
;*
;* DESCRIPTION : Performs the mouse IOCtl function
;* IOMW_SD, register a Pointer Draw DD for a
;* protect mode session.
;*
;* The parmlist field of the request block points to
;* a 3 word structure. The 1st two words is the FAR
;* address to the Pointer Draw entry point. The 3rd
;* word is the Pointer Draw data selector. The data
;* list field points to a 3 word structure. 1st is
;* the structure length (6), 2nd is display config #
;* the pointer is switching to, 3rd is who the call
;* is coming from (0 = app, 1 = BVS). This IOCtl is
;* generated on every MOUOPEN call. For BVS the ptr
;* is always removed and the set mode window flag is
;* set. This is the beginning of a set mode
;* sequence if BVS is the caller.
;*
;* A word is allocated on the local stack frame that
;* is used as a local status word. The bits are
;* defined as follows: bits 15-4, reserved, bit 3 -
;* set if configuration number is changing, bit 2 -
;* set if ptr image was removed and may need to be
;* redrawn, bit 1 - set if ptr draw address is
;* changing, bit 0 - set if BVS is the caller.
;*
;* ENTRY POINT : IOMW_SD LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's Pointer Draw entry point changed.
;*
;* RETURN-ERROR : N/A
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: CheckAccess, GetCfgDataOffset, GetExtModeData.
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: Ptr Draw(DrawPointer, RemovePointer, Check-
;* ModeProtect), DDDD(Enable_Device, Disable_-
;* Device)
;* Dev Helps: None
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_SD (register ptr draw routine for a session)
;*
;* check access to data area (caller information from BVS)
;* IF <data list pointer is not NULL>
;* IF <length of data area is 6>
;* IF <caller value is 1>
;* set status to BVS is the caller
;* set setmode window flag
;* ENDIF
;* get config # from data area
;* IF <config # is new/different from current>
;* set status to config # is changing
;* save new config #
;* ENDIF
;* ENDIF
;* ENDIF
;*
;* get new ptr draw entry point
;* IF <new entry pt is different from current>
;* set status to show ptr draw is changing
;* ENDIF
;* IF <(BVS is caller OR ptr draw changing OR config # changing) AND
;* Ptr draw routines are used for drawing AND
;* display mode is supported AND
;* caller is foreground AND
;* ptr overide flag is off AND
;* there is no collision>
;* call Ptr Draw(RemovePointer) to unconditionally remove the ptr
;* set status to show redraw may be needed
;* ENDIF
;*
;* IF <ptr draw changing OR config # changing>
;* assign new ptr draw entry point
;* IF <BVS is NOT the caller>
;* IF <display mode is currently available>
;* IF <config # is changing>
;* call GetCfgDataOffset to get new cfg data offset
;* IF <offset returned>
;* store sel:off in MSCB for ptr draw use
;* ELSE
;* 0 out sel:off to show no config data available
;* ENDIF
;* ENDIF
;* build a display mode record
;* call Ptr Draw(CheckModeProt) to check curren mode
;* IF <current display mode is supported>
;* set device status to supported mode
;* IF <pointer image needs to be redrawn>
;* call Ptr Draw(DrawPointer) to draw the ptr
;* ENDIF
;* ELSE
;* set device status to unsupported mode
;* ENDIF
;* ENDIF
;* ENDIF
;* ENDIF
;*
;* return
;*
;* EndSub IOMW_SD
;*
;***********************************************************************
IOMW_SD PROC near
?frame = 0 ; Get Local/Temp Stack Frame
LocalVar TempES, WORD ; For ES register
LocalVar TempBX, WORD ; For BX register
LocalVar TempSI, WORD ; For SI register
LocalVar TempDS, WORD ; for ds register
LocalVar Status, WORD ; for local status
LocalVar NewCfg, WORD ; for new config number
;*
;* These equates are used to set bits in the Status word.
;*
BVSCall EQU 0001h
PtrChange EQU 0002h
PtrRedraw EQU 0004h
CfgChange EQU 0008h
EnterProc
mov TempES, es ; Save Request Block Address
mov TempBX, bx
mov TempSI, si ; Save Input SG CB Offset
mov TempDS, ds ; save ds
mov Status, 0 ; set status to 0
call DisableMouse ; disable the mouse
;*
;* Check access to data area. First check and see that we can load the
;* passed selector offset. This is for compatibilty because we never checked
;* to make sure that the pointer was a dword of 0's in the past. If that
;* access fails then we assume that an old subsystem is calling and will
;* not set the BVS calling status bit. If the access is OK then we will
;* check access to the data area. If access then fails to the data area,
;* we will fail with a parameter error.
;*
test word ptr es:[bx].GIODataPack+2, 0fff8h
.if <nz>
les di, es:[bx].GIODataPack
.if <es:[di].DLLen eq 6> ; if valid length field
.if <es:[di].DLCaller eq 1> ; if BVS is the caller
or Status, BVSCall ; then set BVS caller bit
.endif ;
mov bx, es:[di].DLCfg ; get new config number
.if <bx ne [si].Cur_Config> ; if new config is different
or Status, CfgChange ; show that cfg has changed
mov NewCfg, bx ; save new config #
.endif ; end config changed test
.endif ; ignore invalid length
.endif ;
;*
;* Now set flag indicating that ptr draw is changing or not and set the
;* set mode window active if BVS is the caller. Also remove the pointer if
;* needed. Removal is done by current pointer draw, not new one.
;*
mov es, TempES ; restore request packet sel
mov bx, TempBX ; restore offset
les di, es:[bx].GIOParaPack ; get address to ptr draw data
mov ax, word ptr es:[di].Addr1+2 ; get current ptr entry
mov dx, word ptr es:[di].Addr1 ; point
mov cx, word ptr es:[di].Addr2 ; data selector
push ax
push dx
push cx
.if <ax ne <word ptr [si].Screen_Entp+2>> OR ; if ptr entry pt
.if <dx ne <word ptr [si].Screen_Entp>> OR ; has changed, or
.if <cx ne <word ptr [si].Screen_DSeg>> ; data sel changed
or Status, PtrChange ; then set change status
.endif ;
mov bl, fs:FgndSessn ; get foreground session
test Status, BVSCall+PtrChange+CfgChange ; BVS caller or ptr draw
.if nz ; add and to change back ; has changed or cfg change
call PtrDrawCheck
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; set foregrnd session
push cx ; save cx
xor cx, cx ; unconditional remove
RemovePointer ; Hide Mouse Pointer Image
pop cx ; restore cx
or Status, PtrRedraw ; ptr needs to be redrawn
.endif ; Collision Area Test
.endif
pop cx
pop dx
pop ax
;*
;* Now register the new pointer draw if either the ptr draw DD or the
;* display configuration number changed. If BVS is not the caller then
;* verify the current mode data with the new pointer draw.
;*
test Status, PtrChange+CfgChange ; if ptr draw or cfg change
.if nz NEAR ; then register new one
mov word ptr [si].Screen_Entp, dx ; save in session CB
mov word ptr [si].Screen_Entp+2, ax ; save in session CB
mov word ptr [si].Screen_DOff, 0 ; zero offset
mov word ptr [si].Screen_DSeg, cx ; save in session CB
;*
;* Now see if the configuration has changed. If so then store the
;* new configuration data information in the session control block.
;* If BVS is the caller then a subsequent set mode will be done and
;* this new configuration data will be checked. If BVS is not the
;* caller then a check of the current mode is forced. If no mode
;* data is available then leave the mouse in its current state.
;*
test Status, CfgChange ; see if cfg changed
.if <nz> ; if it has then
mov bx, NewCfg ; get new config num
call GetCfgDataOffset ; go get the offset
.if <nc> ; if offset found then
mov [si].Cur_Config, bx ; save new config number
mov [si].CfgOffset, dx ; put data offset in CB
mov [si].CfgSelector, fs ; put selector in CB
.else ; offset not found
mov [si].CfgOffset, 0 ; zero out the config data
mov [si].CfgSelector, 0 ; pointer in the CB
.endif
.endif
;*
;* Now see if BVS is the caller. If not then build a mode data
;* structure and call PtrDraw to check it.
test Status, BVSCall ; see if BVS is the caller
.if z NEAR ; if not then verify mode
.if <[si].MLength ne 0> NEAR ; if mode data available
push fs
pop es ; es pts to our data seg
mov di, offset Modes ; get offset of mode struc
push di ; save offset of mode struc
mov cx, BaseModeLen ; get Base Mode data length
add si, Mlength ; offset to mode data in CB
cld ; go forwart
rep movsb ; move base mode data
mov cx, ExtModeLen ; max len of extended data
mov al, fs:CallSessn ; calling session
xor ah, ah ; convert to word value
call GetExtModeData ; get the extended mode data
pop di ; restore offset mode struc
mov si, TempSI ; restore CB offset
mov ds, TempDS ; restore our data selector
CheckModeProtect ; verify data with new ptr draw
.if <ax eq 0> ; If Mode is supportable then
and [si].D_Status, NOT USS_Mode ; show supported mode
mov bl, fs:FgndSessn
test [si].D_Status, PtrDraw ; If Ptr Draw Rtns Used
call PtrDrawCheck
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; Get caller's screen group #
DrawPointer ; Ensure Mouse Ptr is visible
.endif ; New Ptr Collision Test
.else ; Mode is unsupported so
or [si].D_Status, USS_Mode ; set unsupported mode
.endif ; supported mode tests
.endif
.endif ; BVS is caller test
.endif ; ptr draw or cfg change test
sd1:
mov es, TempES ; restore registers
mov bx, TempBX
mov si, TempSI ; Save Input SG CB Offset
mov ds, TempDS ; save ds
test Status, BVSCall ; see if BVS is the caller
.if nz ; if so then this is the
or [si].Ptr_Flags, SM_WinFlag ; start of set mode sequence
.endif ;
call EnableMouse
LeaveProc ; Clear local Stack variables
RET ; Return to IOCTL Handler Rtn
IOMW_SD ENDP
;**********************************************************************
;*
;* FUNCTION NAME : IOMW_DS (5C)
;*
;* DESCRIPTION : Performs the Mouse IOCtl function
;* IOMW_DS, set device status flags.
;*
;* The parmlist field in the request block points to
;* a new 1-word device status flag. See Tech Ref
;* for definition of each flag. If singleQ mode is
;* activated then mouse "attaches" itself to the
;* singleQ device driver. Reserved bits may not be
;* set. Any further request to start singleQ mode
;* by the same caller is ignored.
;*
;* ENTRY POINT : IOMW_DS LINKAGE: CALL NEAR
;*
;* INPUT : ES:BX points to the request block.
;* DS:SI has offset to current session control block.
;*
;* RETURN-NORMAL : Session's device status flags are updated.
;*
;* RETURN-ERROR : Session's device status flags are unchanged,
;* status field in request block set to error code.
;*
;* EFFECTS : Stack is clean on return. Regs not preserved.
;*
;* INTERNAL REFERENCES:
;* ROUTINES: GetExtModeData, FlushMonChain
;*
;* EXTERNAL REFERENCES:
;* ROUTINES: Ptr Draw(RemovePointer, CheckModeProtect),
;* DDDD(Enable_Device, Disable_Device), SQ DD
;* DevHlps: AttachDD, ProcRun
;*
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_DS (set session device status)
;*
;* call DDDD (Disable_Device) to disable the mouse
;* IF <new device status mask is valid>
;* IF <new device status mask is different>
;*
;*
;*** Enable/Disable ptr draw routines.
;*
;*
;* IF <ptr draw routines are currently used>
;* IF <ptr draw routines are being disabled AND
;* display mode is supported AND
;* caller is foreground AND
;* pointer overide is OFF AND
;* there is no collision>
;* call Ptr Draw(RemovePointer) unconditional remove
;* ENDIF
;* ELSEIF <ptr draw routines are being enabled>
;* build a display mode data record
;* set ptr draw routines used in device status
;* call Ptr Draw(CheckModeProt) to check mode
;* IF <display mode is supported>
;* set device status to supported mode
;* ELSE
;* set device status to unsupported mode
;* ENDIF
;* set ptr draw routines not used in device status
;* ENDIF
;*
;*
;*** data report format.
;*
;*
;* IF <data report format is changing>
;* call FlushMonChain to flush monitors and event queue
;* IF <flush failed>
;* set flag for fail set device status
;* ENDIF
;* ENDIF
;*
;*
;*** SingleQ mode enable/disable
;*
;*
;* IF <activate SQ mode request>
;* IF <no process has activated SQ mode>
;* IF <SQ mode is not active>
;* call Device_Help(AttachDD) to attach to SQDD
;* IF <attach worked>
;* call SQDD(initialize) for mouse data
;* IF <initialize call worked>
;* set SQ ownership PID to current PID
;* IF <Queue flush not in progress>
;* call FlushMonChain to flush data
;* ELSE
;* set flag indicating queue flush done
;* ENDIF
;* IF <queue flush was done>
;* IF <thread blocked on mouse data>
;* call Device_Help(ProcRun) to wake up
;* ENDIF
;* ENDIF
;* ELSE
;* set flag to fail set device status
;* ENDIF
;* ELSE /* attach failed */
;* set flag to fail set device status
;* ENDIF
;* ENDIF
;* ELSE /* SQ has a process owner */
;* IF <calling PID is not same as SQ owner PID>
;* set flag for invalid parameters
;* ENDIF
;* ENDIF
;* ELSE /* could be a reset SQ mode request */
;* IF <SQ mode is active AND
;* caller ownes SQ mode>
;* call SQDD(endinput) to end mouse input
;* ENDIF
;* ENDIF
;*
;*
;*** set cmpletion status
;*
;*
;* IF <failure indicated>
;* set general failure
;* ELSEIF <parameter error indicated>
;* set parameter error
;* ELSE
;* set new device status
;* ENDIF
;*
;* ENDIF /* new status same as old */
;* ELSE /* new status is invalide */
;* set parameter error
;* ENDIF
;*
;* call DDDD(Enable_Device) to enable the mouse
;* return
;*
;* EndSub IOMW_DS
;*
;***********************************************************************/
IOMW_DS proc near
TempES equ <(word ptr[bp-2])> ; temp storage
TempBX equ <(word ptr[bp-4])>
SetStatus equ <(word ptr[bp-6])>
Enter 6,0
mov TempES, es ; Save Request Block address
mov TempBX, bx
mov SetStatus, 0 ; Clear Internal Error Flag
les di, es:[bx].GIOParaPack ; load selector to data area
call DisableMouse ; Hold Mouse Interrupts
mov cx, [si].D_Status ; Get SG device status field flags
mov ax, word ptr es:[di] ; Get new SG dev status user flags
;*
;* First make sure that the new status is valid. If so then see if it is
;* changing. If so then continue
;*
test ax, NOT DevStatSetMax ; see if any non settable bits set
.if <z> NEAR ; If not and the new mask
.if <ah ne ch> NEAR ; is different
;*
;* If pointer draw calls for drawing operations are currently acitve
;* and the new device status is disabling them then remove the current
;* pointer image.
;*
test [si].D_Status, PtrDraw ; Check Ptr Draw Usage Flag
.if <z> ; If Ptr Draw is Active then
mov bl, fs:FgndSessn ; Get FG SG ID #
test ax, PtrDraw ; Check New Ptr Draw Flag Bit
.if <nz> ; If we are disabling it
call PtrDrawCheck ; go see if we can call ptr draw
.if <ax eq 0> ; If so then
mov al, fs:CallSessn ; Get forground screen group #
push cx ; Save current reg value
xor cx, cx ; Flag Remove Ptr Required
RemovePointer ; Hide Mouse Pointer Image
pop cx ; Restore previous reg value
.endif ; Collision Area Test
.endif ; Ptr Image Visibility Tests
;*
;* If pointer draw calls are disabled and the new device status is
;* enabling them then we must check the current mode data to make
;* sure that we can draw. The reason is that a mode may be only
;* partially supported when ptr draw calls are disabled, but un-
;* supported when they are enabled.
;*
.else ; else ptr draw is currently not active
test ax, PtrDraw ; Is ptr draw being enabled ?
.if z ; Yes, is so check the display mode
push di
push es
push fs ; save our data sel
push fs ; setup es:di as destination
pop es
mov di, offset Modes
push di
push si
add si, MLength ; set ds:si as src of base mode data
mov cx, BaseModeLen ; base mode data lenght in bytes
cld ; go forward
rep movsb ; move base mode data
mov cx, ExtModeLen ; length of extended mode data
mov al, fs:CallSessn ; calling session
xor ah, ah ; make word
call GetExtModeData ; get the extended mode data
pop si ; restore saved registers
pop di
CheckModeProtect ; go check the mode data
pop fs
pop es
pop di
.if <ax eq 0> ; was mode supported
and [si].D_Status, NOT USS_Mode ; display mode valid
.else ; mode is unsupported
or [si].D_Status, USS_Mode ; set unsupported mode
.endif ; end mode supported test
.endif ; end ptr draw enabled test
.endif ; Ptr Draw Rtn Override Test
;*
;* Now see if the reporting format is changing. This would be from
;* mickey data to screen position or the other way. If the format
;* is changing then flush the monitor chain to get rid of any old
;* formatted data.
;*
mov ax, word ptr es:[di] ; Get new SG dev status user flags
mov cx, [si].D_Status ; Get SG device status field flags
and ax, MickeyData ; Check Data Format Flag Bits
and cx, MickeyData ; For both Current & New Masks
.if <ah ne ch> ; If Data formats are different
call FlushMonChain ; Flush the monitor chain and evnt que
.if c ; If MonFlush failed then
mov SetStatus, 1 ; Flag General Failure
.endif ; MonFlush Completion Tests
.endif ; Data Format Change Test
;*
;* Now determine is single queue mode is being enabled or disabled.
;*
mov ax, word ptr es:[di] ; Get new dev status flags
;*
;* If SQ mode is being activated then attach to the singleq device
;* driver and initialize the IDC interface. If this works then the
;* monitor chain is flushed. If a process is blocked on data then
;* it is unblocked, which will cause an error to be returned on the
;* read request (part of another thread) since SQ mode will be active.
;*
test ax, SQ_Mode ; Get SQ Input Mode Flag Mask
.if nz NEAR ; If SQ Activate Request then
.if <fs:SQ_Pid eq 0> NEAR ; no active SQ yet
test [si].D_Status, SQ_Mode ; Check SQ Mode Flag Bit
.if z NEAR ; If SQ Input Mode InActive
push di ; Save New Mask Offset
lea bx, fs:SQDDName ; Offset for SQ DD Name
lea di, fs:SQDD ; Offset to Data Record
mov dl, DevHlp_AttachDD ; DevHelp Function Number
call fs:Device_Help ; Invoke AttachDD Function
pop di ; Restore New Mask Offset
.if nc NEAR ; If Attach DD worked then
mov ax, fs:Eq_Length ; Get Event Queue Byte Size
mov cx, ElRec_Size ; Get Que Element Rec Size
div cl ; Calculate # of Elements
cbw ; Get Element Count as Word
mov cx, Que_Header_Size ; Get Element Header Size
mul cl ; Calc # Header Bytes
add ax, fs:Eq_Length ; Add required Byte Count
mov cx, ax ; Total Byte Cnt
mov bx, 0001H ; SQ DD Init & FIFO Buf
mov ax, 0200H ; Mouse DD calling
push es ; Save User Data Selector
push fs:SQDD.ProtDS ; Get SQ DD DS Selector
pop es ; Load into ES for call
call dword ptr fs:SQDD.ProtEntry ; Invoke SQ DD Init Func
pop es ; Restore User Data Selector
.if <ax eq 0> NEAR ; If SQ Init worked then
mov cx, fs:CallPID ; get callers PID
mov fs:SQ_Pid, cx ; Save in SQ PID
test [si].D_Status, Q_Flush ; Check Flush Bit
.if z ; AOK to Flush Que
call FlushMonChain ; go flush mon chain
.else ; If Flush in Progress
clc ; Set DevHlp worked Flag
.endif ; Event Que Flush Tests
.if nc ; If MonFlush worked
test [si].D_Status, Block_Mask ; Check Block Bit
.if nz ; If Thread(s) Blocked
mov bx, ds ; SG que addr low word
mov ax, [si].E_Queue ; SG que addr high word
mov dl, DevHlp_ProcRun ; Specify DevHlp Func
call fs:Device_Help ; Invoke Run Function
.endif ; Blocked Thread test
.else ; If MonFlush failed then
mov SetStatus, 1 ; Flag General Failure
.endif ; MonFlush Completion Tests
.else ; If SQ Init failed then
mov SetStatus, 1 ; Flag General Failure
.endif ; SQ DD Init Function Tests
.else ; If Attach DD failed then
mov SetStatus, 1 ; Flag General Failure
.endif ; Attach DD Tests
.endif ; SQ Mode InActive Test
.else ; SQ already active then
mov ax, fs:SQ_Pid ; Get PID of SQ owner
.if <ax ne fs:CallPID> ; If Caller not owner then error
mov SetStatus, 2 ; Flag Invalid parameter
.endif ; Caller not owner test
.endif ; Shell SQ ID Tests
.else ; If not a Set SQ Mode request
mov ax, fs:SQ_Pid ; Get single queue PID
.if <fs:CallPID eq ax> AND ; See if caller owns SQ
test [si].D_Status, SQ_Mode ; Check SQ Mode Flag Bit &
.if nz ; If SQ Input Mode Active
mov ax, 0200H ; Specify Mouse DD calling
mov bx, 0003H ; Specify SQ DD End Function
push es ; Save User Data Selector
push fs:SQDD.ProtDS ; Get SQ DD DS Selector
pop es ; Load into ES for call
call dword ptr fs:SQDD.ProtEntry ; Invoke SQ DD End Func
pop es ; Restore User Data Selector
mov word ptr fs:SQ_Pid, 00H ; Reset SQ Pid as available
.endif ; End SQ Input Mode Tests
.endif ; SQ Input Mode Activate Tests
;*
;* If every thing was OK then set the new device status
;*
.if <SetStatus eq 0> ; If Mask Bits are verified then
mov ax, word ptr es:[di] ; Get new SG dev status user flags
mov cx, [si].D_Status ; Get SG device status field flags
mov al, cl ; Keep current Status Flags low byte
mov [si].D_Status, ax ; Set new SG Status Flags high byte
.elseif <SetStatus eq 1> ; If General code failure then
GenFail ; Flag General Failure in code
.elseif <SetStatus eq 2> ; If Invalid Parm error then
ParmErr ; Flag Invalid Mask Parameter
.endif ; Mask Processing Verifications
.endif
.else ; Non settable bits where set
ParmErr ; Flag user parameter error
.endif ; New Mask Tests
call EnableMouse ; Allow Mouse Interrupts
mov es, TempES ; Restore Request Block address
mov bx, TempBX
Leave ; Clear Local stack frame
ret ; Return to Generic IOCtl Handler Rtn
IOMW_DS ENDP
;**********************************************************************
;
; FUNCTION NAME : IOMW_MD (5Dh)
;
; DESCRIPTION : Performs the Mouse IOCtl function
; IOMW_MD, display mode change is complete.
;
; This IOCtl is used to tell the mouse that the
; mode switch has completed and is now active. If
; the caller is FG then the pointer is redrawn if
; the new mode is supported. This IOCtl works in
; conjunction with IOCtl IOMW_SM (51h).
;
; ENTRY POINT : IOMW_MD LINKAGE: CALL NEAR
;
; INPUT : ES:BX points to the request block.
; SI has offset to current session control block.
;
; RETURN-NORMAL : Always, pointer is redrawn if necessary.
;
; RETURN-ERROR : N/A
;
; EFFECTS : Stack is clean on return. AX, CX, & DI registers
; are changed.
;
; INTERNAL REFERENCES:
; ROUTINES: None.
;
; EXTERNAL REFERENCES:
; ROUTINES: Ptr Draw(DrawPointer)
; DDDD(Enable_Device, Disable_Device)
; DevHelps: NONE.
;
;**********************************************************************
;* PSEUDOCODE :
;*
;* BeginSub IOMW_MD (end of display mode switch)
;*
;* call DDDD(Disable_Device) to disable the mouse
;* clear setmode window flag
;* call Ptr Draw(DrawPointer) to draw ptr if needed
;* call DDDD(Enable_Device) to enable the mouse
;* return
;*
;* EndSub IOMW_MD
;*
;***********************************************************************
IOMW_MD PROC near
push bx ; save bx
call DisableMouse ; disable the mouse
and [si].Ptr_Flags, NOT SM_WinFlag ; Reset sem mode window flag
push si ;emi
mov bl, fs:FgndSessn ; get FG session
call PtrDrawCheck
.if <ax eq 0> ; If Not a Ptr Collision
mov al, fs:CallSessn ; forground screen group #
DrawPointer ; go draw the pointer image
.endif ; Collision Area Test
pop si ;emi
add si, MLength ;emi
xor ch, ch ;emi
mov cl, fs:CallSessn ;emi
xor bh, bh ;emi
mov bl, fs:FgndSessn ;emi
push es ;emi
call Emi_EndVMChange ; cx = caller's session ;emi
; bx = future session ;emi
; ds:si = video data ;emi
pop es ;emi
call EnableMouse ; enable the mouse
pop bx ; restore bx
ret ; return to IOCtl routine
IOMW_MD ENDP
CSEG2 ENDS
END