;       SCCSID = @(#)smgpopcp.asm       6.4 91/11/19
PAGE 60,132                             ;
; ****************************************************************************
; *                                                                          *
; *                       IBM/Microsoft Confidential                         *
; *                                                                          *
; *                 Copyright (c) IBM Corporation  1987, 1990                *
; *                 Copyright (c) Microsoft Corp.  1987, 1990                *
; *                           All Rights Reserved                            *
; *                                                                          *
; ****************************************************************************

;***************************************************************************
;
; Source File Name:     SMGPOPCP.ASM
;
; Subroutine Name:      DOSSMPOPUPTLECHG
;
; Descriptive Name:     Session Manager Popup Switch and Title Change
;                       Notification
;
; Function:     Process a switch on an applications request to do/end
;               a popup or notify the Shell a screen group title has
;               changed.
;
; Notes:
;       Dependencies:   This procedure only receives control when a
;                       shared RAM semaphore is cleared.
;
;                       This procedure is called via DOSCREATETHREAD.
;
;       Restrictions:   None
;
;     Change History:
;      @TL7 - 04/05/90 - PTR B712376 - Enable for MMIO
;      @CJ10  05/04/90   PTR B712103 Hot Keying performance too slow.
;      @D1088 07/07/90   DCR 1088 Add support for special needs.
;      @MHW - 09/13/90   PTR B715818 Removed MMIO support.
;      @GDW   08/26/91   PTR B725436 Fix to allow semaphore loop on INTERUPT
;
; Entry Point:
;       Linkage:  EXTRN DOSSMPOPUPTLECHG:FAR
;
; Inputs:
;       None
;
; Exit Normal:
;       None
;
; Exit Errors:
;       None
;
; Effects:      This is an infinite loop for the popup switch thread.
;
; Internal References:
;                       The following data is in a shared data segment(SDATA)
;
;                       queueselector - active screen group queue selector
;                       listsem       - array of semaphores for muxwait
;                       listsemnum    - number of semaphores to muxwait on
;                       indexnumber   - semaphore cleared for muxwait
;
;                       popup data
;                                      popvioramsem
;                                      popsmgramsem
;                                      popupsgid
;                                      popupflags
;                                      popupreturncode
;
;          Routines:    DOSSMSGSWITCH
;
; External References:
;          Routines:    DOSMUXSEMWAIT
;                       DOSSEMCLEAR
;                       DOSSEMSET
;
;***************************************************************************
ifdef I1
;
;   REPEAT
;      DOSMUXSEMWAIT (Wait on a list of sems)
;      IF (Popup switch)
;         DOSSEMSET(Set popvioramsem)
;
;         IF (do popup request)
;            DOSFSRAMSEMREQUEST (Wait on popup semaphore)
;
;            IF (popup sg ne 3)
;               Process sg switch
;               RC = No_Error
;            ELSE
;               RC = Error_SMG_Invalid_Session_ID
;            ENDIF
;
;         ELSE
;            RC = Error_SMG_Already_Top
;         ENDIF
;
;         IF (Error_SMG_Already_Top) OR
;         IF (No_Error)
;            DOSSMGSWITCH (Switch sg)
;
;            IF (Error) AND
;            IF (Popup type e do popup)
;               DOSSMGSWITCH (Switch sg)
;            ENDIF
;         ENDIF
;
;         IF (Popup type ne do popup) OR
;         IF (Error)
;            DOSSMNOTIFYDD (Notify registered device drivers of switch)
;            DOSFSRAMSEMCLEAR (Allow popups)
;
;            IF (Title change)
;               DOSSEMCLEAR (Clear title semaphore)
;            ENDIF
;         ENDIF
;         DOSSEMCLEAR (Clear popsmgramsem semaphore)
;
;      ELSE
;         DOSSEMSET (Set title semaphore)
;         IF (no popup)
;            DOSFSRAMSEMREQUEST (Wait on SMG router semaphore)
;            DOSSMAPPNOTIFY (Notify Shell)
;            DOSFSRAMSEMCLEAR (Shell SMG router semaphore)
;         ELSE
;            Increment title change counter
;         ENDIF
;      ENDIF
;
;   UNTIL (forever)
;
;***************************************************************************
else

.386C
    EXTRN IndexNumber             : WORD  ; Index to semaphore cleared
    EXTRN ListSem                 : WORD  ; Semaphore list array
    EXTRN ListSemNum              : WORD  ; Number of semaphores in list
    EXTRN PopSMGRamSem            : DWORD ; Popup ram semaphore for SMGR
    EXTRN PopUpFlags              : WORD  ; Do or end popup request
    EXTRN PopUpPID                : WORD  ; Popup process ID
    EXTRN PopUpReturnCode         : WORD  ; Popup switch return code
    EXTRN PopUpSGID               : WORD  ; Popup screen group ID
    EXTRN PopVioRamSem            : DWORD ; Popup ram semaphore for VIO
    EXTRN BottomMost              : DWORD
    EXTRN CurrentDebugger         : WORD
    EXTRN IncomingDebugger        : WORD
    EXTRN PopUpBlockSem           : BYTE  ; FSRamSem
    EXTRN PopUpScrnGrp2           : WORD
    EXTRN SMRoutSem               : BYTE
    EXTRN TopMost                 : DWORD
    EXTRN STitleRamSem            : DWORD ; Title change ram semaphore
    EXTRN TitleCount              : WORD  ; Title change count
    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 DOSMUXSEMWAIT      : FAR      ; Wait for a semaphore to clear
    EXTRN DOSSEMCLEAR        : FAR      ; Release semaphore ownership
    EXTRN DOSFSRAMSEMREQUEST : FAR      ; Request sem ownership
    EXTRN DOSFSRAMSEMCLEAR   : FAR      ; Request sem ownership
    EXTRN DOSSEMSET          : FAR      ; Reset semaphore for MuxWait
    EXTRN DOSSMGSWITCH       : NEAR     ; Change foreground screen group
    EXTRN DOSSMAPPNOTIFY     : FAR      ; Notify shell to redraw
    EXTRN DOSSMNOTIFYDD      : FAR

.xlist
    INCLUDE SMRSGCB.INC
    INCLUDE SMRRDATA.INC
.xcref
    INCLUDE STRUC.INC
    INCLUDE ERROR2.INC
.cref
.list

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

    PUBLIC DOSSMPOPUPTLECHG
DOSSMPOPUPTLECHG PROC FAR

    Local_Bytes  EQU  0

    ENTER Local_Bytes,0
    MOV  AX, RDATA                      ; Addressability to global data
    MOV  DS, AX

;   **************************************************************************
;   *  Block on a list of semaphores until one of the semaphores is cleared  *
;   **************************************************************************
    .REPEAT
      PUSH DS                           ; Index number of semaphore cleared
      PUSH OFFSET IndexNumber
      PUSH DS                           ; List of semaphore handles
      PUSH OFFSET ListSemNum
      PUSH DWORD PTR -1                 ; Wait until semaphore clears   ;@CJ10
      CALL DOSMUXSEMWAIT

;     ********************************************
;     *  Process do or end popup switch request  *
;     ********************************************
      PUSH ES                           ; Save ES                       ;CJ10
      .IF  <<DS:IndexNumber> eq 0> NEAR ; Popup switch?
        PUSH DS                         ; Reset MUXWAIT sem.
        PUSH OFFSET PopVioRamSem
        CALL DOSSEMSET

        MOV  DX, PopUpSGID              ; SG requesting popup
        MOV  CX, PopUpPID               ; Popup process ID
        MOV  AX, PopUpFlags             ; Popup type / do or end
        MOV  BX, AX
        AND  AX, 7FFFH                  ; Mask out popup type
        ADD  BL, 4                      ; BL=4(DO) or 5(END) popup

        LFS  DI, BottomMost             ; Used for end popup            ;CJ10
        LES  SI, TopMost                ; Switch to old topmost         ;CJ10

        .IF  < zero AX >                ; Do popup request?             ;@CJ10
          .repeat                                                       ;@GDW
            PUSH DS
            PUSH OFFSET PopUpBlockSem   ; Offset of Semaphore
            PUSH DWORD PTR -1                                           ;@CJ10
            CALL DOSFSRAMSEMREQUEST
          .until  <ax ne ERROR_INTERRUPT>                               ;@GDW

          .IF  < DL ne 3 >              ; If not reserved SG
            MOV  DX, 3                  ; Reserved SG
            SUB  AX, AX                 ; Process SG Switch             ;CJ10
            MOV  DS:IncomingDebugger, AX; No debugger                   ;CJ10
                                        ; on popup
          .ELSE                         ; Hard error popup
            MOV  AX, Error_SMG_Invalid_Session_ID
          .ENDIF

        .ELSE                           ; End PopUp
          MOV  DX, ES:[SI].SGCB_ID      ; TopMost SG                    ;CJ10
          .IF  < DL eq 1 >              ; If we are going back to the   ;97973
            .repeat                     ;   Desktop, be sure to end     ;97973
              PUSH DS                   ;   the popup before starting   ;97973
              PUSH OFFSET SMRoutSem     ;   a new session or wait for   ;97973
              PUSH DWORD PTR -1         ;   completion of session start ;97973
              CALL DOSFSRAMSEMREQUEST   ;   to avoid timing problems    ;97973
            .until  <ax ne ERROR_INTERRUPT>;see defect 86659 for detail ;97973
          .ENDIF                                                        ;97973
          MOV  AX, CurrentDebugger      ; Restore
          MOV  IncomingDebugger, AX     ; Debug SID
          MOV  AX, Error_SMG_Already_Top
        .ENDIF

        .IF  < zero AX > OR                                             ;CJ10
        .IF  < AX eq Error_SMG_Already_Top >                            ;CJ10

          PUSH  DX                                                      ;97973
          CALL DOSSMGSWITCH             ; Change foregrnd SG
          POP   DX                                                      ;97973

          .IF  < BL eq End_Popup > and                                  ;97973
          .IF  < DL eq 1 >                                              ;97973
            PUSH AX                                                     ;97973
            PUSH DS                                                     ;97973
            PUSH OFFSET SMRoutSem                                       ;97973
            CALL DOSFSRAMSEMCLEAR                                       ;97973
            POP  AX                                                     ;97973
          .ENDIF                                                        ;97973

          .IF  < nonzero AX > AND       ; Error on do popup             ;@CJ10
          .IF  < BL eq Do_PopUp >

            PUSH AX                     ; Save do popup rc

            LFS  DI, DS:BottomMost                                      ;CJ10
            LES  SI, DS:TopMost                                         ;CJ10

            MOV  DX, ES:[SI].SGCB_ID    ; Previous TopMost, before Switch ;CJ10
            MOV  BX, 4005H              ; Auto end popup
            MOV  AX, CurrentDebugger    ; Restore
            MOV  IncomingDebugger, AX   ; Debug SID
            MOV  AX, Error_SMG_Already_Top
            CALL DOSSMGSWITCH           ; Change foregrnd SG

            POP  AX                     ; Restore Return code
          .ENDIF                        ; Error on Do PopUp check
        .ENDIF

        MOV  PopUpReturnCode, AX        ; Set return code for VIO
        .IF  < BL ne Do_PopUp > OR
        .IF  < nonzero AX >                                             ;CJ10
          MOV  AX, 3                    ; Popup SG                 ;CJ10,@D1088

;         ******************************
;         *  Notify Registered Device  *
;         *  Drivers of SG switch.     *
;         ******************************
;@D1088   PUSH Termination_Notification ; Notification Type
;CJ10     PUSH 0                        ; Incoming SG
;@D1088   PUSH EAX                      ; Current SG                    ;CJ10

          MOV  NotDD_DosDev_Data_Len, Version_1_2_Len        ;data len  ;@D1088
          MOV  NotDD_Notification_Type, Termination_Notification ;type  ;@D1088
          MOV  NotDD_InSG_or_OutType, PROG_FULLSCREEN  ;Outgoing SG type;@D1088
          MOV  NotDD_InType_or_OutSG, AX               ;Outgoing SG     ;@D1088
          PUSH DS                            ;Address of NotifyDD data  ;@D1088
          PUSH OFFSET NotDD_DosDev_Data_Len                             ;@D1088
          CALL DosSMNotifyDD

          PUSH DS
          PUSH OFFSET PopUpBlockSem
          CALL DOSFSRAMSEMCLEAR         ; Allow popups

          .IF  < TitleCount a 0 >       ; Title chg in popup
            PUSH DS                     ; Clear title change sem.
            PUSH OFFSET STitleRamSem
            CALL DOSSEMCLEAR
          .ENDIF
        .ENDIF

        PUSH DS                         ; Indicate switch complete
        PUSH OFFSET PopSMGRamSem
        CALL DOSSEMCLEAR

      .ELSE                             ; Title changed
;       **************************************************
;       *  Process redraw notification for title change  *
;       **************************************************
        PUSH DS                         ; Reset MUXWAIT sem.
        PUSH OFFSET STitleRamSem
        CALL DOSSEMSET

        .IF  <ES:PopUpScrnGrp2 eq 0FFFFH> ; No popup
          .repeat                                                       ;@GDW
            PUSH DS                       ; Block Router
            PUSH OFFSET SMRoutSem
            PUSH DWORD PTR -1                                           ;CJ10
            CALL DOSFSRAMSEMREQUEST
          .until  <ax ne ERROR_INTERRUPT>                               ;@GDW

          PUSH DWORD PTR 01             ; Simulate terminate            ;CJ10
          PUSH 0
          CALL DOSSMAPPNOTIFY           ; Notify Shell

          MOV  TitleCount, 0            ; Reset title chg count

          PUSH DS                       ;  Clear Router
          PUSH OFFSET SMRoutSem
          CALL DOSFSRAMSEMCLEAR
        .ELSE
          INC  TitleCount               ; Inc. title change cnt
        .ENDIF
      .ENDIF
      POP  ES                           ; Restore ES                    ;CJ10
    .UNTIL                              ; Infinite loop

DOSSMPOPUPTLECHG ENDP

CODE ENDS
endif
    END
