--  Em3270Pack:  3270 Emulation Window

--  Last revised for Star 3.3L by Lui:	25-Jun-84 11:23:56
--  Owner:  Terminal Emulation

--  Overview:
--  This module handles various startup and initialzations for the 3270 emulator.
--  More Description will be added here as soon as the content "settles down".



DIRECTORY
  AreaDefs USING [Posn],
  Auth USING [CallProblem],
  CharDefs USING [Char, Code, chsetRoman, Roman],
  CH USING [ConversationHandle, Name, ReturnCode],
  CHCommonLookups USING [LookupAddress],
  DirectoryInternalDefs USING [LookupError],
  DispDefs USING [ctMaxStd, EraseRectangle],
  DispPrivDefs USING [GetDrAddr],
  DocSchemaDefs USING [GetEmptyDoc],
  DocSchemaForgotDefs USING [MarkDirty],
  DtwmPrivDefs USING [FileDt, LSchemaDt, PutIconOnDesktop, PosnFromSquare, SquareFromIcon],
  Em3270Defs,
  EmForgotDefs USING [emulatorIconError],
  Em3270PrivDefs,
  Em3270BufferDefs USING [bufferSize, Create, Destroy, EnumAllFieldsAndNulls,
    numberOfRows, lineSize, Release, Reserve],
  Em3270CharTransDefs USING [CoalesceDeadChar, DeleteFileSpace, GetTransFile],
  Em3270CmdProcessDefs USING [CreateCmd, DestroyCmd],
  Em3270ComDefs USING [AbortOpen, EndCom, ForkComProcesses, StartCom],
  Em3270StatusDefs USING [
    DestroyInstance, Em3270StatusPack, htStatusArea, InitInstance, RepaintStatusArea, SetSrt],
  Em3270UserInputDefs USING [
    Create, Destroy, DoProcessBut, Process3270Keyes,
    ProcessFunRepeat, ProcessFuntion, ProcessInputChar, Reset],
  Em3270OsMgrDefs USING [Em3270osMgr],
  Environment USING [Byte],
  FeatureDefs USING [features],
  FilingUtilDefs USING [GetExtendedAttributeValue],
  FontstyleDefs USING [
    ctBytesFontstyleDescription, Fontstyle, fontstyleidCentury10, FontstyleDescription,
    GetFontstyleDescription],
  Format USING [Date, StringProc],
  GateStream,
  IconDefs USING [DestroyStd,
    Pvcreate, Pttrticonops, Icon, InitTrticonOps, NameFromIcon,
    ParentFromIcon, Pvdestroy, Pvopen, Pttrtctnrops,
    InitTrtctnrOps, Pvmake, MakeNonCtnrStd, Name, CanYouTakeDflt,
    ReferenceFromIcon, SetOpen, SetNoOpen, SetHighlight],
  Inline USING [BITAND, LongCOPY],
  McDefs USING [SetStandardShape, SetDefaultShape],
  MenuSchemaDefs USING [AddMi, RemoveMi],
  MessageDefs USING [GetMsg, MsgFromLsv],
  MessageSwnDefs USING [DisplayMessage],
  MiSchemaDefs USING [Mi],
  NewDocConvertDefs USING [AddParagraph, CreateDc, AddText, Dc, DestroyDc, fontstyleNil],
  MultiNatlDefs USING[variant],
  NSFile USING [
    Attribute, AttributeList, Attributes, AttributesRecord, ChangeAttributes,
    ClearAttributeList, ClearAttributes, Close, EncodeCardinal, Error, ExtendedAttributeType,
    GetAttributes, GetReference, Handle, Move, OpenChild, Reference, Words],
  NSName USING [--+FreeName, Name, NameFromString,+-- maxFullNameLength],
  NSString USING [AppendString, FreeString, MakeString, String, StringFromMesaString, WordsForString],
  PagestyleDefs USING [GetPageLayout, Pagestyle, PagestyleFromTile, PageLayout],
  ParastyleDefs USING [Aqparastyle, GetHeader, GetParadesc, GetParastyleDescription, Paradesc, 
    Parastyle, parastyleidLeftRagged, SetHeader, SetParadesc],
  PswnDefs USING [OsIsUp, Pvreturnoscontrol, PsIsUp],
  RgnDefs USING [IntersectSrtSrt, Srt],
  SchemaDefs USING [
    Aqschrt, Destroy, EnumProgeny, DestroyStd, Lschema, lschemaNil,
    InitTrtschemaData, InitTrtschemaOps, Repaint, Rs, Rsarea,
    ProcessButNopAbortMCSOnButtonUpStd, Pttrtschemaops, Pvgeteldest, Pvdestroy,
    Pvprocesscsnt, Pvprocessbut, Pvrepaint, Pvrs, Pvsc, Pvuserproc, Posnarea,
    Trtschemadatainit],
  SchemaUtilDefs USING [PosnFromPosnSc, RtFromRelrt, SubtractScs],
  SelectionDefs USING [
    Ctxt, DeselectCs, SetCs, Pvcscancelmcs, Pvkillsel, Pvpushorpopcs, Seltype],
  StandardDefs USING [Bytes, Bv, Ct, Cv, Lsv, Msg, String, Wd],
  StandardWindowDefs USING [Aqinstallctxt, InitTrtinstalleeOps, Install, Pvdestall, -- Pvpostinstall, -- stdwnNil],
  StarAttributeTypeDefs USING [AttributeType, clientFileWords, clientStatus],
  StarAttributeTypeForgot1Defs USING [em3270AttrType],
  StarStartDefs USING [],
  StdWnSchemaDefs USING [-- Install, --  MenuFromStdWn, --  Pvdestall, -- TitleFromStdWn],
  SvDefs USING [AppendLsvToLsv, DestroyLsv],
  System USING [NetworkAddress, nullNetworkAddress],
  Time USING [Current],
  TitleSchemaDefs USING [PopTitle, PushTitle],
  TraitDefs USING [
    ClassType, Opsizn, OpsIzn, TraitOps, Instance, instanceNil, instanceNilD,
    MyData],
  TreeEltDefs USING [AncestorOfType, Ctxt, ctxtNil, Pttrttreeeltops, Pvsetparent,
    SetParentStd],
  TxtDefs USING [Flow, Header],
  TxtFontDefs USING [Validate],
  TxtDocDefs USING [DocumentFlow],
  TxtFlowDefs USING [AdvanceCharacter, CharacterCurrent, Destroy],
  UserDefs USING [AcquireConversation],
  VDTDefs USING [Create, CRShape, GetCursorShape, LschemaVDT, SetCursorShape],
  WSCharDefs USING [Character, Tile],
  WSFontDefs USING [Description, familyTerminal],
  WSOISConvertDefs USING [DestroyOISString, OISFromWS],
  WSStringDefs USING [
    Attr, AppendChar, Aqeditctxt, BeginEdit, byteFontTag, EndEdit, Lptstring, SetAttr, String,
    Substring],
  WSStringUtilDefs USING [
    AppendStringToString, LsvFromString, DestroyString, StringCreate, StringFromMsg],
  ZkeyMessageDefs USING [DisplayMessage],
  ZoneMgrDefs USING [Bytes, GetPredefinedZone, Words];


