;       SCCSID = @(#)smgsgfgd.asm       6.8 92/03/20
;       SCCSID = @(#)smgsgfgd.asm       6.8 92/03/20
;       SCCSID @(#)smgsgfgd.asm 6.8 92/03/20
PAGE 60,132                             ;
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************

;**************************************************************************
;
; Source File Name:     SMGSGFGD.ASM
;
; Subroutine Name:      DOSSGSWITCHFOREGROUND
;
; Descriptive Name:     Switch to new Screen group
;
; Function:     Switch to new screen group, and restore contents of new
;               screen group.
;
; Notes:
;       Dependencies:   The queue must be protected by a RAM
;                       semaphore from the calling subroutine.
;
;       Restrictions:   None
;
; Change History:
;  @CJ10  05/04/90  PTR B712103 Hot Keying performance too slow.
;  @D1088 07/07/90  DCR 1088 Add support for special needs.
;  @C39   01/11/91  PTR SM84577 Transparent PopUp over a VDM.
;  @D1200 01/23/91  CJJ, DCR 1200 Call Dos32WriteQueue for Dos32StartSession.
;  B734927 3/20/92  Delete INT3 macro cause MVDM.INC defines it differently.
;  MDLL   01/10/94  BJN Page Tune segments for Merged DLL.
;
; Entry Point:
;       Linkage:  EXTRN DOSSGSWITCHFOREGROUND:NEAR
;                       CALL    DOSSGSWITCHFOREGROUND
;
; Inputs:
;       BL      Action     Value = 0, Switch to specified screen
;                                     group
;                          Value = 1, Switch to next screen group
;                          Value = 2, Skip screen group save for
;                                     for foreground screen group
;                          Value = 3, Skip screen group restore
;                                     for new foreground screen
;                                     group
;                          Value = 4, Do popup switch
;                          Value = 5, End popup switch
;                          Value = 6, Screen group start switch
;       BH      StartAct   Value = 0, Save foreground screen group
;                          Value = 1, Skip save of foreground
;                                     screen
;                          Value = 80H, transparent popup
;       DX      SGID       Screen group number
;       FS:DI   Sel:Off    New foreground SGCB
;       ES:SI   Sel:Off    Previous queue SGCB
;       DS      RDATA
;
; Exit Normal:
;       AX      ReturnCode Value = 0, successful screen group
;                                     switch
; Exit Errors:
;       AX      ReturnCode error_scs_not_session_mgr
;                          error_smg_session_not_found
;
;                          DOSSGDDNOTIFY    errors
;                          DOSSGSWITCHPROC2 errors
;
; Effects:      All other registers preserved.
;
; Internal References:
;                       The following data is in a shared data segment(SDATA)
;
;                       queueselector - active screen group queue selector
;
;          Routines:    DOSSMBASESHELL
;                       DOSSMGETSGQUEUE
;
; External References:
;          Routines:    DOSSEMREQUEST
;                       DOSDEVIOCTL
;                       DOSSGSAVE
;                       DOSSYSTEMSERVICE
;                       DOSSGDDNOTIFY
;                       DOSSGSWITCHPROC2
;                       DOSSGRESTORE
;                       DOSSETFGND
;                       DOSSEMCLEAR
;
;**************************************************************************
ifdef I1
;   IF (Start switch) OR
;   IF (sgid e 0)
;      No validation required
;   ENDIF
;   IF (Transparent popup) AND
;   IF (Outgoing sg is VDM)
;      DOSSMFREEZEVDM (Lock VDM and save video state)
;   ENDIF
;   IF (No errors)
;      IF (Outgoing sg is VDM) OR
;      IF (Outgoing sg is Windowed_VDM)
;        OR sgid with flag
;      ENDIF
;
;      IF (Incoming sg is VDM) OR
;      IF (Incoming sg is Windowed_VDM)
;        OR sgid with flag
;      ENDIF
;
;      Get New debugger SGID
;      IF (valid debugger SGID)
;        IF (New Debugger not Foreground)
;          Set Current Debugger = New Debugger  JUST ALWAYS DO THIS
;        ENDIF
;      ELSEIF (Debugger is present)
;        IF (current debugger not foreground)
;          Get it's SGID
;        ENDIF
;      ENDIF
;
;      IF (Base shell)
;         No validation required
;      ENDIF
;
;      DOSSGDDNOTIFY (Alert screen switcher)
;
;      IF (Transparent popup)
;         Turn off popup flag
;         IF (Outgoing sg is VDM)
;            DOSSMUNFREEZEVDM (Unlock VDM)
;            VIORESTORE (Restore screen)
;         ENDIF
;      ENDIF
;
;      Turn off validation flag for new SG
;      IF (Save foreground)
;        DOSSMNOTIFYDD (Notify registered device drivers of sg switch)
;      ENDIF
;
;      IF (Not do popup request)
;         Set up topmost sg
;         Set up bottommost sg
;      ELSEIF (sgid ne 0)
;         DOSSGSWITCHPROC2 (Switch to new sg)
;      ENDIF
;
;      IF (No error) AND
;      IF (Not a do popup switch)
;         IF (Not a switch with no restore) AND
;         IF (Not a start switch request) AND
;         IF (Not unsave shell) AND
;         IF (Not VDM)
;           DOSSGRESTORE (Tell screen switcher to restore)
;         ENDIF
;         IF (NOT a sg start switch)
;            DOSSMNOTIFYDD (Post Restore Notification)
;         ENDIF
;      ENDIF
;
;   ENDIF
;
;**************************************************************************
else

.386C
    EXTRN PopUpPID                : WORD  ; Popup process ID
    EXTRN BottomMost              : DWORD
    EXTRN CurrentDebugger         : WORD
    EXTRN IncomingDebugger        : WORD
    EXTRN QueueFlags              : WORD
    EXTRN TopMost                 : DWORD
    EXTRN NotDD_DosDev_Data_Len   : WORD ; Data for DosSMNotifyDD       ;@D1088
    EXTRN NotDD_Notification_Type : WORD                                ;@D1088
    EXTRN NotDD_InSG_or_OutType   : WORD                                ;@D1088
    EXTRN NotDD_InType_or_OutSG   : WORD                                ;@D1088
    EXTRN NotDD_OutSG             : WORD                                ;@D1088
    EXTRN NotDD_OutType           : WORD                                ;@D1088
    EXTRN VVideo_Name             : BYTE  ; Virtual Video Device Driver ;@C39

    EXTRN DOSSGDDNOTIFY    : FAR        ; Switch screen groups
    EXTRN DOSSGRESTORE     : FAR        ; Restore screen group state
    EXTRN DOSSGSAVE        : FAR        ; Save screen group state
    EXTRN DOSSGSWITCHPROC2 : FAR        ; Switch process SG
    EXTRN DOSSMNOTIFYDD    : FAR        ; Device driver notification
    EXTRN DOSOPENVDD       : FAR        ; Open VDD                         @C39
    EXTRN DOSCLOSEVDD      : FAR        ; Close VDD                        @C39
    EXTRN DOSREQUESTVDD    : FAR        ; Request VDD to Lock MVDMs        @C39
    EXTRN VIOSAVE          : FAR        ; VioSave foreground MVDM          @C39
    EXTRN VIORESTORE       : FAR        ; VioRestore Popup session         @C39

.xlist
    INCLUDE SMRRDATA.INC
    INCLUDE SMRSGCB.INC

;   ****************************************                               @C39
;   *  Includes and defines for VDD stuff  *                               @C39
;   ****************************************                               @C39
    INCL_DEF             equ   1        ; Needed for basemaca.inc          @C39
    INCL_TYPES           equ   1        ; Needed for basedef.inc           @C39



;   INCLUDE BASEMACA.INC                ; Macros for basedef.inc           @C39
;   INCLUDE BASEDEF.INC                 ; Typedefs for vvd.inc             @C39
    INCLUDE MVDM.INC                    ; JLT - Build Break
    INCLUDE VVD.INC                     ;                                  @C39


.xcref
    INCLUDE STRUC.INC
.cref
    INCLUDE DC1SEGS.INC                                                 ;MDLL
.list

CODE_TUNE4 SEGMENT WORD PUBLIC 'CODE' USE16                             ;MDLL
    ASSUME CS:CONFORM16,DS:RDATA,SS:NOTHING,ES:NOTHING                  ;MDLL

    PUBLIC DOSSGSWITCHFOREGROUND
DOSSGSWITCHFOREGROUND PROC NEAR

    Local_Bytes       EQU 10            ; Local storage                    @C39
    Local_InSGID      EQU SS:[BP][-2]   ; Local variables on stack
    Local_OutSGID     EQU SS:[BP][-4]
    Local_VideoHandle EQU SS:[BP][-8]                                     ;@C39
    Local_SGID        EQU SS:[BP][-10]                                    ;@C39
    VVD_VideoHandle   EQU DWORD PTR SS:[BP][4]                            ;@C39

    Enter Local_Bytes,0
    PUSH CX                             ; Save CX                          @C39

    MOV  Local_InSGID, DX               ; Save full sgcb ID on stack
    XOR  DH, DH                         ; Save truncated ID in DX reg

    .IF  < BL eq SG_Start_Switch > OR   ; Action indicate start request
    .IF  < DL eq Hard_Error_SG >
      OR   DX, 8000H                    ; No validation required
    .ENDIF

;   ***************************************
;   *  ES:SI --> TopMost SGCB (outgoing)  *
;   *  FS:DI --> Next SGCB (incoming)     *
;   ***************************************
    MOV  AX, ES:[SI].SGCB_ID            ; Current foreground SGID
    MOV  Local_OutSGID, AX              ; Save full SGCB ID on stack

;   ****************************
;   *  Free up some registers  *
;   ****************************
    PUSH SI                             ; Save pointer to outgoing SGCB    @C39
    PUSH BX                             ; Save BX                          @C39
    PUSH AX                             ; Save SGID                        @C39

;   ***********************************************************            @C39
;   *  If this is a transparent popup, and a Full Screen VDM  *            @C39
;   *  is in the foreground, we have to freeze the VDM,       *            @C39
;   *  and call VIOSAVE.                                      *            @C39
;   *                                                         *            @C39
;   *  INPUTS:  AX = Full SGID                                *            @C39
;   ***********************************************************            @C39
    .IF  < BH e Transparent_PopUp > AND ; Transparent PopUp?               @C39
    .IF  < ES:[SI].SGCB_Type e VDM_Type > ; ForeGround a VDM?              @C39
      LEA  BX, Local_VideoHandle        ; @ to put Video Handle            @C39
      PUSH SS                           ;                                  @C39
      PUSH BX                           ;                                  @C39
      CALL DosSMFreezeVDM               ; Freeze VDM & call VIO            @C39
    .ELSE                               ; Not Transparent Popup over a VDM @C39
      XOR  AX, AX                       ; Preset to No_Error               @C39
    .ENDIF                              ;                                  @C39

    POP  BX                             ; Restore SGID                     @C39
    .IF  < zero AX > NEAR               ;                                  @C39
      XOR  BH, BH                       ; Truncated value in BX reg        @C39
      MOV  CX, ES:[SI].SGCB_Type        ; CX = Session Type                @C39
      .IF  < CX e VDM_Type > OR         ; Outgoing VDM?                    @C39
      .IF  < ES:[SI].SGCB_Type e Windowed_VDM_Type >
        OR   BX, 4000H                  ; Indicate it's a VDM              @C39
      .ENDIF                            ; Outgoing VDM Test

      .IF  < FS:[DI].SGCB_Type e VDM_Type > OR ; Incoming VDM?
      .IF  < FS:[DI].SGCB_Type e Windowed_VDM_Type >
        OR   DX, 4000H                  ; Indicate it's a VDM
      .ENDIF                            ; Incoming VDM Test

      MOV  SI, BX                       ; SI = Outgoing SGID               @C39
      MOV  BX, IncomingDebugger         ; Get new debugger SGID
      XOR  BH, BH                       ; Only use the lower byte

      .IF  < nonzero BX >               ; Valid debugger SGID?          ;@CJ10
        .IF  < BL ne DL >               ; Debugger SGID <> FgSG?
          MOV  CurrentDebugger, BX      ; Register new debugger

          MOV  AX, BX                   ; Validate new debugger
          OR   AX, 8000h
        .ENDIF

      .ELSEIF < CurrentDebugger a AX >  ; Debugger present?
        MOV  BX, CurrentDebugger
        .IF  < BL ne DL >               ; Debugger <> FgSG?
          MOV  AX, BX
        .ENDIF
      .ENDIF
      POP  BX                           ; Restore BX

      .IF  < SI eq Shell_SG >           ; Base Shell?
        OR   SI, 8000H                  ; No validation required
      .ENDIF

      PUSH SI                           ; Old fore. screen group ID
      PUSH DX                           ; New foreground screen group ID
      PUSH AX                           ; Debugger SGID
      CALL DOSSGDDNOTIFY                ; Switch screen groups

;     ***********************************************************          @C39
;     *  If this is a transparent popup, and a Full Screen VDM  *          @C39
;     *  is in the foreground, we now unfreeze the VDM and      *          @C39
;     *  restore the screen.                                    *          @C39
;     *  INPUTS:  SI = SGID in lower byte.                      *          @C39
;     ***********************************************************          @C39
      .IF  < BH e Transparent_PopUp >   ; Transparent PopUp?               @C39
        XOR  BH, BH                     ; No longer need popup type        @C39
        .IF  < CX e VDM_Type >          ; ForeGround a VDM?                @C39
          LEA  AX, Local_VideoHandle    ; @ to put Video Handle            @C39
          PUSH SS                       ;                                  @C39
          PUSH AX                       ;                                  @C39
          CALL DOSSMUNFREEZEVDM         ; Unlock VDM video (SI = SGID)     @C39

          PUSH Local_InSGID             ; Popup session                    @C39
          PUSH 0                        ; regular restore                  @C39
          CALL VIORESTORE               ; Restore display for popup        @C39
        .ENDIF                          ;                                  @C39
      .ENDIF                            ;                                  @C39

      AND  DX, NOT 8000H + 4000H        ; Turn off no validation / VDM flag
      POP  SI                           ; Restore offset to outgoing SGCB

;     ******************************
;     *  Notify Registered Device  *
;     *  Drivers of SG switch.     *
;     ******************************
      .IF  < BH eq Save_Foreground >    ; No Post_Save on SG Termination
;@D1088 PUSH Post_Save_Notification       ; Notification Type
;@D1088 PUSH Local_InSGID                 ; New SG
;@D1088 PUSH Local_OutSGID                ; Old SG

        MOV  NotDD_DosDev_Data_Len, Version_1_2_Len          ;data length;@D1088
        MOV  NotDD_Notification_Type, Post_Save_Notification ;notify type;@D1088
        MOV  AX, Local_InSGID             ; New SG                       ;@D1088
        XOR  AH, AH                       ; Zero out type byte           ;@D1088,VR4
        MOV  NotDD_InSG_or_OutType, AX                                   ;@D1088
        MOV  AX,Local_OutSGID             ; Old SG                       ;@D1088
        XOR  AH, AH                       ; Zero out type byte           ;@D1088,VR4
        MOV  NotDD_InType_or_OutSG, AX                                   ;@D1088
        PUSH DS                           ; Address of NotifyDD data     ;@D1088
        PUSH OFFSET NotDD_DosDev_Data_Len                                ;@D1088
        CALL DOSSMNOTIFYDD
      .ENDIF                            ; Hard Error test

      .IF  < BL ne Do_PopUp >           ; Not do popup request?(BX = Action)
        MOV  WORD PTR TopMost[2], FS    ; New TopMost SG
        MOV  WORD PTR TopMost,    DI

        MOV  WORD PTR BottomMost[2], ES ; Now BottomMost SG
        MOV  WORD PTR BottomMost,    SI

      .ELSEIF < DX ne Hard_Error_SG >
        PUSH PopUpPID                   ; Process that did popup
        PUSH DX                         ; New popup SG
        PUSH 0                          ; Make Window Type = Full scrn
        CALL DOSSGSWITCHPROC2           ; Switch proc. to new SG
      .ENDIF

;     **************************************************
;     *  Restore state of new foreground screen group  *
;     **************************************************
      .IF  < AX eq No_Error > AND              ; Error occurred in DDNotify?
      .IF  < BL ne Do_PopUp >                  ; Not a do popup switch
        .IF  < BL ne Skip_SG_Restore > AND     ; Not a switch with no restore
        .IF  < BL ne SG_Start_Switch > AND     ; Not a start switch request
        TEST FS:[DI].SGCB_Flags, Not_Saved     ; Foregrnd SG not saved   @D1200
        .IF  < zero >  AND                                              ;@D1200

;@D1200;.IF  < FS:[DI].SGCB_Flags ne 1 > AND   ; Not unsaved shell

        .IF  < FS:[DI].SGCB_Type ne VDM_Type > ; Not a FS VDM
          PUSH FS                       ;92872 sgrestore may trash FS
          PUSH 0                        ; Full screen group restore
          PUSH DX                       ; New foregrnd SG ID
          CALL DOSSGRESTORE
          POP  FS                       ;92872 sgrestore may have trashed FS   
        .ENDIF

        .IF  < BL ne SG_Start_Switch >  ; Don't notify of a restore on Start
;         ******************************
;         *  Notify Registered Device  *
;         *  Drivers of SG switch.     *
;         ******************************
;@D1088 PUSH Post_Restore_Notification  ; Not. Type
;@D1088 PUSH Local_InSGID               ; Incoming SG
;@D1088 PUSH 0                          ; Current SG

          MOV  NotDD_DosDev_Data_Len, Version_1_2_Len           ;data len;@D1088
          MOV  NotDD_Notification_Type, Post_Restore_Notification ;type  ;@D1088
          MOV  AX, Local_InSGID             ; Incoming SG                ;@D1088
          XOR  AH, AH                       ; Zero out type byte         ;@D1088,VR4
          MOV  NotDD_InSG_or_OutType, AX                                 ;@D1088
          MOV  AX,FS:[DI].SGCB_Type         ; Incoming SG type           ;@D1088
          MOV  NotDD_InType_or_OutSG, AX                                 ;@D1088
          PUSH DS                           ; Address of NotifyDD data   ;@D1088
          PUSH OFFSET NotDD_DosDev_Data_Len                              ;@D1088
          CALL DosSMNotifyDD
        .ENDIF                          ; Screen Group Start Test

        AND  FS:[DI].SGCB_Flags, NOT Not_Saved ; Turn off no save flag   @D1200
      .ENDIF                            ; If Not POPUP test

    .ELSE                               ; DosSMFreezeVDM failed            @C39
      POP  BX                           ; Restore BX                       @C39
      POP  SI                           ; Restore offset to outgoing SGCB  @C39
    .ENDIF                              ; DosSMFreezeVDM Test              @C39

    POP  CX                             ; Restore CX                       @C39
    LEAVE
    RET

DOSSGSWITCHFOREGROUND ENDP

CODE_TUNE4 ENDS                                                         ;MDLL

;*****************************************************************************




CODE SEGMENT WORD PUBLIC 'CODE' USE16                                   ;MDLL
    ASSUME CS:CONFORM16,DS:RDATA,SS:NOTHING,ES:NOTHING                  ;MDLL


;******************************************                                @C39
; Opens the Virtual Video Device Driver   *                                @C39
; to get a handle to it, then freezes the *                                @C39
; VDM's video state and calls VIOSAVE.    *                                @C39
;                                         *                                @C39
; INPUTS:                                 *                                @C39
;         SS:[SP] Address to put Handle   *                                @C39
;******************************************                                @C39

PUBLIC DOSSMFREEZEVDM                                                     ;@C39
DOSSMFREEZEVDM PROC NEAR                                                  ;@C39

    ENTER Local_Bytes,0
    PUSH ESI
    PUSH BX
    PUSH DS

    MOV  BX, AX                         ; Save full SGID
    XOR  AH, AH                         ; Get rid of high byte
    MOV  Local_SGID, AX                 ; Save truncated SGID

;   ******************************************
;   *  Open the Virtual Video Device Driver  *
;   ******************************************
    LDS  SI, VVD_VideoHandle
    PUSH RDATA
    PUSH OFFSET VVideo_Name
    PUSH DS
    PUSH SI
    CALL DOSOPENVDD

    .IF  < zero AX >                    ; If DosOpenVDD worked
;     **********************************
;     *  Freeze the VDM's video state  *
;     **********************************
      MOV  ESI, DS:[SI]                 ; VVD_VideoHandle
      PUSH ESI                          ; Handle
      PUSH Local_SGID                   ; SGID

      PUSH VVDSYSREQ_SETLOCK            ; Request type = Lock

      PUSH DWORD PTR 1                  ; TRUE = Lock VDD Video
      XOR  EAX, EAX                     ; Get a DWORD of 0's
      PUSH EAX                          ; pInput (Ignored)
      PUSH EAX                          ; cbInput (Ignored)
      PUSH EAX                          ; pOutput (Ignored)
      CALL DOSREQUESTVDD

      .IF  < zero AX >                  ; If DosRequestVDD worked
;       *******************************************************
;       *  Call VioSave so VIO can restore state after popup  *
;       *******************************************************
        PUSH BX                         ; Full SGID
        PUSH 5                          ; Transparent POPUP
        CALL VIOSAVE                    ; Let VIO know about this

        .IF  < nonzero AX >             ; VioSave failed
          PUSH AX                       ; Save error

;         ************************************
;         *  Unfreeze the VDM's video state  *
;         ************************************
          PUSH ESI                            ; Handle
          PUSH Local_SGID                     ; SGID

          PUSH VVDSYSREQ_SETLOCK              ; Request type = Lock

          XOR  EAX, EAX                       ; Get a DWORD of 0's
          PUSH EAX                            ; FALSE = UNLock VDD Video
          PUSH EAX                            ; pInput (Ignored)
          PUSH EAX                            ; cbInput (Ignored)
          PUSH EAX                            ; pOutput (Ignored)
          CALL DOSREQUESTVDD

;         *******************************************
;         *  Close the Virtual Video Device Driver  *
;         *******************************************
          PUSH ESI
          CALL DOSCLOSEVDD

          POP  AX                       ; Restore VioSave error
        .ENDIF
      .ENDIF                            ; DosRequestVDD test
    .ENDIF                              ; Error Check from DosOpenVDD

    POP  DS
    POP  BX
    POP  ESI
    LEAVE
    RET  4

DOSSMFREEZEVDM ENDP
;*****************************************************************************

;*****************************************                                @C39
; Unfreeeze the VDM's video state.       *                                @C39
; INPUTS:                                *                                @C39
;         SS:[SP] Address to put Handle  *                                @C39
;*****************************************                                @C39

PUBLIC DOSSMUNFREEZEVDM                                                  ;@C39
DOSSMUNFREEZEVDM PROC NEAR                                               ;@C39

    ENTER Local_Bytes,0
    PUSH ESI
    PUSH DS

    MOV  AX, SI                         ; Get SGID into AX
    XOR  AH, AH                         ; Get rid of high byte
    MOV  Local_SGID, AX                 ; Save truncated SGID

;   ************************************
;   *  Unfreeze the VDM's video state  *
;   ************************************
    LDS  SI,  VVD_VideoHandle
    MOV  ESI, DS:[SI]
    PUSH ESI                            ; Handle
    PUSH Local_SGID                     ; SGID

    PUSH VVDSYSREQ_SETLOCK              ; Request type = Lock

    XOR  EAX, EAX                       ; Get a DWORD of 0's
    PUSH EAX                            ; FALSE = UNLock VDD Video
    PUSH EAX                            ; pInput (Ignored)
    PUSH EAX                            ; cbInput (Ignored)
    PUSH EAX                            ; pOutput (Ignored)
    CALL DOSREQUESTVDD

    PUSH AX                             ; Save RC from DosReqeustVDD
;   *******************************************
;   *  Close the Virtual Video Device Driver  *
;   *******************************************
    PUSH ESI
    CALL DOSCLOSEVDD

    POP  AX                             ; Restore RC from DosReqeustVDD

    POP  DS
    POP  ESI
    LEAVE
    RET  4

DOSSMUNFREEZEVDM ENDP

CODE ENDS
endif
    END
