*copyc OSD$DEFAULT_PRAGMATS
MODULE iim$st_send_attributes_change;
?? TITLE := 'MODULE iim$st_send_attributes_change' ??

?? PUSH (LISTEXT := ON) ??
*copyc iik$keypoints
*copyc iip$clear_lock
*copyc iip$set_lock
*copyc iip$connection_to_vt_attributes
*copyc iip$st_update_actual_attributes
*copyc iiv$connection_desc_ptr
*copyc iiv$interactive_terminated
*copyc ost$status
*copyc osv$job_pageable_heap
*copyc pmp$log
?? POP ??

?? NEWTITLE := 'PROCEDURE iip$st_send_attributes_change', EJECT ??

  PROCEDURE [XDCL] iip$st_send_attributes_change (downline_queue_entry: ^iit$st_downline_queue_entry;
        count: integer;
    VAR status: ost$status);

  { Construct a iit$vt_attributes from the different connection attributes in the downline queue
  { and the connection table.  Use this array to call iip$vt_change_attributes.

    VAR
      cdp,
      dqe: ^iit$connection_attributes,
      if_attributes: ^ift$connection_attributes,
      if_attributes_final: ^ift$connection_attributes,
      j: integer,
      k: integer;


  { Build an ift$connection_attributes array from those attribute records in the downline
  { queue entry which are different from those in the connection table.

    cdp := ^downline_queue_entry^.connection_ptr^.actual_connection_attributes;
    dqe := ^downline_queue_entry^.attributes;
    PUSH if_attributes:  [1 .. count];

  { Note - the following comparisons must exactly mimic those in iim$st_send_output_message,
  { otherwise we could have a problem with the array allocated at wrong dimension.

    j := 1;

    IF downline_queue_entry^.term_char_null THEN

      IF dqe^ .input_editing_mode.value <> cdp^ .input_editing_mode.value THEN
        if_attributes^ [j].key := ifc$input_editing_mode;
        if_attributes^ [j].input_editing_mode := dqe^ .input_editing_mode.value;
        j := j + 1;
      IFEND;

      IF dqe^ .trans_character_mode.value <> cdp^ .trans_character_mode.value THEN
        if_attributes^ [j].key := ifc$trans_character_mode;
        if_attributes^ [j].trans_character_mode := dqe^ .trans_character_mode.value;
        j := j + 1;
      IFEND;

      IF (dqe^ .trans_forward_character.value.size <> cdp^ .trans_forward_character.value.size) OR
            (dqe^ .trans_forward_character.value.value (1, dqe^ .trans_forward_character.value.size)
            <> cdp^ .trans_forward_character.value.value (1, cdp^ .trans_forward_character.value.size))
      THEN
        if_attributes^ [j].key := ifc$trans_forward_character;
        if_attributes^ [j].trans_forward_character := dqe^ .trans_forward_character.value;
        j := j + 1;
      IFEND;

      IF dqe^ .trans_length_mode.value <> cdp^ .trans_length_mode.value THEN
        if_attributes^ [j].key := ifc$trans_length_mode;
        if_attributes^ [j].trans_length_mode := dqe^ .trans_length_mode.value;
        j := j + 1;
      IFEND;

      IF dqe^ .trans_timeout_mode.value <> cdp^ .trans_timeout_mode.value THEN
        if_attributes^ [j].key := ifc$trans_timeout_mode;
        if_attributes^ [j].trans_timeout_mode := dqe^ .trans_timeout_mode.value;
        j := j + 1;
      IFEND;

      IF dqe^ .trans_message_length.value <> cdp^ .trans_message_length.value THEN
        if_attributes^ [j].key := ifc$trans_message_length;
        if_attributes^ [j].trans_message_length := dqe^ .trans_message_length.value;
        j := j + 1;
      IFEND;

      IF (dqe^ .trans_terminate_character.value.size <> cdp^ .trans_terminate_character.value.size) OR
            (dqe^ .trans_terminate_character.value.value (1, dqe^ .trans_terminate_character.value.size)
            <> cdp^ .trans_terminate_character.value.value (1, cdp^ .trans_terminate_character.
            value.size)) THEN
        if_attributes^ [j].key := ifc$trans_terminate_character;
        if_attributes^ [j].trans_terminate_character := dqe^ .trans_terminate_character.value;
        j := j + 1;
      IFEND;
    IFEND;  { term_char_null }


    IF dqe^ .attention_character_action.value <> cdp^ .attention_character_action.value THEN
      if_attributes^ [j].key := ifc$attention_character_action;
      if_attributes^ [j].attention_character_action := dqe^ .attention_character_action.value;
      j := j + 1;
    IFEND;

    IF dqe^ .break_key_action.value <> cdp^ .break_key_action.value THEN
      if_attributes^ [j].key := ifc$break_key_action;
      if_attributes^ [j].break_key_action := dqe^ .break_key_action.value;
      j := j + 1;
    IFEND;

    IF dqe^ .input_block_size.value <> cdp^ .input_block_size.value THEN
      if_attributes^ [j].key := ifc$input_block_size;
      if_attributes^ [j].input_block_size := dqe^ .input_block_size.value;
      j := j + 1;
    IFEND;

    IF dqe^ .input_output_mode.value <> cdp^ .input_output_mode.value THEN
      if_attributes^ [j].key := ifc$input_output_mode;
      if_attributes^ [j].input_output_mode := dqe^ .input_output_mode.value;
      j := j + 1;
    IFEND;

    IF dqe^ .partial_char_forwarding.value <> cdp^ .partial_char_forwarding.value THEN
      if_attributes^ [j].key := ifc$partial_char_forwarding;
      if_attributes^ [j].partial_character_forwarding := dqe^ .partial_char_forwarding.value;
      j := j + 1;
    IFEND;

    IF dqe^ .store_backspace_character.value <> cdp^ .store_backspace_character.value THEN
      if_attributes^ [j].key := ifc$store_backspace_character;
      if_attributes^ [j].store_backspace_character := dqe^ .store_backspace_character.value;
      j := j + 1;
    IFEND;

    IF dqe^ .store_nuls_dels.value <> cdp^ .store_nuls_dels.value THEN
      if_attributes^ [j].key := ifc$store_nuls_dels;
      if_attributes^ [j].store_nuls_dels := dqe^ .store_nuls_dels.value;
      j := j + 1;
    IFEND;

  { Convert the ift$connection_attributes array to a iit$vt_attributes array and use it
  { as input on a iip$vt_change_attributes call.
    IF j-1 > 0 THEN
      PUSH if_attributes_final: [1.. j-1];
      FOR k := 1 to  j-1 DO
        if_attributes_final^[k] := if_attributes^[k];
      FOREND;

      iip$connection_to_vt_attributes (downline_queue_entry^.connection_ptr, if_attributes_final^,
             status);
      IF NOT status.normal THEN
{!!   we are required to continue despite error }
        status.normal := TRUE;
      IFEND;

      { Update the actual_attributes in the terminal connection table.
      iip$st_update_actual_attributes (downline_queue_entry^.connection_ptr, if_attributes_final^,
          ifc$undefined_attribute);
    IFEND;

  PROCEND iip$st_send_attributes_change;

MODEND iim$st_send_attributes_change;