Em3270Pack: PROGRAM
  IMPORTS
    CharDefs, CHCommonLookups, DirectoryInternalDefs, DispDefs, DispPrivDefs, DocSchemaDefs, DocSchemaForgotDefs, DtwmPrivDefs,
    EmForgotDefs, Em3270PrivDefs, Em3270BufferDefs, Em3270CharTransDefs, Em3270CmdProcessDefs,
    Em3270ComDefs, Em3270StatusDefs, Em3270UserInputDefs, Em3270OsMgrDefs, FeatureDefs, FontstyleDefs,
    FilingUtilDefs, Format, IconDefs, Inline, McDefs, MenuSchemaDefs,
    MessageDefs, MessageSwnDefs, MultiNatlDefs, NewDocConvertDefs, NSFile, --+NSName,+-- NSString, PagestyleDefs, ParastyleDefs, PswnDefs, RgnDefs,
    SchemaDefs, SchemaUtilDefs, SelectionDefs, StandardWindowDefs, StdWnSchemaDefs, SvDefs, TxtDocDefs, TxtFlowDefs, TxtFontDefs, Time,
    TitleSchemaDefs, TraitDefs, TreeEltDefs, UserDefs, VDTDefs, WSStringDefs,
    WSOISConvertDefs, WSStringUtilDefs, ZkeyMessageDefs, ZoneMgrDefs
  EXPORTS EmForgotDefs, Em3270Defs, Em3270PrivDefs, StarStartDefs
  SHARES Em3270Defs, Em3270OsMgrDefs, Em3270BufferDefs, Em3270StatusDefs, IconDefs, NewDocConvertDefs, SchemaDefs =
  BEGIN OPEN  FormatPilot:Format, Em3270Defs, Em3270PrivDefs, StandardDefs;


  --===================
  --  Types
  --===================
  -- *+*+ Stub for Clearinghouse
  EcsAddr: TYPE = MACHINE DEPENDENT RECORD [address(0): System.NetworkAddress];
  ECSPt: TYPE = LONG POINTER TO EcsAddr;

  Star3wrAttributeData: TYPE = MACHINE DEPENDENT RECORD[  -- describes info stored on icon's file object
      lang: IBMlanguages,      -- the language of this controller as specified in ClearingHouse.
      termaddr: GateStream.DeviceAddress,   --  the terminal address previously selected.
      ecsaddr: System.NetworkAddress,
      controllerAddr: CARDINAL,
      numOfTerm: GateStream.DeviceAddress,       -- the number of ports on the controller.
      -- modelNum: ModelType,    the 3278 model number,  future enchancement
      length: CARDINAL,  --  this & the followng fields MUST be last in FileAttributeData (see GetFileData)!
      maxlength: CARDINAL,
      bytes: PACKED ARRAY [0..0) OF Environment.Byte];

    -- Note: this is the FileAttributeData for Star 2,  should be delete from future releases
  Star2FileAttributeData: TYPE = MACHINE DEPENDENT RECORD[  -- describes info stored on icon's file object
      termaddr: GateStream.DeviceAddress,
      ecsaddr: System.NetworkAddress,
      controllerAddr: CARDINAL,
      length: CARDINAL,  -- this & the followng fields MUST be last in FileAttributeData (see GetFileData)!
      maxlength: CARDINAL,
      text: PACKED ARRAY [0..0) OF CHARACTER];

  --===================
  --  Signals and Errors
  --===================

  emulatorIconError: PUBLIC SIGNAL = CODE;

  --===================
  --  Constants
  --===================

  addrECSDflt: PUBLIC System.NetworkAddress ← System.nullNetworkAddress;
  dftLang: IBMlanguages ← USenglish;   -- might want to move to Em3270PrivDefs
  em3270AttrType: StarAttributeTypeDefs.AttributeType = StarAttributeTypeForgot1Defs.em3270AttrType;


  --===================
  --  Global Variables
  --===================

  bvStreamOn: Bv ← TRUE;  -- for testing purposes without a stream connection +++

  spredefinedZone: UNCOUNTED ZONE ← ZoneMgrDefs.GetPredefinedZone[short];
  lpredefinedZone: UNCOUNTED ZONE ← ZoneMgrDefs.GetPredefinedZone[session];
  msgMakeDoc: Msg ← MessageDefs.GetMsg[keyMakeDocumentWn].msg;  -- Make Doc menu title


  --===================
  --  Public Procedures
  --===================

  Create: PUBLIC IconDefs.Pvcreate =
    -- PROC[ Reference, Type, Name, fileParent, Viewid]  RETURNS[iconInstance:IconInstance]
    -- This routine is called by IconPack.MakeWithin after "Make" to create an instance of trt3270icon when the icon is copied from the directory, or, when the desktop is made up after logon.
    -- Note: when icons become Instances we will need to call IconDefs.InitTrticonData here also.
    BEGIN
    -- Get zone operations vector from default zone (where all the traits reside)
    opsizn: TraitDefs.Opsizn = TraitDefs.OpsIzn[TraitDefs.instanceNilD];

    -- Set up the various trt*datainit records necessary for the associated InitTrt*Data calls
    trt3270icondatainit: Trt3270icondatainit ← [termAddrDflt, addrECSDflt, maxNumPorts, dftLang];
    --  ++== do we really want to default the language and the maxNumPorts
    -- trticondatainit: IconDefs.Trticondatainit ← [icon: icon];  ++ future change (see note above)

    -- get an instance of trt3270icon in zone instanceNilD
    iconInstance ← opsizn.create[trt3270icon, TraitDefs.instanceNilD];  -- *+*+Handle no room signal
    --Initialize trt3270icon component's Data
    -- IconDefs.InitTrticonData[iconInstance, @trticondatainit];  ++ future change (see note above)
    InitTrt3270iconData[iconInstance, reference, fileParent, @trt3270icondatainit];
    RETURN[iconInstance];
    END;  -- of Create


  Make: PUBLIC IconDefs.Pvmake =
    --PROCEDURE [type: Type, name: Name, fileParent: File] RETURNS [reference: Reference]
    -- This routine (a long with Create) is the first of two called by IconPack.MakeWithin when copying a 3270 icon to the desktop.  It will create an empty 3270icon file object to back up the 3270 icon which is about to be created (by Create).  It is a Star requirement that all icons be backed by a file object reguardless of whether or not the file is needed.  In the process of copying the icon from the Directory to the desktop, DtwmPack will copy this file object and its icon to a completetly different place (therefore having a set of two each).  The very last thing Directory will do as part of the Copy is delete the origional icon and file object, leaving us with only one of each (as it should be).
    -- Any actual data that is put on the file (or in the Attribute clientFileWord and name fields as is the case with 3270) is done by SetResourceParams which is called by StarCopy in Directory3Pack after Make and Create are finished.  No valid data is put on the backing file at this time because none is known yet.  A NIL name field is set to indicate this fact.
    BEGIN
    RETURN
      IconDefs.MakeNonCtnrStd[type: type, name: name, fileParent: fileParent];
    END;  --of Make


  Open: PUBLIC IconDefs.Pvopen =
    --	PROC[ icon: Icon]  RETURNS[ lschemaIcon: SchemaDefs.Lschema]
    -- Open/Build 3270 window whem icon is opened; Initialize all associated Data.
    -- Create an instance of trt3270wnschema.  This routine is called by DtwmPack in its OPEN routine.  At the time Em3270defs.Open is called the StdWnSchema window has not been created (this is so aborting will be made easier if there is some problem with creating the window body schema).  After it is completed, DtwmPack will then create a Standard Window with a viewer, and install lschema3270 into that viewer.  Hence, the hierarcy tree structure is StdWindow above Viewer above 3270 schema body.

    BEGIN OPEN Em3270OsMgrDefs;
    lptOpenData: LONG POINTER TO OpenData;
    Mydata: Lpttrt3270icondata;
    lschema3270icon:SchemaDefs.Lschema ← icon.iconInstance;

    -- Check to see if this user has Emulation factored into his system
    IF ~FeatureDefs.features.bv3270Emulation  THEN {
       MessageSwnDefs.DisplayMessage[key3270No3270Emulation];
       -- RETURN[SchemaDefs.lschemaNil];
       EmForgotDefs.emulatorIconError; };
       
    --/* Cute hack by Steve Tom to see if six windows are already open */
    IF DispPrivDefs.GetDrAddr[].ctStd >= DispDefs.ctMaxStd THEN 
      {
      MessageSwnDefs.DisplayMessage[keyDtWindows];
      EmForgotDefs.emulatorIconError
      };

    -- Check to see if there is any Property or Option sheet that is already up.
    IF (PswnDefs.OsIsUp[] OR PswnDefs.PsIsUp[]) THEN {
      MessageSwnDefs.DisplayMessage[keyWnReadOnly];
      RETURN [SchemaDefs.lschemaNil]; };

    -- check to see if icon contains the correct file data(i.e was created with a star 3.0xr desktop)
    Mydata ← TraitDefs.MyData[lschema3270icon, trt3270icon];  -- pointer to icon's trait data
    IF Mydata.language = unused6 THEN  {  -- the icon contain invalid data; cannot be open must be deleted.
      ZkeyMessageDefs.DisplayMessage[keyZ440];
      -- MessageSwnDefs.DisplayMessageLiteral[MessageDefs.MsgFromLsv["Sorry, The desktop is unable to open the 3270 icon selected. Please refetch a new 3270 icon from the Directory. "L]];
      -- RETURN[SchemaDefs.lschemaNil];
      EmForgotDefs.emulatorIconError }; -- raised a signal so that our message would override the message generated by Icon2Pack. must check for space leak in Icon2Pack.

    -- Bring up Option Sheet
    lptOpenData ← spredefinedZone.NEW[OpenData];  -- get space to pass parameters to ReturnControl3270Os
    lptOpenData.icon3270 ← icon;  --  save away pointer to 3270 icon
    lptOpenData.lptHostN ← WSStringUtilDefs.LsvFromString[
      icon.name, spredefinedZone];
    Em3270osMgr[ctxt: [lptr[lptOpenData]], pvreturncontrol: ReturnControl3270Os];

    EmForgotDefs.emulatorIconError;  -- ++  raise a signal so that SchemaDefs.lschemaNil will not be returned thus dtwmpack.Open will not display the message "Can't open that icon".

    RETURN[SchemaDefs.lschemaNil];
    END;  -- of Open


  ReturnControl3270Os: PswnDefs.Pvreturnoscontrol =
    --	PROC[ctxt:Ctxt, returnreason:Returnreason{start, cancel}]
    -- This routine will process the START/CANCEL menu items on the 3270 Option Sheet.   (Don't blame me, I'm just another ParameterDefs client!)

    BEGIN OPEN Em3270OsMgrDefs;
    -- SAVE ANY VARIABLES PASSED IN lptOpenData BLOCK AT THIS POINT
    lptOpenData: LONG POINTER TO OpenData ← ctxt.lptr;  -- pointer to any data coming from Open
    icon3270: IconDefs.Icon ← lptOpenData.icon3270;  -- 3270 icon handle
    opsizn: TraitDefs.Opsizn ← TraitDefs.OpsIzn[TraitDefs.instanceNilD];  -- pointer to vector of instance zone operations
    lschema3270wn: SchemaDefs.Lschema;  -- 3270's window handow returned by OPEN
    srtstatus: RgnDefs.Srt;  -- Srt for the status area
    rs3270Viewer: SchemaDefs.Rsarea;
    -- Set up the various trt*datainit records necessary for the associated InitTrt*Data calls
    trtschemadatainit: SchemaDefs.Trtschemadatainit ← [SchemaDefs.lschemaNil];
    trt3270schemadatainit: Trt3270schemadatainit ← [
      icon: icon3270, lptEmState: NIL];
    emdata: LONG POINTER TO EmHandle ← NIL;
    tempLang: IBMlanguages ← lptOpenData.lang;     -- save the language field. need to store in EmHandle later
	
    -- Return space used by and within the lptOpenData block
    SvDefs.DestroyLsv[lptOpenData.lptHostN, spredefinedZone];  --return host name space
    spredefinedZone.FREE[@lptOpenData];  -- return OpenData space

    -- Check why the option sheet closed
    IF returnreason = cancel THEN RETURN;  -- don't open 3270 window

    McDefs.SetStandardShape[idHourGlass];

    -- Create an instance of trt3270schema in zone instanceNilD.  The storage for all of lshema3270's data is within that zone
    lschema3270wn ← opsizn.create[trt3270schema, TraitDefs.instanceNilD];  --+*+*Handle possible "No room" signal

    -- Initialize trt3270schema component's data
    SchemaDefs.InitTrtschemaData[lschema3270wn, @trtschemadatainit];

    -- Allocate space for Emulator global data (freed in
    emdata ← lpredefinedZone.NEW[EmHandle];  -- used just as a shorter name for trt3270schemadatainit.lptEmState

    -- Initialize trt3270schema's own data (save the Icon information for later use in  SetMenuParent)
    trt3270schemadatainit.lptEmState ← emdata;
    InitTrt3270schemaData[lschema3270wn, @trt3270schemadatainit];

    --  store the language of the controller into EmHandle.
    emdata.lang ← tempLang;

    -- IMPORTANT NOTE: the order in which the various modules gets called matters. Do not change the order of the calls unless you know what you are doing.
    Em3270UserInputDefs.Create[lschema3270wn];

    -- Create Display Handle
    emdata.display ← VDTDefs.Create[
      lschemaParent: lschema3270wn, ctLines: Em3270BufferDefs.numberOfRows,
      ctCharsPerLine: Em3270BufferDefs.lineSize, charSize: magnified];
    VDTDefs.SetCursorShape[emdata.display, ghostunderscore];

    -- Create CharTransHandle,
    [emdata.lptToTransFile, emdata.spHandle] ← Em3270CharTransDefs.GetTransFile[hostLang: emdata.lang];     -- returns a pointer to the EBCDIC translation file.

    -- Create buffer Handle and store in a zone somewhere with pointer in trait data area.  Give buffer handle to Command Processor.
    emdata.buffer ← Em3270BufferDefs.Create[lschemaVDT: emdata.display, lptToTransFile: emdata.lptToTransFile];  -- get buffer handle

    -- Create Command Processor Handle
    emdata.command ← Em3270CmdProcessDefs.CreateCmd[
      lschemaWn: lschema3270wn, lptBufferData: emdata.buffer, lptToTransFile: emdata.lptToTransFile];

    -- Set up srt of status area
    rs3270Viewer ← ReturnRs[lschema3270wn];  -- returns 3270 viewer's dimentions
    srtstatus.sc ← [xc: 0, yc: (SchemaDefs.Rs[emdata.display].ht + wthBorder)];
    srtstatus.rs ← [wth: rs3270Viewer.wth, ht: Em3270StatusDefs.htStatusArea];
    emdata.status ← Em3270StatusDefs.InitInstance[];
    Em3270StatusDefs.SetSrt[lschema3270wn, srtstatus]; -- now a procedural interface

    -- Create GateStream, get stream handle, fork both GET and WaitAttention Processes.
    IF bvStreamOn THEN
    emdata.commun ← Em3270ComDefs.StartCom[
      lschemaWn: lschema3270wn, icon: icon3270, lptCmdData: emdata.command !
      Em3270ComDefs.AbortOpen =>   -- gently shut down all instance data created up to now
	{Destroy3270SchemaAndInstanceData[lschema3270wn]; GOTO comlinkfailed; }; ];


   --  ++== Create data needed for the Standard window and Install my schema in it
   --   These are the changes needed to accomminated rewrite of StandardWindow
   BEGIN
    ctxt: SelectionDefs.Ctxt;
    aqinstallctxt: StandardWindowDefs.Aqinstallctxt;
    sq: Wd ← DtwmPrivDefs.SquareFromIcon[icon3270];
    ctxt.lptr ← icon3270;
    SelectionDefs.DeselectCs[];    --   De-highlight current selection
    IconDefs.SetOpen[icon3270, DtwmPrivDefs.PosnFromSquare[sq]];  --   see DtwmPack.Open
    aqinstallctxt ← [
      rsDesired: [wth: rs3270Viewer.wth, ht: rs3270Viewer.ht],
      ctxt:  ctxt,
      pvdestall: Destall3270];

   --  Create standard window schema and install the 3270 schema into it.  lschemaNil tells Install to first create a standard window.
   StandardWindowDefs.Install[installee: lschema3270wn, stdwn: StandardWindowDefs.stdwnNil, installctxt: @aqinstallctxt];
<</*
--==============================================================================
Even though we test for too many windows in Open, might be a good idea
to double check here since Install has an ERROR for too many windows.
An abort EXITS clause would have to be provided to undo everything.
    StandardWindowDefs.Install[installee: lschema3270wn, stdwn: StandardWindowDefs.stdwnNil, installctxt: @aqinstallctxt ! StandardWindowDefs.Error => {
      SELECT type FROM
        tooManyWindows => MessageSwnDefs.DisplayMessage[keyDtWindows];
        ENDCASE => NULL; GOTO abort }];
--==============================================================================
*/>>
   END;



    -- Fork any independent Communications processes required here now that standard window is built and ready to receive & display information from the host.  We can not do the forking inside of  "Em3270ComDefs.StartCom" because there is not yet a window built to put any potentual output from the host.  It is only after the window is built and lschema3270wn installed that we are ready to accept anything from the host (ala the Get process).
    IF bvStreamOn THEN
    Em3270ComDefs.ForkComProcesses[emdata.commun];

    Em3270UserInputDefs.Reset[lschema3270wn];  -- set system available and 3 normal connect statuses
    icon3270.lschema ←  lschema3270wn;  -- to indicate that a valid schema is opened & associated with this icon.  Clear to NIL in Destall3270.

    McDefs.SetDefaultShape[];
    EXITS comlinkfailed => McDefs.SetDefaultShape[];
    END;  -- of ReturnControl3270Os


  --  This is the new Destall3270 associated with the rewrite of StandardWindow.
  Destall3270: StandardWindowDefs.Pvdestall =
    --  PROC [lschemaDestallee: Lschema, installctxt: Installctxt];
    -- Routine to let Standard window inform me that it is closing.  3270 does not have a icon.lschema opened as is the normal case in Star.  When the icon is opened it simply calls the option processor to do its thing then the icon's job is done.  It is then the job of the ReturnControl3270Os to create the lschema3270 and install it in the Standard window.  The Destall routine's job is to destroy that lschema3270 only (and Highlight the icon).  All of this is rather detailed I realize, but TRUE.

    BEGIN OPEN DtwmPrivDefs;
    icon: IconDefs.Icon ← installctxt.ctxt.lptr;  --  retrieve icon handle;
    posn: SchemaDefs.Posnarea;

    IF lschemaDestallee # SchemaDefs.lschemaNil THEN
      SchemaDefs.Destroy[lschemaDestallee];
    --   Indicate that a valid schema is no longer opened & associated with this icon
    icon.lschema ← SchemaDefs.lschemaNil;
    -- note I am not sure whether the above statement is actually necessary or correct.
    -- maybe is ok because I am setting icon.lschmea to nil and not 3270schema data. which needs to be referenced when the standard window actually gets close.

    --  Make the icon for closing window selection
    SelectionDefs.DeselectCs;

    --  The following statement should ok.
    SelectionDefs.SetCs[LSchemaDt[], seltypeIcon, [lptr[icon]]];

    --  Paint the icon with hiliting
    posn ← PosnFromSquare[SquareFromIcon[icon]];
    IconDefs.SetNoOpen[icon, posn];
    IconDefs.SetHighlight[icon, posn];

    END;   -- of Destall3270


  SetMenuParent: TreeEltDefs.Pvsetparent =
    -- 	PROC[ lschema, lschemaParent: Instance];
    -- SetMenuParent - This routine, which is called at Open time twice, replaces the normal SetParent in TreeeltOps only because it is the only way to add menu items to the header at open time.  This additional menu code should only be executed after the window and its parent exist (i.e, at StdWnSchemaDefs.Install in DtwmPack time).  The first time Set Parent is called is at InitTrttreeeltData time.  The control flow is StdWn schemaDefs.install  to  ViewerSchemaDefs.Install  to  TreeEltDefs.SetParent.  It calls TreeEltDefs.SetParentStd, then sets up the 3270-unique menu items.

    BEGIN
    -- Identify the Menu items
    miMakeDoc : MiSchemaDefs.Mi;
    lschemaStdWn: TraitDefs.Instance;   -- 3270 window's schema
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;

    TreeEltDefs.SetParentStd[lschema, lschemaParent];  --  first go set parent normally
    IF lschemaParent = SchemaDefs.lschemaNil THEN RETURN;  --  if no parent exist yet

    --  must locate the StdWnSchema which contains theis viewer "lschema".  It will contain the menu items.
    lschemaStdWn ← TreeEltDefs.AncestorOfType[lschema, trtstdwnschema];  -- I'm made up of a StdWindow!

    -- Set up 3270 window title
    emdata.lschemaTitle ← StdWnSchemaDefs.TitleFromStdWn[lschemaStdWn];
    TitleSchemaDefs.PushTitle[emdata.lschemaTitle, MYdata.icon,      --  The title of window is the hoat name.
	MYdata.icon.name];

    -- Get Menu schema from StdWnSchema
    emdata.lschemaMenu ← StdWnSchemaDefs.MenuFromStdWn[lschemaStdWn];
    miMakeDoc ← [msg:msgMakeDoc , pvmenucmd: MenuCmdMakeDoc, lschemaOwner: lschemaStdWn];

    -- Set up Menu items
    [] ← MenuSchemaDefs.AddMi[emdata.lschemaMenu, @miMakeDoc, mousemenutypeNil]; --  put in Header menu

    END;  --  of SetMenuParent


  GetTransHandle: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [handle: BaseOISToEFile] =
    -- Retrieve the lptr to the translation file assoicated with this instance of the emulator.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    handle ← emdata.lptToTransFile;
    RETURN;
    END;  -- of GetLangType

  GetLangType: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [lang: IBMlanguages] =
    -- Retrieve the language of the controller stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    lang ← emdata.lang;
    RETURN;
    END;  -- of GetLangType

  SetLangType: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema, lang: Em3270Defs.IBMlanguages] =
    --  Store the controller language in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    --  This procedure actually does not get called, It is here for ???.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    emdata.lang ← lang;
    RETURN;
    END;   -- SetLangType.

  GetBufferHandle: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [handle: LptBufferData] =
    -- Retrieve the Buffer Handle which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    handle ← emdata.buffer;
    RETURN;
    END;  -- of GetBufferHandle

  GetNameOfIcon: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [iconName: IconDefs.Name] =
    -- Retrieve the name of the 3270 icon. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    iconName ← IconDefs.NameFromIcon[MYdata.icon];
    RETURN;
    END;


  GetDisplayHandle: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [handle: VDTDefs.LschemaVDT] =
    -- Retrieve the Display Handle which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    handle ← emdata.display;
    RETURN;
    END;  -- of GetDisplayHandle


  GetSelType: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [SelectionDefs.Seltype] =
    --  returns the appropriate SelType according to the host language so that the correct Virtual Keyboard can be selected.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    SELECT emdata.lang FROM
      USenglish => RETURN[seltype3270US];
      UKenglish => RETURN[seltype3270UK];
      German => RETURN[seltype3270Ger];
      French => RETURN[seltype3270Fr];
      JapaneseKana => RETURN[seltype3270JK];
      Swedish => RETURN[seltype3270Sw];
      JapaneseEnglish => RETURN[seltype3270JEng];
      ENDCASE => RETURN[seltype3270US];
    END;

  GetComHandle: PUBLIC PROC [lschema: SchemaDefs.Lschema]
    RETURNS [handle: LptComData] =
    -- Retrieve the communications Handle which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    handle ← emdata.commun;
    RETURN;
    END;  -- of GetComHandle


  GetCmdHandle: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [handle: LptCmdData] =
    -- Retrieve the command Handle which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    handle ← emdata.command;
    RETURN;
    END;  -- of GetCmdHandle

  GetPrevCursorShape: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [crShape: VDTDefs.CRShape] =
    --  Retrieve the previous cursor shape which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    crShape ← emdata.prevCursorShape;
    RETURN;
    END;  -- of GetPrevCursorShape.

  SetPrevCrShape: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema, crShape: VDTDefs.CRShape] =
    -- Store cursor shape in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    emdata.prevCursorShape ← crShape;
    RETURN;
    END;   -- SetPrevCrShape.


  GetInputStatus: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [status: InputStatus] =
    -- Retrieve the input status which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    status ← emdata.inputStatus;
    RETURN;
    END;  -- of GetInputStatus


  SetInputStatus: PUBLIC PROCEDURE [
    lschema: SchemaDefs.Lschema, status: InputStatus] =
    -- Sets the input status which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    emdata.inputStatus ← status;
    RETURN;
    END;  -- of SetInputStatus

  GetMDTStream: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [putMDTStream: MDTStream] =
    -- Retrieve the Lpt to the data that are to be sent or was sent to the host which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    putMDTStream ← emdata.putMDTStream;
    RETURN;
    END;  --  GetLptPutBuf

  SetMDTStream: PUBLIC PROCEDURE [
    lschema: SchemaDefs.Lschema, putMDTStream: MDTStream] =
    -- Sets the Lpt to the data that are to be sent or was sent to the host which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    emdata.putMDTStream ← putMDTStream;
    RETURN;
    END;  --  SetInputStatus

  GetAIDStatus: PUBLIC PROCEDURE [lschema: SchemaDefs.Lschema]
    RETURNS [bvNoAID: Bv] =
    -- Retrieve the AID status which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    bvNoAID ← emdata.bvNoAID;
    RETURN;
    END;  -- GetAIDStatus

  SetAIDStatus: PUBLIC PROCEDURE [
    lschema: SchemaDefs.Lschema, bvNoAID: Bv] =
    -- Sets the AID status which is stored in the Emulator's hyper-space data area. lschema must be the 3270 schema.
    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;
    emdata.bvNoAID ← bvNoAID;
    RETURN;
    END;  -- SetLptPutBuf


  MenuCmdMakeDoc: PROC [lschema: SchemaDefs.Lschema] RETURNS [bvDehilite: Bv] =
    BEGIN OPEN Em3270BufferDefs;
    -- VARIABLES --
    aqeditctxt: WSStringDefs.Aqeditctxt; -- initialized in 'BeginEdit'
    attr: WSStringDefs.Attr;
    attributeArray: ARRAY[0..2) OF NSFile.Attribute;
    charNull: CharDefs.Char = CharDefs.Roman[null];
    charPosOnLine: [0..lineSize);
    currentIndex: CARDINAL;
    dc: NewDocConvertDefs.Dc;

    szDataTime: CARDINAL = 23;  -- size of time stamp suffix
    newname: WSStringDefs.String;  -- hold new name
    oldname: WSStringDefs.String ← [];  -- hold the host name
    iconName: WSStringDefs.String; -- name of icon
    lsvname: Lsv ← [szDataTime];

    GetString: FormatPilot.StringProc = {SvDefs.AppendLsvToLsv[lsvname, s];};

    oisName: NSString.String;
    fieldString: WSStringDefs.String;
    fileDest: NSFile.Handle;

    -- Basic font style to work from.
    -- Note: Though Titan appears to be fixed pitch, it is actually 'proportional'.
    fontdescription: WSFontDefs.Description = [
      size: 12,
      weight: medium,  -- initial value
      emphasis: normal,
      underline: FALSE, strikeout: FALSE, placement: nil, reserved2a:,
      pitch: fixed, ornateness: simple,
      family: WSFontDefs.familyTerminal,
      reserved2b:, reserved4a:, offset: 0, reserved4b:, unused:];
      
    ctLeftMargin: CARDINAL = 18;  -- value for left margin; should be mutilples of 6. contact text folks for explanation.

    -- Since converting the above FontstyleDescription into a Fontstyle (suitable for passing to AddPageBreak) is extremely hairy, we use Century for page breaks and new paragraph.  Note that the font is irrelevant anyway.

  ffstyle: FontstyleDefs.Fontstyle =
    FontstyleDefs.GetFontstyleDescription [FontstyleDefs.fontstyleidCentury10];


  fontstyledescription: FontstyleDefs.FontstyleDescription;
  myptctxtNil: TreeEltDefs.Ctxt ← TreeEltDefs.ctxtNil;
  sourceBuffer: LptBufferData ← NIL;
  lptToTransFile: BaseOISToEFile  ← NIL;
     -- Will be made to point to the translation file for the language of the IBM host
     -- mainframe associated with this 3270 window.

    -- LOCAL PROCEDURE --

    MoveText: Em3270PrivDefs.PvFieldAndNullsHit
      -- PROCEDURE[mainBuffer: VDTDefs.LptCharSeq, startPos: VDTDefs.CharPos,
      -- fLength: CARDINAL, bvHasAttribute: Bv ← TRUE, visibility: Em3270PivDefs.Visibility]
      -- this procedure is called for each field in a 3270 buffer --
      =
      BEGIN OPEN Em3270PrivDefs;

      -- VARIABLES --
      i: CARDINAL;
      char1, char2, newChar: CharDefs.Char;
      bvSkip: Bv;

      IncIndexAndCheckLine: PROCEDURE =
	BEGIN
	currentIndex ← currentIndex+1;
	IF currentIndex > bufferSize THEN ERROR;	-- too many characters for substring
	IF charPosOnLine = lineSize-1 THEN
	  BEGIN
	  charPosOnLine ← 0;		-- start a new line
	  WSStringDefs.AppendChar[@aqeditctxt, CharDefs.Roman[newLine]];
	  END
	ELSE charPosOnLine ← charPosOnLine+1;
	END;  -- of IncIndexAndCheckLine
	
      currentIndex ← startPos;

      IF bvHasAttribute THEN
	BEGIN
	  WSStringDefs.AppendChar[@aqeditctxt, CharDefs.Roman[space]];
	  IncIndexAndCheckLine[];	
	  IF (fLength = 1) OR (currentIndex = bufferSize) THEN RETURN;
	  fLength ← fLength-1;
      	END;
      SELECT visibility FROM
      	intense	=> fontstyledescription.fontdesc.weight ← heavy;
	ENDCASE => fontstyledescription.fontdesc.weight ← medium;
      fontstyledescription.fontdesc ← TxtFontDefs.Validate[fontstyledescription.fontdesc];
      WSStringDefs.SetAttr[@aqeditctxt, fontstyle, attr];

      i ← 0;
      -- Some accent characters can only be represented as 2 characters in 3270 can actually be represented as a single character in STAR document.
      WHILE i < fLength - 1 DO
	IF (mainBuffer[currentIndex] = charNull) OR (visibility = invisible) THEN
	  WSStringDefs.AppendChar[@aqeditctxt, CharDefs.Roman[space]]
	ELSE  {
	  char1 ← mainBuffer[currentIndex];
	  char2 ← mainBuffer[currentIndex+1];
	  [newChar, bvSkip] ← Em3270CharTransDefs.CoalesceDeadChar[lptToTransFile, char1, char2];
	  IF bvSkip THEN {
	    WSStringDefs.AppendChar[@aqeditctxt, newChar];
	    i ← i + 1;
	    IncIndexAndCheckLine[]; }
	  ELSE
	    WSStringDefs.AppendChar[@aqeditctxt, char1]; };
	IncIndexAndCheckLine[];
	i ← i + 1;
	ENDLOOP;
      IF i < fLength THEN {
	WSStringDefs.AppendChar[@aqeditctxt,
	  IF (mainBuffer[currentIndex] = charNull) OR (visibility = invisible) THEN
	    CharDefs.Roman[space]
	  ELSE mainBuffer[currentIndex]];
	IncIndexAndCheckLine[]; };
      END;  -- of MoveText (local to MenuCmdMakeDoc)

    Get3270schema: SchemaDefs.Pvuserproc =
      -- PROC [lscema, Ptctxt]
      BEGIN
      IF TraitDefs.ClassType[lschema] # trt3270schema
	THEN RETURN[continue]
      ELSE {
	oldname ← GetNameOfIcon[lschema];
	sourceBuffer ← GetBufferHandle[lschema];
	lptToTransFile ← GetTransHandle[lschema]; };
      RETURN[stop];
      END;  -- of Get3270schema (local to MenuCmdMakeDoc)

    -- MAIN CODE of MenuCmdMakeDoc STARTS HERE --

    fieldString ← WSStringUtilDefs.StringCreate[3*(bufferSize)+lineSize];
    fontstyledescription ← [
      header: [
      length: FontstyleDefs.ctBytesFontstyleDescription, type: WSStringDefs.byteFontTag],
      fontdesc: fontdescription];
    attr ← [bytes: LOOPHOLE[LONG[@fontstyledescription],LONG POINTER], loc: 0];

    -- Build the font attributes and the character into the WSString. --
    WSStringDefs.BeginEdit[@fieldString, @aqeditctxt];
    fontstyledescription.fontdesc ← TxtFontDefs.Validate[fontstyledescription.fontdesc];
    WSStringDefs.SetAttr[@aqeditctxt, fontstyle, attr];
	
    charPosOnLine ← 0; currentIndex ← 0;		-- initialize pointers
    McDefs.SetStandardShape[idHourGlass];
    [] ← SchemaDefs.EnumProgeny[		-- sourceBuffer ← BufferHandle
	lschema: lschema, pvuserproc: Get3270schema,
	ptctxt: @myptctxtNil];
    Reserve[sourceBuffer];			-- get buffer before it changes
    fileDest ← DocSchemaDefs.GetEmptyDoc[];	-- new document

    newname.bytes ← LOOPHOLE[spredefinedZone.NEW[ZoneMgrDefs.Bytes[(oldname.length + szDataTime)]], Bytes];
    newname.length ← 0;
    newname.maxlength ← oldname.length + szDataTime;
    WSStringUtilDefs.AppendStringToString[@newname, oldname];  -- append source icon name; oldname already holds name of host.
    -- Append Current date and time
    lsvname.length ← 0;
    FormatPilot.Date[GetString, Time.Current[], full];  -- append current date and time (full affects szDataTime)
    WSStringUtilDefs.AppendStringToString[@newname,
       		WSStringUtilDefs.StringFromMsg[MessageDefs.MsgFromLsv[lsvname]]];
    iconName ← newname;  -- assign contents of the resulting WS string   	
	
    oisName ← WSOISConvertDefs.OISFromWS[iconName];
    attributeArray ←
      [[name[oisName]],
      [extended[StarAttributeTypeDefs.clientStatus, NSFile.EncodeCardinal[0]]]];
    NSFile.Move[fileDest, DtwmPrivDefs.FileDt[],
	DESCRIPTOR[BASE[attributeArray],2], ];  -- associate name with fileDest
    NSFile.ClearAttributeList[DESCRIPTOR[BASE[attributeArray],2]];
    dc ← NewDocConvertDefs.CreateDc[fileDest];	-- create data space for document

    -- the following block is needed to set the desired left margin. In JStar the left margin is set by adding a new paragraph, this way it'll take effect without doing a paginate. In Non-JStar the left margin is set in the initial PFC; it will not take effect until the document is paginated. That the way JStar and AStar wanted it.   
    --=========================================
    IF MultiNatlDefs.variant = JStar THEN 
      {
      paradesc: ParastyleDefs.Paradesc;
      parahdr: TxtDefs.Header ←   
        ParastyleDefs.GetHeader[ParastyleDefs.GetParastyleDescription[ParastyleDefs.parastyleidLeftRagged]];
      parastyle: ParastyleDefs.Parastyle ← 
        ParastyleDefs.GetParastyleDescription[ParastyleDefs.parastyleidLeftRagged];  -- WSStringDefs.attrsDefault
      parastyle.bytes ← LOOPHOLE[spredefinedZone.NEW[ParastyleDefs.Aqparastyle]];
      parastyle.loc ← 0;  
      paradesc ← 
        ParastyleDefs.GetParadesc[ParastyleDefs.GetParastyleDescription[ParastyleDefs.parastyleidLeftRagged]];
      paradesc.parastylemetrics[leftIndent] ← ctLeftMargin;
      ParastyleDefs.SetHeader[parastyle, parahdr];
      ParastyleDefs.SetParadesc[parastyle, paradesc];
      NewDocConvertDefs.AddParagraph[dc, parastyle, ffstyle];
      spredefinedZone.FREE[@parastyle.bytes];
      }
    ELSE
      {
      char: WSCharDefs.Character;
      tile: WSCharDefs.Tile;
      pageStyle: PagestyleDefs.Pagestyle;
      pageLayout: PagestyleDefs.PageLayout;
      flow: TxtDefs.Flow ← TxtDocDefs.DocumentFlow[dc.lschema];
      [] ← TxtFlowDefs.AdvanceCharacter[flow]; -- Current Char is now PFC tile
      char ← TxtFlowDefs.CharacterCurrent[flow];
      TxtFlowDefs.Destroy[flow];
      IF char.aqplaincharacter.representation # tile THEN ERROR;
      tile ← char.aqplaincharacter.byteptr;
      pageStyle ← PagestyleDefs.PagestyleFromTile[dc.lschema, tile];
      pageLayout ← PagestyleDefs.GetPageLayout[pageStyle];
      pageLayout.pageDimensions.wthLeftMargin ← ctLeftMargin;
      DocSchemaForgotDefs.MarkDirty[dc.lschema]; 
      };
    --========================================

    EnumAllFieldsAndNulls[sourceBuffer, MoveText]; -- transfer all fields now
    WSStringDefs.EndEdit[@aqeditctxt];
    NewDocConvertDefs.AddText  		-- put entire edited string in document --
	[dc,WSStringDefs.Substring[fieldString,[locFirst:0,locLast:fieldString.length-1]],
	NewDocConvertDefs.fontstyleNil];
	
    Release[sourceBuffer];			-- ok for buffer to change now

    BEGIN
    localRef: NSFile.Reference;
    localRef ← NSFile.GetReference[fileDest];
    DtwmPrivDefs.PutIconOnDesktop[	-- put icon on desktop with name in it --
	localRef.fileID, iconName, 0]
    END;

    WSStringUtilDefs.DestroyString[fieldString];   -- release string storage
    NewDocConvertDefs.DestroyDc[dc];		-- release data space, close file
    NSFile.Close[fileDest];
    WSOISConvertDefs.DestroyOISString[oisName];
    spredefinedZone.FREE[@(iconName.bytes)];
    McDefs.SetDefaultShape[];
    RETURN[TRUE];
    END;  -- End of MenuCmdMakeDoc


  --MenuCmdSetWn: PROC [lschema:SchemaDefs.Lschema]  RETURNS [bvDehilite:Bv] =
  --BEGIN
  --  McDefs.SetStandardShape [idHourGlass];
  --  MessageSwnDefs.DisplayMessage[ keyNotImplemented ];
  --  McDefs.SetDefaultShape [];
  --  RETURN[TRUE];
  --END;	++ End of MenuCmdSetWn		++ STUB


  Destroy3270Wn: SchemaDefs.Pvdestroy =
    --	PROC[ lschema: Lschema];
    -- The SchemaOps.pvdestroy routine for 3270 is broken into two parts.  The first shuts down the communications instance and everything created subsequent to the Em3270ComDefs.Create in ReturnControl3270Os.  The second cleans up everything created prior to the Em3270ComDefs.Create, and destroys the schema itself and the trait instance.  This is so that ReturnControl3270Os can do only the latter part if the Em3270ComDefs.Create call fails.
    -- Gently perform any termination processing here before closing the Emulator.  These include:
    --	a.  Close the connection to the Host/ECS.
    --	b.  Pop Window's Title and all 3270 menu items
    --  c.  Destroy lschema3270 instance, all its children, and all emulator-associated instance data

    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;

    McDefs.SetStandardShape[idHourGlass];
    IF bvStreamOn THEN Em3270ComDefs.EndCom[GetComHandle[lschema]];  -- Close the connection to the Host/ECS

    -- Pop Window's Title and all 3270 menu items
    [] ← TitleSchemaDefs.PopTitle[emdata.lschemaTitle];
    MenuSchemaDefs.RemoveMi[emdata.lschemaMenu, [msgMakeDoc]];

    -- Destroy all the emulator's instance data areas (this must be the last action done by the emulator)
    Destroy3270SchemaAndInstanceData[lschema:lschema];  -- includes freeing lptEmState area

    McDefs.SetDefaultShape[];
    END;  -- End of Destroy3270Wn


  DestroyIcon: IconDefs.Pvdestroy =
    --	PROC[ icon:Icon ];
    -- When the 3270 Icon is actually deleted from the desktop this routine is invoked.  It will write any trait instance data to the icon's backing file object.

    BEGIN
    SetFileData[
      icon3270: icon !
      NSFile.Error => {
	IF error = [access[fileNotFound]] THEN CONTINUE ELSE REJECT}; ];
    IconDefs.DestroyStd[icon];  -- free up any trait data associated with this icon
    END;  -- of DestroyIcon

  Destroy3270SchemaAndInstanceData: SchemaDefs.Pvdestroy =
    --	PROC[ lschema: Lschema];
    --  This routine will call the "Destroy" routines for:
    --	a. the display (VDT) instance data
    --	b. the buffer instance data
    --	c. the command instance data
    --  d. the status area instance data
    --	e. return the global emulator storage area pointed to by the trait data
    --  f. and release the instance of lschema3270 and children

    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    emdata: LONG POINTER TO EmHandle ← MYdata.lptEmState;  -- having "emdata" here helps keep this routine stand-alone

    -- Destroy all emulator-associated instance data
    Em3270BufferDefs.Destroy[GetBufferHandle[lschema]];  -- Destroy buffer instance data
    Em3270CmdProcessDefs.DestroyCmd[GetCmdHandle[lschema]];  -- Destroy command instance data
    Em3270CharTransDefs.DeleteFileSpace[emdata.spHandle];  -- delete spaces allocated for the translation file.
    Em3270UserInputDefs.Destroy[lschema];   -- let user input have a chance to cleanup itself.
    Em3270StatusDefs.DestroyInstance[emdata.status]; -- Destroy status area instance data

    -- DeAllocate space for Emulator global data (allocated in ReturnControl3270Os)
    lpredefinedZone.FREE[@emdata];

    -- Destroy lschema3270 instance and all its children (VDT schema)
    SchemaDefs.DestroyStd[lschema];
    END;  -- of Destroy3270SchemaAndInstanceData


  InitTrt3270schemaData: PUBLIC PvInitTrt3270schemaData =
    --	PROC[ lschema:SchemaDefs.Lschema, ptdatainit: POINTER TO Trt3270schemadatainit ];
    -- Initialize the trt3270schema's trait data here for each new instance of 3270's trait.

    BEGIN
    MYdata: Lpttrt3270schemadata ← TraitDefs.MyData[lschema, trt3270schema];
    MYdata.icon ← ptdatainit.icon;  -- from input paramters
    MYdata.lptEmState ← ptdatainit.lptEmState;
    END;  --of  InitTrt3270schemaData


  InitTrt3270iconData: PUBLIC PvInitTrt3270iconData =
    --	PROC[ lschema:SchemaDefs.Lschema, ref:IconDefs.Reference, parent:IconDefs.File, ptdatainit: POINTER TO Trt3270icondatainit ];
    -- This routine will initialize trt3270icon's data from one of two sources depending on the following:   IF (valid data already exists on the file)
    --			THEN  use the file's data
    --			ELSE  use Trt3270icondatainit (default data);

    -- The data is store in the Attributes.clientFileWords field of the file as follows:
    --	terminal Address       - at a length of SIZE[GateStream.DeviceAddress]
    --	owning ECS Net Address - at a length of SIZE[System.NetworkAddress]
    --  controller address      - at a length of SIZE[CARDINAL]
    --  RS232C Port name length - at a length of SIZE[CARDINAL]
    --  RS232C Port name	- at a length of SIZE[RS232CPortname.length]  (variable)

    -- Note that the host controller name is stored in the Attributes.name field of the file.
    BEGIN
    file3270: NSFile.Handle ← NSFile.OpenChild[parent, ref.fileID];
    MYdata: Lpttrt3270icondata ← TraitDefs.MyData[lschema, trt3270icon];
    attributesRecord: NSFile.AttributesRecord;
    path: NSString.String;

    IF ValidFileData[file3270] THEN  {
      [MYdata.terminalAddress, MYdata.sysNetAddrECS, ,MYdata.portOnController, MYdata.language, path] ← GetFileData[file3270, @attributesRecord, spredefinedZone];
      NSString.FreeString[spredefinedZone, path];
      ClearFileData[@attributesRecord]; }
    ELSE
      BEGIN     --  it should not be false; otherwise portOnController and language would get defaulted.
      MYdata.terminalAddress ← ptdatainit.terminalAddress;  -- from input paramters
      MYdata.sysNetAddrECS ← ptdatainit.sysNetAddrECS;  -- from input paramters
      MYdata.portOnController ← ptdatainit.portOnController;
      MYdata.language ← ptdatainit.language;
      END;

    NSFile.Close[file3270];
    END;  --of  InitTrt3270iconData


  ValidFileData: PROCEDURE [file: NSFile.Handle]
    RETURNS [valid: BOOLEAN ← FALSE] =
    -- This routine will check the Attributes.clientFileWords field for its length to see if it has been set to any valid data (i.e., non-zero).  It assumes the file is opened.

    BEGIN
    attributes: NSFile.Attributes ← @attributesRecord;
    attributesRecord: NSFile.AttributesRecord;
    selArray: ARRAY [0..1) OF NSFile.ExtendedAttributeType ←
      [em3270AttrType];
    words: NSFile.Words;

    NSFile.GetAttributes[file, [extended: DESCRIPTOR[selArray]], @attributesRecord];  -- retrieve the name field
    words ← FilingUtilDefs.GetExtendedAttributeValue[attributesRecord.extended, em3270AttrType];

    IF BASE[words] = NIL OR LENGTH[words] = 0 THEN { -- might be old format - look in clientFileWords
      attrArrayCFW: ARRAY [0..1) OF NSFile.ExtendedAttributeType ← [StarAttributeTypeDefs.clientFileWords];
      NSFile.ClearAttributes[attributes];  -- get rid of anything left over from previous call
      NSFile.GetAttributes[file, [extended: DESCRIPTOR[attrArrayCFW]], attributes];
      words ← FilingUtilDefs.GetExtendedAttributeValue[attributesRecord.extended, StarAttributeTypeDefs.clientFileWords];
      IF BASE[words] = NIL OR LENGTH[words] = 0 THEN  -- reference not available
	valid←FALSE
      ELSE  -- reference in clientFileWords
	valid←TRUE;
      }
    ELSE  -- reference available in new format.
      valid←TRUE;

    NSFile.ClearAttributes[attributes];
    RETURN[valid];
    END;  -- of ValidFileData


  GetFileData: PUBLIC PROCEDURE [file: NSFile.Handle, attributes: NSFile.Attributes, z: UNCOUNTED ZONE]
    RETURNS [
      taddress: GateStream.DeviceAddress,
      netaddress: System.NetworkAddress,
      controllerAddr: CARDINAL,
      portOnController: GateStream.DeviceAddress,
      hostLang: IBMlanguages,
      ptrs232String: NSString.String] =
    -- This routine retrieves from the 3270 icon backing file all the data stored in the Attributes.clientFileWords field and brings it into memory.

    BEGIN
    LptfileData: TYPE = LONG POINTER TO FileAttributeData;  -- for star 3.oxr
    LptStar2FileAttributeData: TYPE = LONG POINTER TO Star2FileAttributeData;
    LptStar3wrAttributeData: TYPE = LONG POINTER TO Star3wrAttributeData;
    lptfileData: LptfileData;
    star3WrLptfileData: LptStar3wrAttributeData;
    numWds: CARDINAL;
    words: NSFile.Words;
    selArray: ARRAY [0..1) OF NSFile.ExtendedAttributeType ←
      [em3270AttrType];

    NSFile.GetAttributes[file, [extended: DESCRIPTOR[selArray]], attributes];  -- retrieve the ttyXAttrType field; previously in clientFileWords field
    words ← FilingUtilDefs.GetExtendedAttributeValue[attributes.extended, em3270AttrType];

    IF BASE[words] = NIL OR LENGTH[words] = 0 THEN { -- might be old format - look in clientFileWords
      attrArrayCFW: ARRAY [0..1) OF NSFile.ExtendedAttributeType ← [StarAttributeTypeDefs.clientFileWords];
      NSFile.ClearAttributes[attributes];  -- get rid of anything left over from previous call
      NSFile.GetAttributes[file, [extended: DESCRIPTOR[attrArrayCFW]], attributes];
      words ← FilingUtilDefs.GetExtendedAttributeValue[attributes.extended, StarAttributeTypeDefs.clientFileWords];
      IF BASE[words] = NIL OR LENGTH[words] = 0 THEN  -- reference not available
	lptfileData← NIL
      ELSE  -- reference in clientFileWords
	lptfileData ← LOOPHOLE[BASE[attributes.extended[0].value], LptfileData];	
      }
    ELSE  -- found a valid reference attribute
      lptfileData ← LOOPHOLE[BASE[words], LptfileData];

    -- Note the ordering of the following IF statments matters.
    IF lptfileData.version = Star3 THEN -- we have a Star 3.0xr or the newest version
      BEGIN
      --   normal processing.
      -- loophole into the FileAttributeData format.
      ptrs232String ← NSString.MakeString[z, lptfileData.maxlength];
      ptrs232String.length ← lptfileData.length;
      numWds ← NSString.WordsForString[ptrs232String.maxlength];
      Inline.LongCOPY[@(lptfileData.bytes), numWds, ptrs232String.bytes];
      RETURN[lptfileData.termaddr, lptfileData.ecsaddr, lptfileData.controllerAddr,
	       lptfileData.numOfTerm, lptfileData.lang,
	       ptrs232String];
      END;

    IF lptfileData.version = StarUnknown THEN    -- StarUnknown = unused6 of Em3270Defs.Language; it means the user did not delete the icon from the desktop as he was suppose to.
      BEGIN  -- this could be a star 2 or 3 will do nothing and tell user to delete all 3270 icon.
      -- default whatever we know and display message
      ptrs232String ← NSString.MakeString[z, 10];  -- temporary only just so the overall logic would work correctly.
      ZkeyMessageDefs.DisplayMessage[keyZ441];
      --  MessageSwnDefs.DisplayMessageLiteral[MessageDefs.MsgFromLsv["Delete and Refetch from Directory all 3270 icons on your desktop before proceeding "L]];
      RETURN[termAddrDflt, addrECSDflt, ,
	       maxNumPorts, unused6, ptrs232String];   -- open time key on lang field being unused6
      END;
		
    --   we have either a Star3.0wr version or a Star 2 version.
    IF lptfileData.version = LAST[CARDINAL] THEN  --  we have a Star 2 version because all ones mean this have got to be the terminal address of ANY, since the language can never be last[cardinal].
      BEGIN
      -- process according to star2format
      -- display message telling user to delete the icon.
      -- not sure whether we should try fixing up the icon or not.
      ptrs232String ← NSString.MakeString[z, 10];  -- temporary only just so the overall logic would work correctly.
      ZkeyMessageDefs.DisplayMessage[keyZ441];
      --  MessageSwnDefs.DisplayMessageLiteral[MessageDefs.MsgFromLsv["Delete and Refetch from Directory all 3270 icons on your desktop before proceeding "L]];
      RETURN[termAddrDflt, addrECSDflt, ,
	     maxNumPorts, unused6, ptrs232String];   -- open time key on lang field being unused6
      END;

    -- is bit 3 or 4 on, yes=>3.0
    IF Inline.BITAND[lptfileData.version, 24] # 0 THEN -- either bit 3 or bit 4 was on => lang field => star3.0wr
      BEGIN
      -- we have a star 3 icon.
      -- no need to tell the user what happened.
      -- process according to star 3 format,
      -- should probably fix it up
      star3WrLptfileData ← LOOPHOLE[lptfileData, LptStar3wrAttributeData];
      ptrs232String ← NSString.MakeString[z, star3WrLptfileData.maxlength];
      ptrs232String.length ← star3WrLptfileData.length;
      numWds ← NSString.WordsForString[ptrs232String.maxlength];
      Inline.LongCOPY[@(star3WrLptfileData.bytes), numWds, ptrs232String.bytes];
      RETURN[star3WrLptfileData.termaddr, star3WrLptfileData.ecsaddr, star3WrLptfileData.controllerAddr,
		  star3WrLptfileData.numOfTerm, star3WrLptfileData.lang, ptrs232String];
      END;
	
    -- this could be a star 2 or 3 will do nothing and tell user to delete all 3270 icon.
    -- default whatever we know and display message
    ptrs232String ← NSString.MakeString[z, 10];  -- temporary only just so the overall logic would work correctly.
    ZkeyMessageDefs.DisplayMessage[keyZ441];
    --  MessageSwnDefs.DisplayMessageLiteral[MessageDefs.MsgFromLsv["Delete and Refetch from Directory all 3270 icons on your desktop before proceeding "L]];
    RETURN[termAddrDflt, addrECSDflt, ,
	     maxNumPorts, unused6, ptrs232String];   -- open time key on lang field being unused6
    END;  -- of GetFileData


  ClearFileData: PUBLIC PROCEDURE [attributes: NSFile.Attributes] =
  -- This routine MUST be used inconjunction with GetFileData to free the storage that GetFileData allocates
  BEGIN  NSFile.ClearAttributes[attributes];  END;  -- of ClearFileData


  SetResourceParms: PUBLIC PvSetFileParms =
    --	PROCEDURE [icon3270: IconDefs.Icon, em3270data: PtDir3270RowData];
