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

?? PUSH (LISTEXT := ON) ??
*copyc iik$keypoints
*copyc IIT$CONNECTION_DESCRIPTION
*copyc iiv$int_task_open_file_count
*copyc IIP$BUILD_SUPER_MSG_SKELETON
*copyc IIP$CONVERT_DOWNLINE_TERM_CHAR
*copyc IIV$INTERACTIVE_TERMINATED
*copyc IIP$SEND_TO_PASS_ON
*copyc MLD$MEMORY_LINK_DECLARATIONS
*copyc pmp$task_debug_mode_on
*copyc OST$STATUS
?? POP ??


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

  PROCEDURE [XDCL] iip$send_attributes_change (downline_queue_entry_pointer:
    ^iit$downline_queue_entry;
        connection_desc_pointer: ^iit$connection_description;
    VAR status: ost$status);


    PROCEDURE build_fn_fv_pair (fn: 0..0ff(16),
          key: iic$key_user_break_1..iic$key_trans_mode_delim_char);

  {  Purpose: Add an FN/FV pair to the CTRL/CHAR/R supervisory message being built.

      output_supervisory_message.define_term_char.term_char_string [j].field_number := fn;
      output_supervisory_message.define_term_char.term_char_string [j].field_value := dqe^ [key];
      j := j + 1;

  {  Update the connection description's active_term_char_values array.
      cdp^ [key] := dqe^ [key];

    PROCEND build_fn_fv_pair;


    PROCEDURE build_fn_constant_pair (fn: 0..0ff(16),
          constant: 0..0ff(16));

  {  Purpose: Add an FN/FV pair to the CTRL/CHAR/R supervisory message being built.

      output_supervisory_message.define_term_char.term_char_string [j].field_number := fn;
      output_supervisory_message.define_term_char.term_char_string [j].field_value := constant;
      j := j + 1;

    PROCEND build_fn_constant_pair;


    VAR
      downloading: boolean,
      output_supervisory_message: iit$output_supervisory_message,
      define_term_char_message: iit$output_data_message,
      term_char_message_length: mlt$message_length,
      i: iic$key_user_break_1 .. iic$key_trans_mode_delim_char,
      j: 1 .. 15,
      dqe,
      cdp: ^array [1..15] of iit$field_value,
      send_term_char_pair,
      transparent_mode: boolean;


{ Build a define terminal characteristics message to change terminal
{ attributes.

    iip$build_super_msg_skeleton (^output_supervisory_message,
          iic$sm_define_term_char, 0);
    output_supervisory_message.header.address := connection_desc_pointer^.
          connection_number;
    output_supervisory_message.header.character_type := iic$8_bit_characters;
    output_supervisory_message.header.block_number :=
          downline_queue_entry_pointer^.message.header.block_number;

    downloading := false;
    j := 1;

    dqe := ^downline_queue_entry_pointer^.term_char_values;
    cdp := ^connection_desc_pointer^.active_term_char_values;

    IF dqe^ [iic$key_trans_input_mode] = 0 THEN
      IF cdp^ [iic$key_trans_input_mode] <> 0 THEN
        IF cdp^ [iic$key_trans_input_type] = iic$multi_message THEN
        { Turn transparent mode off. }
          build_fn_fv_pair (iic$fn_trans_input_mode, iic$key_trans_input_mode);
        ELSE
        { Update the connection description to reflect the drop of xparency inherent with single-message mode.
          cdp^ [iic$key_trans_input_mode] := 0;
        IFEND;
      IFEND;
    ELSE
      IF downline_queue_entry_pointer^.term_char_null THEN

      { Send transparency attribute changes only for output flushed because of a request for input.

        IF (dqe^ [iic$key_trans_input_type] = iic$single_message) OR
              (cdp^ [iic$key_trans_input_type] <> iic$multi_message) OR
              (cdp^ [iic$key_trans_input_mode] = 0) THEN
          downloading := TRUE;
        IFEND;
        IF dqe^ [iic$key_trans_input_type] <> cdp^ [iic$key_trans_input_type] THEN
          downloading := TRUE;
        IFEND;
        IF dqe^ [iic$key_trans_delim_char_select] <> cdp^ [iic$key_trans_delim_char_select] THEN
          downloading := TRUE;
        IFEND;
        IF dqe^ [iic$key_trans_delim_char_select] = 1 THEN
          CASE dqe^ [iic$key_trans_input_type] OF
          = iic$single_message =
            IF dqe^ [iic$key_trans_mode_delim_char] <> cdp^ [iic$key_trans_mode_delim_char] THEN
              downloading := TRUE;
            IFEND;
          = iic$multi_message =
            IF dqe^ [iic$key_trans_mode_delim_char] <> cdp^ [iic$key_trans_mode_delim_char] THEN
              downloading := TRUE;
            IFEND;
            IF dqe^ [iic$key_trans_delim_character] <> cdp^ [iic$key_trans_delim_character] THEN
              downloading := TRUE;
            IFEND;
          ELSE
          CASEND;
        IFEND;
        IF NOT downline_queue_entry_pointer^.transparent_count_selected THEN
          IF (cdp^ [iic$key_trans_delim_count_most] <> 0)
                OR (cdp^ [iic$key_trans_delim_count_least] <> 0) THEN
            downloading := TRUE;
          IFEND;
        ELSE
          IF (dqe^ [iic$key_trans_delim_count_least] <> cdp^ [iic$key_trans_delim_count_least])
                OR (dqe^ [iic$key_trans_delim_count_most] <> cdp^ [iic$key_trans_delim_count_most]) THEN
            downloading := TRUE;
          IFEND;
        IFEND;
        IF dqe^ [iic$key_trans_delim_timeout] <> cdp^ [iic$key_trans_delim_timeout] THEN
          downloading := TRUE;
        IFEND;
        IF (dqe^ [iic$key_trans_input_type] = iic$multi_message)
              AND (dqe^ [iic$key_trans_delim_timeout] <> 0)
              AND (dqe^ [iic$key_trans_mode_delim_lock] <> cdp^ [iic$key_trans_mode_delim_lock]) THEN
          downloading := TRUE;
        IFEND;

  {  Always turn transparent mode on unless multi_message is already in effect.

        IF downloading THEN

          { Turn transparent mode on. }
          build_fn_fv_pair (iic$fn_trans_input_mode, iic$key_trans_input_mode);
          IF NOT iiv$cdcnet_connection THEN
            IF connection_desc_pointer^.terminal_attributes.attention_character = CHR (0(16)) THEN
              build_fn_constant_pair (iic$fn_trans_interruptable, 0);
            ELSE
              build_fn_constant_pair (iic$fn_trans_interruptable, 1);
            IFEND;
          IFEND;

      {  Select transparent type.

          build_fn_fv_pair (iic$fn_trans_input_type, iic$key_trans_input_type);

      {  Select end character message and mode delimiter.

          build_fn_fv_pair (iic$fn_trans_delim_char_select, iic$key_trans_delim_char_select);   { 38(16):TDS }

          IF dqe^ [iic$key_trans_delim_char_select] = 1 THEN

          { Send a msg. and/or mode character delimiter only if they changed.

            CASE dqe^ [iic$key_trans_input_type] OF

            = iic$single_message =
              build_fn_fv_pair (iic$fn_trans_delim_character, iic$key_trans_mode_delim_char);   { 3b(16):TTC }

            = iic$multi_message =
              build_fn_fv_pair (iic$fn_trans_mode_delim_char, iic$key_trans_mode_delim_char);   { 45(16):TTC }
              build_fn_fv_pair (iic$fn_trans_delim_character, iic$key_trans_delim_character);   { 3b(16):TFC }

            ELSE
            CASEND;
          IFEND;

      {  Select transparent end count message delimiter.

          IF NOT downline_queue_entry_pointer^.transparent_count_selected THEN
            dqe^ [iic$key_trans_delim_count_least] := 0;
            dqe^ [iic$key_trans_delim_count_most] := 0;
            IF NOT iiv$cdcnet_connection THEN
              build_fn_fv_pair (iic$fn_trans_delim_count_most, iic$key_trans_delim_count_most);
              build_fn_fv_pair (iic$fn_trans_delim_count_least, iic$key_trans_delim_count_least);
            IFEND;
          ELSE
            build_fn_fv_pair (iic$fn_trans_delim_count_most, iic$key_trans_delim_count_most);
            build_fn_fv_pair (iic$fn_trans_delim_count_least, iic$key_trans_delim_count_least);
          IFEND;

      {  Select timeout message and mode delimiter.

          build_fn_fv_pair (iic$fn_trans_delim_timeout, iic$key_trans_delim_timeout);

          IF (dqe^ [iic$key_trans_input_type] = iic$multi_message)
                AND (dqe^ [iic$key_trans_delim_timeout] <> 0)
                AND (dqe^ [iic$key_trans_mode_delim_lock] <> cdp^ [iic$key_trans_mode_delim_lock])
                THEN
            build_fn_fv_pair (iic$fn_trans_mode_delim_lock, iic$key_trans_mode_delim_lock);
          IFEND;

        IFEND; {downloading}

      IFEND; { term_char_null}
    IFEND;
    FOR i := iic$key_user_break_1 TO iic$key_full_ascii DO

      IF dqe^ [i] <> cdp^ [i] THEN

      { Add the pair to the define terminal characteristics message

        output_supervisory_message.define_term_char.term_char_string [j].
              field_number := iiv$skeleton_term_char_string [i].field_number;
        output_supervisory_message.define_term_char.term_char_string [j].
              field_value := dqe^ [i];
        j := j + 1;

      { Update the active terminal characteristic value.

        cdp^ [i] := dqe^ [i];
      IFEND;

    FOREND;

    status.normal := TRUE;
    IF j > 1 THEN
      output_supervisory_message.header.text_length := (j - 1) * 2 + 2;

      iiv$term_char_change_count := iiv$term_char_change_count + 1;

{ Convert the define terminal characteristics message to C170 NAM format.

      iip$convert_downline_term_char (#LOC (output_supervisory_message), #LOC
            (define_term_char_message), iic$l_define_term_char * 8,
            term_char_message_length);

{ Send the define terminal characteristics message to Pass-On.

      iip$send_to_pass_on (iiv$int_application_name, #LOC
            (define_term_char_message), term_char_message_length,
            iic$output_data_message + iiv$job_connection, status);
    IFEND;


  PROCEND iip$send_attributes_change;

MODEND iim$send_attributes_change;
