#module NEWSMODE "V5.6"

/*
**++
**  FACILITY:
**
**      NEWSMODE
**
**  ABSTRACT:
**
**      Map up and down arrow keys into NEWS, with an exit handler to restore
**      key settings
**
**  AUTHOR:
**
**      Geoff Huston
**
**  COPYRIGHT:
**
**      Copyright © 1988
**
**  MODIFICATION HISTORY:
**
**      V5.5     7-Oct-1988     GIH
**      V5.6    11-Nov-1988     GIH
**        - Make uparrow command user-settable between command recall and
**          cursor positioning mode.
**        - Make broadcast trapping user-settable.
**
**--
**/

#include "newsinclude.h"
#include "newsdefine.h"
#include "newsextern.h"

#include iodef
#include ttdef
#include tt2def

static unsigned short chan;
static int old_char_buf[3],
       new_char_buf[3] = {0,0,0},
       edit_on_buf[3],
       brd_char_buf[3],
       exit_handler_block[5] = {0,0,0,0,0},
       b_trap_flag = 1,
       b_trap_state = 0,
       line_flag = 1,
       line_state = 0;


/*
 *  exit_mode
 *
 *  Exit handler, to reset arrow key definition
 */

static exit_mode()
{
    int i;
    sys$cancel(chan);
    sys$qiow(0,chan,IO$_SETMODE,0,0,0,old_char_buf,12,0,0,0,0);
    for (i = 0 ; i < 3 ; ++i) new_char_buf[i] = old_char_buf[i];
    sys$dassgn(chan);
}

/*
 *  chg_mode
 *
 *  Turn off line edit mode to allow arrow keys to be sent to application
 */

chg_mode()
{
    int i;
    sys$assign(c$dsc("SYS$INPUT"),&chan,0,0);
    sys$qiow(0,chan,IO$_SENSEMODE,0,0,0,old_char_buf,12,0,0,0,0);
    exit_handler_block[1] = exit_mode;
    exit_handler_block[2] = 1;
    exit_handler_block[3] = &exit_handler_block[4];
    sys$dclexh(exit_handler_block);
    for (i = 0 ; i < 3 ; ++i) edit_on_buf[i] = new_char_buf[i] = old_char_buf[i];
    if (line_flag) new_char_buf[2] &= ~(TT2$M_EDITING);
    edit_on_buf[2] |= TT2$M_EDITING ;
    edit_m_off();
}

/*
 *  reset_mode
 *
 *  Revert mode to original, and cancel exit handler
 */

reset_mode()
{
    sys$canexh(exit_handler_block);
    line_state = 0;
    if (line_flag) {
        smg$delete_key_def(&keytab,c$dsc("UP"),0);
        smg$delete_key_def(&keytab,c$dsc("DOWN"),0);
        smg$delete_key_def(&keytab,c$dsc("UP"),c$dsc("GOLD"));
        smg$delete_key_def(&keytab,c$dsc("DOWN"),c$dsc("GOLD"));
        }
    exit_mode();
}

/*
 *  edit_m_on
 *  edit_m_off
 *
 *  Turn on/off line edit mode
 */

edit_m_off()
{
    line_state = 1;
    if (line_flag) {
        sys$qiow(0,chan,IO$_SETMODE,0,0,0,new_char_buf,12,0,0,0,0);
        smg$add_key_def(&keytab,c$dsc("UP"),0,c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("UP"),0);
        smg$add_key_def(&keytab,c$dsc("DOWN"),0,c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("DOWN"),0);
        smg$add_key_def(&keytab,c$dsc("UP"),c$dsc("GOLD"),c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("TOP"),0);
        smg$add_key_def(&keytab,c$dsc("DOWN"),c$dsc("GOLD"),c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("BOTTOM"),0);
        smg$add_key_def(&keytab,c$dsc("PREV_SCREEN"),0,c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("UP 18"),0);
        smg$add_key_def(&keytab,c$dsc("PREV_SCREEN"),c$dsc("GOLD"),c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("TOP"),0);
        smg$add_key_def(&keytab,c$dsc("NEXT_SCREEN"),0,c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("DOWN 18"),0);
        smg$add_key_def(&keytab,c$dsc("NEXT_SCREEN"),c$dsc("GOLD"),c$rfi(SMG$M_KEY_TERMINATE+SMG$M_KEY_NOECHO),c$dsc("BOTTOM"),0);
        }
}

edit_m_on()
{
    line_state = 0;
    if (line_flag) {
        smg$delete_key_def(&keytab,c$dsc("UP"),0);
        smg$delete_key_def(&keytab,c$dsc("DOWN"),0);
        smg$delete_key_def(&keytab,c$dsc("UP"),c$dsc("GOLD"));
        smg$delete_key_def(&keytab,c$dsc("DOWN"),c$dsc("GOLD"));
        sys$qiow(0,chan,IO$_SETMODE,0,0,0,edit_on_buf,12,0,0,0,0);
        }
}

set_line()
{
    if (line_flag) {
        new_char_buf[2] = edit_on_buf[2];
        if (line_state) {
            edit_m_on();
            line_state = 1;
            }
        line_flag = 0;
        }
    return(0);
}

set_noline()
{
    if (!line_flag) {
        new_char_buf[2] &= ~(TT2$M_EDITING);
        line_flag = 1;
        if (line_state) edit_m_off();
        }
    return(0);
}

no_broad_trap()
{
    b_trap_state = 0;
    if (b_trap_flag) {
        smg$disable_broadcast_trapping(&pid);
        sys$qiow(0,chan,IO$_SENSEMODE,0,0,0,brd_char_buf,12,0,0,0,0);
        brd_char_buf[1] &= ~(TT$M_NOBRDCST);
        old_char_buf[1] &= ~(TT$M_NOBRDCST);
        new_char_buf[1] &= ~(TT$M_NOBRDCST);
        edit_on_buf[1] &= ~(TT$M_NOBRDCST);
        if (new_char_buf[0]) sys$qiow(0,chan,IO$_SETMODE,0,0,0,new_char_buf,12,0,0,0,0);
        else sys$qiow(0,chan,IO$_SETMODE,0,0,0,brd_char_buf,12,0,0,0,0);
        }
}

broad_trap()
{
    b_trap_state = 1;
    if (b_trap_flag) {
        smg$set_broadcast_trapping(&pid,b_trap,0);
        sys$qiow(0,chan,IO$_SENSEMODE,0,0,0,brd_char_buf,12,0,0,0,0);
        brd_char_buf[1] |= TT$M_NOBRDCST;
        new_char_buf[1] |= TT$M_NOBRDCST;
        edit_on_buf[1] |= TT$M_NOBRDCST;
        if (new_char_buf[0]) sys$qiow(0,chan,IO$_SETMODE,0,0,0,new_char_buf,12,0,0,0,0);
        else sys$qiow(0,chan,IO$_SETMODE,0,0,0,brd_char_buf,12,0,0,0,0);
    }
}

set_broad()
{
    if (!b_trap_flag) {
        b_trap_flag = 1;
        if (b_trap_state) broad_trap();
        }
    return(0);
}

set_nobroad()
{
    if (b_trap_flag) {
        if (b_trap_state) {
            no_broad_trap();
            b_trap_state = 1;
            }
        b_trap_flag = 0;
        }
    return(0);
}