--==============================================================================
    -- This routine is called to initially write the 3270 emulator data to its icon's backing file and trt3270icon's trait data when the icon is being copied to the desktop.  This data must "live" forever (as long as the desktop does).  It will take the row data saved by Directory when the emulators where enumerated, places the host controller name in the Attributes.name field, and places the terminal address and system network address of the owning ECS in the Attributes.clientFileWords field of the file.  Note that no data is actually written to the main file, but the infotmation is stored in the Attribute record accoiated with this file.  The system network address of the owning ECS is retrieved by calling the Clearinghouse with the owning ECS name (from the row data) and extracting the address from the returned ECS entry.  The terminal address has not yet been specified by the user and therefore the default value is left in the trait data for now.  The option sheet processor will update this field when needed.
    -- The data is store in the Attributes.clientFileWords field of the file as follows:
    --	terminal Address	- at a length of SIZE[GateStream.DeviceAddress]
    --	owning ECS Net Address  - at a length of SIZE[System.NetworkAddress]
    --  controller address      - at a length of SIZE[CARDINAL]
    --  RS232C Port name length - at a length of SIZE[CARDINAL]
    --  RS232C Port name max length - at a length of SIZE[CARDINAL]
    --  RS232C Port name	- at a length of SIZE[RS232CPortname.length]  (variable)

    -- Some of the  file information is put into the trait data area here, as well as in InitTrt3270iconData, for easy of access in other parts of the emulator code.
    -- This routine is called as the very last thing in Directory3Pack.StartCopy.
