/* Copyright (C) Magna Carta Software, Inc. 1990. All Rights Reserved ALTOS3.C -- Altos III terminal emulation routines. */ #include #include #if defined(__TURBOC__) #include #elif defined(MSC) || defined(__WATCOMC__) || defined(__POWERC) #include #endif #include #include #include #include #include #include WORD pf[MAX_FUNC_KEYS] = {F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, ALT_F1, ALT_F2, ALT_F3, ALT_F4}; WORD shift_pf[] = {SF1, SF2, SF3, SF4, SF5, SF6, SF7, SF8, SF9, SF10, SF11, SF12, CTRL_F1, CTRL_F2, CTRL_F3, CTRL_F4}; WORD pad[MAX_PAD_KEYS] = {',', '-', KPERIOD, 0XFF, K0, K1, K2, K3, K4, K5, K6, K7, K8, K9}; WORD arrow[MAX_ARROW_KEYS] = {GREY_UP_ARROW, GREY_DOWN_ARROW, GREY_RIGHT_ARROW, GREY_LEFT_ARROW}; WORD shift_arrow[4] = {SUP_ARROW, SDOWN_ARROW, SRIGHT_ARROW, SLEFT_ARROW}; TERMKEYS tk_altos3 = { HOME, /* "HOME" key */ 0, /* "HELP" key (e.g. ALTOS III) */ KENTER, /* "enter" key */ TAB, /* horizontal tab */ ENTER, /* vertical tab */ PAGE_UP, /* key to page to prev screen */ PAGE_DOWN, /* key to page to next screen */ 16, /* number of function keys on terminal */ pf, /* programmable function keys */ shift_pf, /* shifted programmable function keys */ 15, /* number of keys on terminal keypad */ pad, /* programmable function keys */ 4, /* number of arrow keys on terminal */ arrow, /* PC arrow key codes */ shift_arrow, /* PC shift arrow key codes */ }; /* ALTOS3_INIT -- Initialize for ALTOS3 terminal emulation. This function is passed as a pointer to "init_port()". */ short altos3_init(TERMINAL *t) { t->csi1 = ESC; t->csi2 = '['; t->delim1 = ';'; t->mode = 0X8004; t->d_att = 7; t->att = 7; t->tk = &tk_altos3; ((struct comm_port *) t->port)->c_write = altos3_c_write; /* fn. to send byte to port */ ((struct comm_port *) t->port)->c_out = altos3_conoutc; /* local echo function */ return (0); } /* ALTOS3_WRITE -- VT100 driver function to send a byte out of the serial port. This function is pointed at by p->c_write (i.e. it replaces u8250_write(), etc. It is just a 'binding' to make the VT100 code independent of CCT. */ void altos3_c_write(COMM_PORT *p, short ch) { altos3_c_putc(p->term, ch); } /* ALTOS3_C_PUTC -- ALTOS III driver function to send a byte out of the serial port (typically, a keystroke). This function is pointed at by p->c_write (i.e. it replaces u8250_write(), and works if transmitter interrupts are enabled. 'ch' is the character to be sent out of the port. It may be a keystroke, in which case it can consist of a scan code in the high byte and a character code in the low byte. See KEYS.H and ASCII.H for key definitions. */ void altos3_c_putc(TERMINAL *t, short ch) { short i, f_ascii = TRUE; /* if (ch == TAB) printf("TAB pressed"); */ /* TEST FOR "HOME" */ if (ch == t->tk->home) { (*t->c_putc)(t, ESC); (*t->c_putc)(t, '['); ch = 'H'; f_ascii = FALSE; } /* TEST FOR "HELP" */ if (ch == t->tk->help) { (*t->c_putc)(t, SOH); (*t->c_putc)(t, 'P'); ch = CR; f_ascii = FALSE; } /* TEST FOR "PREVIOUS SCREEN" */ if (ch == t->tk->prevscreen) { (*t->c_putc)(t, ESC); (*t->c_putc)(t, '['); ch = 'T'; f_ascii = FALSE; } /* TEST FOR "NEXT SCREEN" */ if (ch == t->tk->nextscreen) { (*t->c_putc)(t, ESC); (*t->c_putc)(t, '['); ch = 'S'; f_ascii = FALSE; } /* TEST FOR A FUNCTION KEY */ for (i=0; i< t->tk->numfkeys; i++) { if (ch == t->tk->pf[i]) { /* F1 - F12, ALT_F1 - ALT_F4 */ (*t->c_putc)(t, SOH); (*t->c_putc)(t, '@' + i); ch = CR; f_ascii = FALSE; break; } if (ch == t->tk->shift_pf[i]) { /* SF1 - SF12, CTRL_F1 - CTRL_F4 */ (*t->c_putc)(t, SOH); (*t->c_putc)(t, '`' + i); ch = CR; f_ascii = FALSE; break; } } /* TEST FOR KEYPAD KEYS (in Application Mode) */ if (isapp()) { for (i=0; i< t->tk->numpadkeys; i++) { if ((ch & 0XFF) == t->tk->pad[i]) { (*t->c_putc)(t, ESC); (*t->c_putc)(t, 'O'); ch = 'l' + i; f_ascii = FALSE; break; } } /* TEST FOR ENTER KEY (on numeric keypad) */ if (ch == t->tk->enter) { (*t->c_putc)(t, ESC); (*t->c_putc)(t, 'O'); ch = 'M'; f_ascii = FALSE; } } /* TEST FOR ARROW KEYS */ for (i=0; i< t->tk->numarrowkeys; i++) { if (ch == t->tk->arrow[i]) { (*t->c_putc)(t, ESC); if (isapp() && iscur()) (*t->c_putc)(t, 'O'); else (*t->c_putc)(t, '['); ch = 'A' + i; f_ascii = FALSE; break; } if (ch == t->tk->shift_arrow[i]) { (*t->c_putc)(t, SOH); (*t->c_putc)(t, 'q' + i); ch = CR; f_ascii = FALSE; break; } } /* A VALID CHARACTER CODE */ if (f_ascii) switch(ch & 0XFF) { case CR: /* treat these as LFs */ case VT: case FF: if (isaddlf()) { (*t->c_putc)(t, CR); ch = LF; } break; default: break; } (*t->c_putc)(t, ch); /* send character */ } /* ALTOS3_CONOUTC --- Under ALTOS3 emulation, this function replaces conoutc(). It is just a 'binding' to make the ALTOS3 code independent of CCT. */ void altos3_conoutc(COMM_PORT *p, short ch) { altos3_parse(p->term, ch); } /* ALTOS3_PARSE -- All characters for output to the screen go through here. This is the ALTOS3 console emulation driver. */ void altos3_parse(TERMINAL *t, short ch) { short ret = 0; /* COMMAND SEQUENCE INTRODUCER RECEIVED */ if (ch == ESC) { #if DEBUG (*t->putc)(ch, FG(t->att | 8), BG(t->att)); #endif t->inescape = 1; t->s = t->sequence; /* initialize buffer ptr. */ memset(t->sequence, 0X0, MAX_ESC_LEN); /* initialize buffer */ } /* ALREADY IN AN ESCAPE SEQUENCE */ else if (t->inescape) { /* HANDLE BUFFER OVERFLOW */ if (t->s - t->sequence >= MAX_ESC_LEN) ret = EOF; else if (t->inescape == 1) { #if DEBUG (*t->putc)(ch, FG(t->att | 8), BG(t->att)); #endif *t->s++ = (char) ch; if (ch == '[' || ch == '(') t->inescape++; else { ret = ansi_dispatch(t, t->sequence, ch); if (ret == EOF) ret = vt100_dispatch(t, t->sequence, ch); ret = EOF; } } else { if (isalpha(ch)) { #if DEBUG (*t->putc)(ch, FG(t->att | 8), BG(t->att)); #endif ret = ansi_dispatch(t, t->sequence, ch); if (ret == EOF) vt100_dispatch(t, t->sequence, ch); if (ret == EOF) ret = altos3_dispatch(t, t->sequence, ch); ret = EOF; } else *t->s++ = (char) ch; } } /* CONTROL CHARACTER RECEIVED */ else if (iscntrl(ch)) ret = vt_dispatch_ctrl(t, ch); /* NON-CONTROL ASCII CHARACTER */ else (*t->putc)(ch, FG(t->att), BG(t->att)); if (ret == EOF) t->inescape = FALSE; } /* ALTOS3_DISPATCH -- Test for a DEC PRIVATE command received from the serial port. Return value: 0 -- OK EOF -- Command not recognized. */ short altos3_dispatch(TERMINAL *t, char *buf, short ch) { WORD num[128]; short count, ret = 0; t->ccol = cur_get_col(); t->crow = cur_get_row(); count = term_parse(buf, num, ';'); /* no. of parameters */ if (buf[0] == '[' || buf[0] == '(') { if (buf[1] == '?' || buf[1] == '>' || buf[1] == '=') { if (ch == 'h') ret = altos3_set_mode(t, num, count, buf[1]); else if (ch == 'l') ret = altos3_reset_mode(t, num, count, buf[1]); } } else ret = EOF; return (ret); } /* ALTOS3_SET_MODE -- Called on receipt of "CSI Ps;...;Psh" (SM) sequence. This routine sets ALTOS3 modes. */ short altos3_set_mode(TERMINAL *t, WORD *num, WORD len, WORD delim) { short i = 0, ret = 0; while (i < len) { if (delim == '>') switch(num[i]) { case 0: break; case 1: break; case 5: /* cursor invisible */ break; default: ret = EOF; break; } else if (delim == '=') switch(num[i]) { case 0: break; case 1: /* select printer echo mode */ break; case 2: /* select unformatted printer mode */ break; default: ret = EOF; break; } else ret = EOF; i++; } return (ret); } /* ALTOS3_RESET_MODE -- Called on receipt of "CSI Ps;...;Psl" (SM) sequence. This routine resets ALTOS3 modes. */ short altos3_reset_mode(TERMINAL *t, WORD *num, WORD len, WORD delim) { short i = 0, ret = 0; while (i < len) { if (delim == '>') switch(num[i]) { case 0: break; case 1: break; case 5: /* cursor visible */ break; default: ret = EOF; break; } else if (delim == '=') switch(num[i]) { case 0: break; case 1: /* select printer pass through mode */ break; case 2: /* select formatted printer mode */ break; default: ret = EOF; break; } else ret = EOF; i++; } return (ret); }