?? NEWTITLE := 'NOS/VE Terminal Mgr. - Immediate Attribute Flush [2,3,D]' ??
MODULE ifm$immediate_attribute_flush;

{ PURPOSE:
{   This module contains the interface which causes immediate downloading
{   of queued attribute changes to the network.
{
{ DESIGN:
{   Doing an output with Term_Char_Null and Build_Msg_Block set to TRUE
{   puts a network block in the output queue which causes all attribute
{   changes (and the associated output data) queued by Terminal Manager
{   to be sent to the network (CDCNET or CCP).  The output buffer is then
{   flushed to immediately invoke the effects of the attribute values,
{   particularly the Input_Editing_Mode attribute and the transparent
{   mode attributes.
{
{   AMP$FLUSH for a terminal file causes the same results, except that
{   Term_Char_Null is not set to TRUE, causing the Input_Editing_Mode to
{   not be effected immediately.  AMP$GET_NEXT/PARTIAL will also accomplish
{   the same effect as this  interface with the added (and, maybe,
{   unwanted) effect of requesting input.
{
?? PUSH (LISTEXT := ON) ??
*copyc osd$default_pragmats
*copyc bat$task_file_table
*copyc bav$last_tft_entry
*copyc bav$task_file_table
*copyc ife$error_codes
*copyc ifk$keypoints
*copyc iip$flush
*copyc iip$put
*copyc iip$st_flush
*copyc iip$st_put
*copyc iiv$interactive_terminated
*copyc iiv$int_task_open_file_count
*copyc osp$set_status_abnormal
?? POP ??

?? TITLE := '[XDCL, #GATE] ifp$immediate_attribute_flush' ??

*copyc ifh$immediate_attribute_flush

  PROCEDURE [XDCL, #GATE] ifp$immediate_attribute_flush
    (file_id: amt$file_identifier;
     VAR status: ost$status);

    VAR
      file_identifier: amt$file_identifier,
      file_id_is_valid: boolean,
      file_instance: ^bat$task_file_entry,
      open_file_dsc_pointer: ^iit$open_file_description,
      st_open_file_dsc_pointer: ^iit$st_open_file_description,
      put_byte_address: amt$file_byte_address;


  /immediate_attribute_flush/
    BEGIN

{ Get the pointer to the open file description which was stored on the open.

      file_identifier := file_id;
*copy bai$validate_file_identifier
      IF iiv$network_identifier = iic$cdcnet_network THEN
*copy iii$fetch_st_open_file_desc_ptr
      ELSE
*copy iii$fetch_open_file_desc_ptr
      IFEND;
      IF NOT status.normal THEN
        EXIT /immediate_attribute_flush/;
      IFEND;

{ Perform an output with Term_Char_Null and Build_Msg_Block TRUE.

      iiv$put_info.build_msg_block := TRUE;
      iiv$put_info.term_char_null := TRUE;

      IF iiv$network_identifier = iic$cdcnet_network THEN
        iip$st_put (file_id, st_open_file_dsc_pointer, amc$put_partial_req,
              ^st_open_file_dsc_pointer^.attributes.prompt_string.value.value
              (1, 1), 0, ^put_byte_address, amc$terminate, status);
      ELSE
        iip$put (file_id, open_file_dsc_pointer, amc$put_partial_req,
              ^open_file_dsc_pointer^.attributes.prompt_string.value.value
              (1, 1), 0, ^put_byte_address, amc$terminate, status);
      IFEND;
      IF NOT status.normal THEN
        EXIT /immediate_attribute_flush/;
      IFEND;

{ Reset the Term_Char_Null and Build_Msg_Block flags.

      iiv$put_info.term_char_null := FALSE;
      iiv$put_info.build_msg_block := FALSE;

{ Flush the queued output data and its associated queued attribute changes.

      IF iiv$network_identifier = iic$cdcnet_network THEN
        iip$st_flush (file_id, st_open_file_dsc_pointer, status);
      ELSE
        iip$flush (file_id, open_file_dsc_pointer, status);
      IFEND;

    END /immediate_attribute_flush/;

  PROCEND ifp$immediate_attribute_flush;
MODEND ifm$immediate_attribute_flush;