--==============================================================================
    BEGIN  --/* Of PROC */
--==============================================================================
    -- Note that the host name need not be written to the Attributes.name field here (although it would not hurt) since it was put there already by the Directory by virtue of the fact that the information displayed in the second column of any directory divider is used to name the icon.  How about them apples!
--==============================================================================

    fileData: FileAttributeData;
    rs232NameLengthWords: CARDINAL;
    totalFileWords: CARDINAL;
    pt3270data: LONG POINTER TO Wd;
    rgwdResourceParms: NSFile.Words;
    attributeArray: ARRAY [1..1] OF NSFile.Attribute;
    attributeList: NSFile.AttributeList;
    MYdata: Lpttrt3270icondata ← TraitDefs.MyData[
      icon3270.iconInstance, trt3270icon];
    abortCHEnum: SIGNAL = CODE;
    file3270: NSFile.Handle ← NSFile.OpenChild[
      IconDefs.ParentFromIcon[icon3270], IconDefs.ReferenceFromIcon[icon3270].fileID];

    pathString: NSString.String ← NSString.MakeString[
      spredefinedZone, 
      NSName.maxFullNameLength];
    pathString ← NSString.AppendString[ --/* Local */
      pathString, 
      em3270data.nameOf3270Entry.local];
    pathString ← NSString.AppendString[ --/* Hack for inserting colon */
      pathString,
      NSString.StringFromMesaString[":"L]];
    pathString ← NSString.AppendString[ --/* Domain */
      pathString, 
      em3270data.nameOf3270Entry.domain];
    pathString ← NSString.AppendString[ --/* Hack for inserting colon */
      pathString,
      NSString.StringFromMesaString[":"L]];
    pathString ← NSString.AppendString[ --/* Organization */
      pathString, 
      em3270data.nameOf3270Entry.org];
    
    fileData ← [
      version: Star3,
      lang: em3270data.lang,  --/* new for 3.3 */
      termaddr: termAddrDflt,
      ecsaddr: addrECSDflt,  -- reset by SetECSAddr     
      controllerAddr: em3270data.controllerAddress,
      numOfTerm: 8,  --/* filled in later */
      length: pathString.length,
      maxlength: pathString.maxlength,
      bytes: ];

    rs232NameLengthWords ← NSString.WordsForString[pathString.maxlength];
    totalFileWords ← sztotal + rs232NameLengthWords;  -- fixed part + variable part
    pt3270data ← LOOPHOLE[spredefinedZone.NEW[ZoneMgrDefs.Words[totalFileWords]]];
    rgwdResourceParms ← DESCRIPTOR[pt3270data, totalFileWords];  -- base and length of the array of words
    attributeArray ← [
      [extended[em3270AttrType, rgwdResourceParms]]];
    attributeList ← DESCRIPTOR[attributeArray];

    BEGIN  --/* of scope-of-definition on file3270 & pt3270data for EXITS cause */
--==== Deleted SetECSAddr, GetECSAddr (local procs)
      
      barfCode: CH.ReturnCode;
      ch: CH.ConversationHandle;
      ok: BOOLEAN ← FALSE;
      problem: Auth.CallProblem ← other;
--X      name: NSName.Name ← NIL;
--==============================================================================
    -- Start of SetResourceParms mainline code
    -- Retrieve the ECSAddr associated with this IBM3270Host with Authentication
--==============================================================================
     
      THROUGH [0..2) DO
	[ch, problem] ← UserDefs.AcquireConversation[];
	IF ch = [NIL, NIL] THEN LOOP ELSE EXIT;
	ENDLOOP;
      IF ch = [NIL, NIL] THEN {
--$--	SELECT problem FROM 
--$--	  tooBusy => ZkeyMessageDefs.DisplayMessage[keyZ1114];
--$--	  cannotReachAS => ZkeyMessageDefs.DisplayMessage[keyZ1115];
--$--	  keysUnavailable => ZkeyMessageDefs.DisplayMessage[keyZ1116]
--$--	ENDCASE => ZkeyMessageDefs.DisplayMessage[keyZ1116];
--!	SELECT problem FROM 
--!	  tooBusy => MessageSwnDefs.DisplayMessage[keyAuthTooBusy];
--!	  cannotReachAS => MessageSwnDefs.DisplayMessage[keyAuthCannotReachAS];
--!	  keysUnavailable => MessageSwnDefs.DisplayMessage[keyUserKeysUnavailable]
--!	ENDCASE => MessageSwnDefs.DisplayMessage[keyUserKeysUnavailable];
	GOTO enumFail};
    
--X      name ← NSName.NameFromString[spredefinedZone, em3270data.nameOf3270Entry.local];
      [barfCode, fileData.ecsaddr, ok] ← CHCommonLookups.LookupAddress[
        conversation: ch, name: em3270data.nameOf3270Entry];
      IF NOT ok THEN {
        MessageSwnDefs.DisplayMessage[key3270ClhECSentryError];  -- "Error in ECS Clearinghouse entry associated with this 3270"
	GOTO enumFail;
      };
      
--==== DELETE KEY key3270RS232PortError:"Error in RS232C Port Clearinghouse entry assoicated with this 3270"

<</*
--==============================================================================
Set selected divider data into trt3270icon's trait data area
Note that the following statement may be omitted since CREATE has already set the default terminal address at InitTrt3270iconData time.  It is left here for carity sake since this is the time all trait and file data is being set.
--==============================================================================
*/>>
    MYdata.terminalAddress ← fileData.termaddr;
    MYdata.sysNetAddrECS ← fileData.ecsaddr;  -- set by SetECSAddr
<</*
--==============================================================================
the following 2 statement is necessary because Create default portOnController and language. We must change that to be same as what was enter in the clearinghouse.
--==============================================================================
*/>>
    MYdata.portOnController ← fileData.numOfTerm;
    MYdata.language ← fileData.lang;
<</*
--==============================================================================
Set Attributes.clientFileWords with terminaladdress + ECSaddress + controlleraddress + nameLength + name maxlength + RS232C Port name
--==============================================================================
*/>>
    Inline.LongCOPY[@fileData, sztotal, pt3270data];  -- copy over fixed portion
    Inline.LongCOPY[pathString.bytes, rs232NameLengthWords, pt3270data + sztotal];  -- copy over variable portion

    NSFile.ChangeAttributes[file3270, attributeList];  -- write 3270 data to Attributes fields

    NSFile.Close[file3270];
    NSString.FreeString[spredefinedZone, pathString];
    spredefinedZone.FREE[@pt3270data];  -- throw away array of clientFileWords data

    EXITS
    enumFail => {NSFile.Close[file3270];
		 NSString.FreeString[spredefinedZone, pathString];
    		 spredefinedZone.FREE[@pt3270data];  -- throw away array of clientFileWords data
		 ERROR DirectoryInternalDefs.LookupError;  -- raise error to be caught in Directory code
		};
    END;  -- of scope-of-definition on file3270 & pt3270data
    END;  -- of SetResourceParms


  SetFileData: PROCEDURE [icon3270: IconDefs.Icon] =
    -- This routine takes the trait data associated with this icon and updates the backing file object.
    -- At this point only the terminal address has the possibility of changing between icon creation and deletion.

    BEGIN
    MYdata: Lpttrt3270icondata ← TraitDefs.MyData[icon3270.iconInstance, trt3270icon];
    fileData: FileAttributeData;
    rs232NameLengthWords, totalFileWords: CARDINAL;
    rs232PortString: NSString.String;
    file3270: NSFile.Handle ← NSFile.OpenChild[IconDefs.ParentFromIcon[icon3270], IconDefs.ReferenceFromIcon[icon3270].fileID];
    pt3270data: LONG POINTER TO Wd;
    rgwdParms: NSFile.Words;  -- base and length of the array of words
    attributeArray: ARRAY [1..1] OF NSFile.Attribute;
    attributeList: NSFile.AttributeList;
    attributesRecord: NSFile.AttributesRecord;

    -- Insure that valid data exist on the file before accessing it (this will only not be TRUE when an error occured while copying an 3270 icon from the directory).
    IF NOT ValidFileData[file3270] THEN {NSFile.Close[file3270]; RETURN;};
    IF MYdata.language = unused6 THEN {NSFile.Close[file3270]; RETURN;};  -- the icon was a leftover from Star2 or earilier versions of Star3

    -- First get file data which is not stored in trait data area
    [ , , fileData.controllerAddr, , , rs232PortString] ← GetFileData[file3270, @attributesRecord, spredefinedZone];  -- get current file data
    -- ++== Note: it might not be nescessary to save the number of ports on controller and the language field also.
    fileData.lang ← MYdata.language;
    fileData.numOfTerm ← MYdata.portOnController;
    fileData.termaddr ← MYdata.terminalAddress;
    fileData.version ← Star3;
    fileData.ecsaddr ← MYdata.sysNetAddrECS;
    fileData.length ← rs232PortString.length;
    fileData.maxlength ← rs232PortString.maxlength;
    rs232NameLengthWords ← NSString.WordsForString[rs232PortString.maxlength];
    totalFileWords ← sztotal + rs232NameLengthWords;  -- fixed part + variable part
    pt3270data ← LOOPHOLE[spredefinedZone.NEW[ZoneMgrDefs.Words[totalFileWords]]];
    rgwdParms ← DESCRIPTOR[pt3270data, totalFileWords];
    attributeArray ← [ [extended[em3270AttrType, rgwdParms]] ];
    attributeList ← DESCRIPTOR[attributeArray];

    Inline.LongCOPY[@fileData, sztotal, pt3270data];
    Inline.LongCOPY[rs232PortString.bytes, rs232NameLengthWords, pt3270data + sztotal];

    NSFile.ChangeAttributes[file3270, attributeList];  -- write 3270 data to Attributes fields
    NSString.FreeString[spredefinedZone, rs232PortString];
    NSFile.Close[file3270];
    ClearFileData[@attributesRecord];  -- throw away rs232cport string name
    spredefinedZone.FREE[@pt3270data];  -- throw away array of clientFileWords data
    END;  -- of SetFileData


  ProcessCsNt: SchemaDefs.Pvprocesscsnt =
    --	PROC[lschema:SchemaDefs.Lschema, nt:NtDefs.Nt]
    BEGIN
    -- since the following operation can effect the data resided in the internal buffer Em3270BufferDefs.Reserve/Release must be called
    buffer: LptBufferData ← GetBufferHandle[lschema];
    Em3270BufferDefs.Reserve[buffer];
    WITH ntBound: nt SELECT FROM
      vrKeyboardChar =>
	Em3270UserInputDefs.ProcessInputChar[lschema, ntBound.string];
      vrKeyboard3270Special => Em3270UserInputDefs.Process3270Keyes[lschema, ntBound.special];
      vrKeyboardFunction =>
	Em3270UserInputDefs.ProcessFuntion[lschema, ntBound.fun];
      vrKeyboardFunrepeat =>
	Em3270UserInputDefs.ProcessFunRepeat[
	  lschema, ntBound.cvFunrepeat, ntBound.funrepeat];
      ENDCASE;
    Em3270BufferDefs.Release[buffer];
    END;  -- of ProcessCsNt


  ProcessBut: SchemaDefs.Pvprocessbut =
    --	PROC[lschema:SchemaDefs.Lschema, pbrequest:SchemaDefs.PBRequest]
    --		posnSchema = posn of addressed schema
    --							(must be unchanged on return)
    --		button:
    --			buttype = {butSelect, butAdjust, butCopy, butSameAs, butMove}
    --			sc = where the button was last seen
    --			bvInitial = true only on initial button down
    --			bvChanged = NOT bvInitial
    --			bvAnyInterest = FALSE
    --		direction = (ignored)
    --		rgnTrack = suggested tracking region
    --		ctxt = space to be used as 3270 sees fit
    --		processbutctrl = {timout, ignored, forward, backward, movement, buttonup, cancel}
    -- ProcessBut will be called by this 3270 list lschema's parent when it determines that the button lies within its rectangle.  This ProcessBut is very similar to SchemaDefs.ProcessButStd except that it handles hiliting and selection.
    -- (It does not yet handle adjusting.)
    -- The 3270 world assumes that if an ancestor of an lschema is the current CsOwner, then the lschema's ProcessBut will not be called.  Instead, the selected ancestor will handle all tracking within itself, and interpret any select button-up anywhere within its background or children as a multi-click to select its parent.

    BEGIN
    SELECT pbrequest.button.buttype FROM
      butSelect, butCopy, butMove  --, butSameAs--
	=> Em3270UserInputDefs.DoProcessBut[lschema, pbrequest];  -- handle legal button actions
      ENDCASE => {
	McDefs.SetStandardShape[idQuestion];
	SchemaDefs.ProcessButNopAbortMCSOnButtonUpStd[lschema, pbrequest];  -- handle illegal button actions
	McDefs.SetDefaultShape[];
	};
    END;  -- of ProcessBut


  Repaint3270: SchemaDefs.Pvrepaint =
    --	PROC[lschema:Lschema, schrt:Schrt]
    -- This routine will repaint a section of the 3270 schema.  schrt/posn is the upper left corner of the schema, and schrt.srt is the schema-relative rectangle to be painted.  Actual storage for schrt is provided by the caller and may be overwritten.
    BEGIN
    display: VDTDefs.LschemaVDT ← GetDisplayHandle[lschema];
    srtVDT: RgnDefs.Srt ← [ScVDT[], SchemaDefs.Rs[display]];
    srtIntersect: RgnDefs.Srt ← [[0, 0], [0, 0]];  -- Initial value, will be intersected with schrt.srt
    aqschrt: SchemaDefs.Aqschrt;

    -- Prepare rectangle for erasing (include margins).
    RgnDefs.IntersectSrtSrt[@srtVDT, @schrt.srt, @srtIntersect];  -- get VDT portion to repaint

    -- Erase rectangle preparatory to painting onto it.
    DispDefs.EraseRectangle[rt: SchemaUtilDefs.RtFromRelrt[@schrt.posn, @schrt.srt]];
    -- repaint any boarders

    aqschrt ← [
      posn: SchemaUtilDefs.PosnFromPosnSc[@schrt.posn, srtVDT.sc],  -- VDT's posn ← schrt.posn+ScVDT
      srt: [
      SchemaUtilDefs.SubtractScs[sc1: srtIntersect.sc, sc2: srtVDT.sc], srtIntersect.rs]
      -- VDT's srt
      ];  -- get VDT's pos & srtIntersect translated relative to VDT's schema for VDT's repaint

    -- Have VDT repaint itself
    SchemaDefs.Repaint[display, @aqschrt];

    -- Have status area repaint itself
    Em3270StatusDefs.RepaintStatusArea[lschema, schrt];
    END;  -- of Repaint3270


  ReturnRs: SchemaDefs.Pvrs =
    --	PROC[lschema:Lschema] RETURNS[rs:Rsarea]
    -- This routine will report lschema's size (rs)
    BEGIN
    display: VDTDefs.LschemaVDT ← GetDisplayHandle[lschema];
    rsVDT: SchemaDefs.Rsarea ← SchemaDefs.Rs[display];

    rs.ht ← rsVDT.ht + wthBorder + Em3270StatusDefs.htStatusArea;  -- topboarder + status area hieght
    rs.wth ← rsVDT.wth + 2*wthBorder;  -- two side boarders
    RETURN;
    END;  -- of ReturnRs


  ReturnSc: SchemaDefs.Pvsc =
    --	PROC[lschema,lschemaChild: Lschema]  RETURNS[sc: Scrgn]
    -- This routine will report lschema's relative position sc of its child lschemaChild within itself.  May be expensive.
    -- assume even boarders and only one child!
    BEGIN RETURN[ScVDT[]]; END;  -- of ReturnSc


  GetEldest: SchemaDefs.Pvgeteldest =
    --	PROC[lschema:Lschema] RETURNS[Instance]
    -- This routine returns the schema handle of lschema's eldest child (VDT)
    BEGIN
    RETURN[GetDisplayHandle[lschema]];  -- return VDT's lschema
    END;  -- of GetEldest

  PushOrPopCs: PUBLIC SelectionDefs.Pvpushorpopcs =  -- +++ Currently a NOOP.  May have to do somthing more valid here???
    --	PROC[lschema: Lschema, pushpop: Pushpop];
    BEGIN NULL END;  -- of PushOrPopCs


  CsCancelMCS: SelectionDefs.Pvcscancelmcs =  -- +++ Currently a NOOP.  May have to do somthing more valid here???
    --	PROC[lschema: Lschema, fun: Fun];
    BEGIN NULL END;  -- of CsCancelMCS


  KillSel: SelectionDefs.Pvkillsel =  -- May have to do somthing more valid here???
    --	PROC[lschema:Lschema, sel:Sel]
    BEGIN
    display: VDTDefs.LschemaVDT ← GetDisplayHandle[lschema];
    crShape:VDTDefs.CRShape ← VDTDefs.GetCursorShape[display];
    SetPrevCrShape[lschema, crShape];
    VDTDefs.SetCursorShape[display,
      (SELECT crShape FROM
	 underscore => ghostunderscore,
	 box => ghostbox,
	 ghostunderscore => ghostunderscore,
	 ghostbox => ghostbox,
	 invisible => invisible,
	 blinkunderscore => ghostunderscore,
	 blinkbox => ghostbox,
       ENDCASE => ghostunderscore)];
    END;  -- of KillSel



  -- Class Initialization
  -- Initialize all associated Ops vectors here
  -- Initialize all associated Data in "Open"
  Init: PROCEDURE =
    BEGIN
    -- Get pointers to each component's ops vector
    schemaOps: SchemaDefs.Pttrtschemaops ← TraitDefs.TraitOps[
      NIL, trt3270schema, trtschema];
    iconOps: IconDefs.Pttrticonops ← TraitDefs.TraitOps[
      NIL, trt3270icon, trticon];
    ctnrOps: IconDefs.Pttrtctnrops ← TraitDefs.TraitOps[
      NIL, trt3270icon, trtctnr];
    treeeltOps: TreeEltDefs.Pttrttreeeltops ← TraitDefs.TraitOps[
      NIL, trt3270schema, trttreeelt];

    -- The storage loacation for all of 3270 trait's ops are calulated within the Init routines.
    -- Initialize schema operations
    [] ← SchemaDefs.InitTrtschemaOps[NIL, trt3270schema];

    -- Init trtinstallee ops.
    [] ← StandardWindowDefs.InitTrtinstalleeOps[NIL, trt3270schema];

    -- Initialize icon operations
    -- 3270 isn't really a ctnr or nonctnr, but nonctnr is closer
    [] ← IconDefs.InitTrticonOps[NIL, trt3270icon, nonctnr];
    [] ← IconDefs.InitTrtctnrOps[NIL, trt3270icon, nonctnr];

    -- Initialize 3270schema operations ( trt3270schema has no ops of its own(yet), no initialization is needed here)

    -- Now override any schema ops of IconSchema
    iconOps.pvopen ← Open;  -- must replace; link to open & build 3270 window
    iconOps.pvdestroy ← DestroyIcon;  --update file with trait data
    ctnrOps.pvcanyoutake ← IconDefs.CanYouTakeDflt;  -- 3270 icon can't take anything dropped on it

    -- Now override any schema ops of StandardSchema
    -- this is a new op
--    schemaOps.pvpostinstall ← SetMenuAndTitle;    set up menu and title.
    schemaOps.pvdestroy ← Destroy3270Wn;  -- close 3270 emulator window
    schemaOps.pvprocesscsnt ← ProcessCsNt;  -- process current selection
    schemaOps.pvprocessbut ← ProcessBut;  -- handle button actions
    schemaOps.pvrepaint ← Repaint3270;  -- repaint a section of 3270's schema
    schemaOps.pvrs ← ReturnRs;  -- report current size
    schemaOps.pvsc ← ReturnSc;  -- report relative position
    schemaOps.pvpushorpopcs ← PushOrPopCs;  -- save and restor current selection (NOOP)
    schemaOps.pvcscancelmcs ← CsCancelMCS;  -- if destination refuses M/C/SA or user hits STOP
    schemaOps.pvkillsel ← KillSel;  -- kill the current selection
    -- 3270 assumes that these replacements have been made in SchemaDefs.InitTrtschemaOps
    --schemaOps.pvgetspecialkeyboard ← SelectionDefs.GetSpecialKeyboardStd;  ++ passesto next guy or returns"none"



    -- Now override any TreeElt ops
  -- Note we no longer need to supply our own ops vector for this pvsetparent if we set up out menu and title at pvpostinstall time.
    treeeltOps.pvsetparent ← SetMenuParent;  -- build menu items and set parent schema
    treeeltOps.pvgeteldest ← GetEldest;  -- return schema of my eldest (ONLY) child

    -- Need to have some of Em3270StatusDefs's exported variables (e.g.,htStatusArea) initialized before the first call to something inside of Em3270StatusDefs
    START Em3270StatusDefs.Em3270StatusPack;
    END;  -- of Init


  --  Mainline  Code

  Init[];  -- go initialize the 3270 class's ops (at boot time)

  END.   -- of Em3270Pack


LOG
March 14, 1982 - Kernaghan - Created
March 19, 1982 - Kernaghan - Cleaned up Repaint3270; Renamed lschema3270 to lschemaStdWn in
  SetMenu Parent.
March 23, 1982 - Kernaghan - Add code to access real Clearinghouse and store/get new file data.
  Make GetFileData and ClearFileData PUBLIC.
24-Mar-82 - RHansen - implemented code to make star document.
March 29, 1982 - Kernaghan - Add call to Em3270ComDefs.ForkComProcesses inside of
  "ReturnControl3270Os" to fix a timing problem whereby input from host would be available
  before the window was built.
March 29, 1982 - Kernaghan - Add a check for bvStreamOn before calling ForkComProcesses
  (for debugging purposes).
7-Apr-82 - Hansen/Stepak - fixed attribute processing bugs in MenuCmdMakeDoc.
12-Apr-82 - Weissman - Pass schrt to Em3270StatusDefs.RepaintStatusArea
14-Apr-82 - Kernaghan - Add code to OPEN to first check for Emulation product factoring.
14-Apr-82 - Kernaghan - Add code to SetResourceParms to gently handle incorrect Clearinghouse
  entry information.
14-Apr-82 - RHansen - Add code to MakeDoc to use the faster convertion method.
15-Apr-82 - Kernaghan - Add code to SetFileData to insure that valid data exist on the file
  before accessing it.
20-Apr-82 - Kernaghan - Add code to ReturnControl3270Os to opsizn.destroy the newly created
  lschema3270wn when a communications error was encountered while trying to create a Stream.
29-Apr-82 - Kernaghan - Remove the opsizn.destroy from ReturnControl3270Os and handle the space
  deallocation of all instance and children data areas better in Destroy3270SchemaAndInstanceData
  by using SchemaDefs.DestroyStd on 3270's lschema.
14-Jul-82 - Lui - added Em3270BufferDefs.Reserve/Release to ProcessCsNt
21-Jul-82 - Lui - assign cursorShape to be ghostunderscore at open time.
  Added GetPrevCursorShape and SetPrevCrShape. Added codes to KillSel
 4-Aug-82 - Lui - Moved SubtractScs and RtFromRelrt from SchemaDefs to SchemaUtilDefs.
 6-Aug-82 - Lui - Moved  PosnFromSquare and SquareFromIcon from DtwmTempDefs to DtwmPrivDefs.
 6-Aug-82 - Lui - Modify code to use StandardWindowDefs (the changes have been commented out
   for the moment until a verson exist in integration).
12-Aug-82 - Lui - Add StarStartDefs.
20-Aug-82 - Lui - Modify code to use StandardWindowDefs.
25-Aug-82 - Lui - Added language and portOnController.
 1-Sep-82 - Lui - Modified MenuCmdMakeDoc to enable multiNational support. (Accent keys)
 2-Sep-82 - Lui - forgot to call StandardWindowDefs.inittrtinstallee
 9-Sep-82 - Lui - added lptToTransFile
14-Sep-82 - Lui - added called to PswnDefs.OsIsUp and PswnDefs.PsIsUp at Open time. AR# 8181
16-Sep-82 - Lui - changed SetMenuParent so that the Host Name is used as Window Title
September 21, 1982 - Hanzel - Converted to Filing 5.0 and new Clearinghouse for 3.0i.
27-Sep-82 - Hanzel - got rid of warning messages.
28-Sep-82 - Lui - edited MenuCmdMakeDoc, change name of icon created by MakDoc from
   "3270-date-time" to "HostName-Date-Time"
29-Sep-82 - Lui - added GetSelType
 4-Oct-82 - Lui - replaced keyZ08 with key3270No3270Emulation; keyZ12 with
   key3270ClhECSentryError; keyZ11 with key3270RS232PortError;
 4-Oct-82 - Lui - added UKenglish.
12-Oct-82 - Lui - edited SetResourceParms to reflect changes to Directory2Pack
13-Oct-82 - Lui - added new message keys and activated language and portOnController.
28-Oct-82 - Lui - changed the way how path got stored into backing file.
 4-Nov-82 - Lui - edited MenuCmdMakeDoc, newname was getting address faults.
 5-Nov-82 - Lui - dded EmForgotDefs.emulatorIconError
 9-Nov-82 - Lui - SetFileData was storing the MYdata.portOnController to controllerAddr
   whether than to numOfTerm. AR #9621
18-Nov-82 - Lui - changed fontdescription to use new terminal fonts. using familySpare35,
   size 8 for MakeDoc.
19-Nov-82 - Lui - size 8 was too small, a user can hardy see it on the display.
   changed it back to size 12.
 9-Dec-82 - Lui - added called to Em3270CharTransDefs.DeleteFileSpace.
13-Dec-82 - Lui - fixed space leak in SetResourceParms (pathString).
15-Feb-83 - Lui - edited GetFileData, SetFileData, and Open for backward compatability.
22-Feb-83 - Lui - replaced string literals with zkeys
 3-Mar-83 - Lui - AR 10459, raised EmForgotDefs.emulatorIconError instead of returning
   SchemaDefs.lschemaNil at open time.
25-Apr-83 - Lui - remove clientFileWord.
31-May-83 - Lui - AR ?????: 0 page margin.
10-Jun-83 - Lui - AR 13585: added JapaneseEnglish to GetSelType and SetResourceParms.
14-Jul-83 - Lui - support for Read Modified
30-Nov-83 - Pettit - Klamath conversion: GateStream.TerminalAddress -> DeviceAddress.
30-Jan-84 - Moursellas - Converted to Services 8.0.
30-Mar-84 15:49:38 - Caro - Begin conversion to Star 3.3E
 2-Apr-84 14:31:59 - Caro - pathstring in SetResourceParms must come from new em3270data that Directory must provide.  Commented out for now.
 5-Apr-84 15:36:29 - Caro - Updated to new Em3270Defs
 6-Apr-84 10:22:01 - Caro - Added new directory code to SetResourceParms
 9-Apr-84 15:17:10 - Caro - Fixed Open so that only six windows can open.
10-Apr-84 13:03:18 - Caro - Added loop to SetResourceParms for AcquireConversation
16-Apr-84 10:36:39 - Caro - Changed SetResourceParms to use ZKeys
19-Apr-84 15:13:45 - Caro - fixed name bug for CHCommonLookups in SetResourceParms
20-Apr-84 16:58:19 - Kernaghan - Changed SetResourceParms.em3270data.nameOf3270Entry from CH.ThreePartName to CH.Name.
 2-May-84 15:52:23 - Caro - Fixed open 7 windows bug in Open[] 
30-May-84 11:25:42 - Caro - Fixed AR 7554 in MenuCmdMakeDoc by using EmGTTYBufferPack code
22-Jun-84 13:27:37 - Lui - changed value of ctLeftMargin from 20 to 18. Left margins should be multiples of 6. Edited MenuCmdMakeDoc so that JStar's builti-in left margin is set by adding a paragraph, whereas AStar's left margin is set in PFC.