/* Copyright (C) Magna Carta Software, Inc. 1988-1991. All Rights Reserved C COMMUNICATIONS TOOLKIT ANSI.C -- X3.64 terminal emulation routines. */ #define CCT_DEVELOPMENT #if (defined(CCTW) || defined(_WINDOWS)) #include #endif #include #include #include #include #include #include #include /* ANSI_CPR -- Send a cursor position report from an ANSI terminal. */ void ansi_cpr_(TERMINAL *t) { char *pa, asc[4]; term_write(t, t->csi); term_write(t, '['); itoa((*t->cur_get_row)(t)+1, asc, 10); pa = asc; while (*pa) term_write(t, *pa++); term_write(t, t->delim1); itoa((*t->cur_get_col)(t)+1, asc, 10); pa = asc; while (*pa) term_write(t, *pa++); term_write(t, 'R'); } /* ANSI_CURSOR -- Handle terminal movement commands. */ void ansi_cursor_(TERMINAL *t, short cmd) { switch(cmd) { case CUB: /* cursor back */ if (t->ccol > t->clmargin) { t->ccol = (t->num[0]==0) ? t->ccol-1 : max(t->ccol-t->num[0], t->clmargin); } break; case CUD: if (t->crow < t->cbmargin) { t->crow = (t->num[0] == 0) ? t->crow+1 : min(t->crow+t->num[0], t->cbmargin); } break; case CUF: if (t->ccol < t->crmargin) { t->ccol = (t->num[0] == 0) ? t->ccol+1 : min(t->ccol+t->num[0], t->crmargin); } break; case CUP: case HVP: t->crow = (t->num[0] == 0) ? t->ctmargin : t->ctmargin + t->num[0] - 1; t->ccol = (t->num[1] == 0) ? t->clmargin : t->clmargin + t->num[1] - 1; if (t->num[0] == 22 && t->num[1] == 0) t->num[0] = 22; break; case CUU: if (t->crow > t->ctmargin) { t->crow = (t->num[0] == 0) ? t->crow-1 : max(t->crow-t->num[0], t->ctmargin); } break; case IND: /* index */ if (t->crow == t->bmargin) (*t->scroll)(t, t->lmargin, t->tmargin, t->rmargin, t->bmargin, t->d_att, 1); else t->crow++; break; case NEL: /* next line */ if (t->crow == t->bmargin) (*t->scroll)(t, t->lmargin, t->tmargin, t->rmargin, t->bmargin, t->d_att, 1); else t->crow++; t->ccol = 0; break; case TRI: /* reverse index */ if (t->crow == t->tmargin) (*t->scroll)(t, t->lmargin, t->tmargin, t->rmargin, t->bmargin, t->d_att, -1); else t->crow--; break; default: #if XDEBUG printf("Unrecognized term_cursor() command %d", cmd); #endif break; } (*t->cur_pos_)(t, t->ccol, t->crow); } /* ANSI_ERASE -- Generic function to handle several erase commands. ANSI X3.64 escape code is "ESC [ Ps K" */ void ansi_erase_(TERMINAL *t, short cmd) { switch (cmd) { case ECH: (*t->ech)(t, SP, t->att, 1); break; case EED0: /* erase from active pos. to end of display */ case EED1: (*t->eed)(t, SP, t->d_att); break; case EBD: /* erase from start of display to active posn. */ (*t->ebd)(t, SP, t->d_att); break; case ED: /* erase all of display */ (*t->scroll)(t, 0, 0, t->d_cols, t->d_rows, t->d_att, 0); if (t->type == ANSI_SYS) { t->crow = 0; t->ccol = 0; (*t->cur_pos_)(t, 0, 0); } break; case EEL0: /* erase from active pos. to end of line */ case EEL1: if (t->type == ANSI_SYS) (*t->eel)(t, SP, t->att); else (*t->eel)(t, SP, t->d_att); break; case EBL: /* erase from start of line to active posn. */ (*t->ebl)(t, SP, t->d_att); break; case EL: /* erase all of line */ (*t->eil)(t, SP, t->d_att); break; default: #if XDEBUG printf("Unrecognized term_erase() command %d", cmd); #endif break; } } /* ANSI_HTS -- ANSI X3.64 tabulation set (HTS) ESC H. */ void ansi_hts_(TERMINAL *t) { t->tabstop[t->ccol] = (char) 1; } /* ANSI_INSERT -- Generic function to handle several insert commands. ANSI X3.64 escape codes: IL Insert Line "ESC [ Ps L" */ void ansi_insert_(TERMINAL *t, short cmd) { switch (cmd) { case IL: (*t->scroll)(t, t->lmargin, t->crow, t->rmargin, t->bmargin, t->d_att, -1); break; default: #if XDEBUG printf("Unrecognized ansi_insert() command %d", cmd); #endif break; } } /* ANSI_MEDIA_COPY -- ANSI X3.64 media copy commands. ANSI X3.64 commands CSIxxPn i */ void ansi_media_copy_(TERMINAL *t) { WORD i=0; while (i < t->parmcount || i == 0) { switch (t->num[0]) { case 0: /* copy entire screen to primary aux. device */ break; case 1: /* copy from primary auxilliary device */ break; case 2: /* copy entire screen to secondary aux. device */ break; case 3: /* copy from secondary auxilliary device */ break; case 4: /* turn off copying RX data to primary aux. */ t->ansimode &= ~PRN_CTRL; break; case 5: /* turn on copying RX data to primary aux. */ t->ansimode |= PRN_CTRL; break; case 6: /* turn off copying RX data to secondary aux. */ break; case 7: /* turn off copying RX data to secondary aux. */ break; default: #if XDEBUG printf("HOST: Unrecognized ANSI printer controller sequence"); #endif break; } i++; } } /* ANSI_PARSE_CMD -- Search forward through the the set of strings that may be received from the host for the one in the command buffer. Ignore parameter specifications ('%'). If the string is not found, return EOF, else return */ short ansi_parse_cmd_(TERMINAL *t, const char *n) { short i, j, k; TERM_RESPONSE *h = t->tr; BYTE ch; if (*n != '\0') { for (i=0; i < MAX_TERM_CMDS; i++) { if (h[i].sh2t[0] == '\0') continue; for (j=0, k=0; j < MAX_PARM_LEN && k < MAX_PARM_LEN; j++, k++) { #if XDEBUG if (i == SGR && n[k-1] == 'm') i = i; #endif ch = h[i].sh2t[j]; if (ch == '\0') return (i); while (n[k] == (char) t->delim1 || n[k] == (char) t->csi) k++; if (ch == '%' || ch == (BYTE) t->delim1) { while (h[i].sh2t[j] == '%' || h[i].sh2t[j] == (char) t->delim1) j++; while (isdigit(n[k]) || n[k] == (char) t->delim1) k++; } if (h[i].sh2t[j] == n[k]) continue; else break; } } } return (EOF); } /* ANSI_RESET -- Reset an ANSI X3.64 terminal to its initial state. */ void ansi_reset_(TERMINAL *t) { t = t; /* silence compiler warning */ return; } /* ANSI_RESET_MODE -- Called on receipt of "CSI Ps;...;Psl" (SM) sequence. This routine handles ANSI X3.64 modes. */ void ansi_reset_mode_(TERMINAL *t) { WORD i=0; while (i < t->parmcount || i == 0) { switch (t->num[i]) { case LNM: /* set CR = CRLF mode ON */ t->ansimode &= ~ANSI_LNM; break; default: break; } i++; } } /* ANSI_SET_MODE -- Called on receipt of "CSI Ps;...;Psh" (SM) sequence. This routine handles ANSI X3.64 modes. */ void ansi_set_mode_(TERMINAL *t) { WORD i=0; while (i < t->parmcount) { switch (t->num[i]) { case 0: break; case LNM: /* set CR = CRLF mode ON */ t->ansimode |= ANSI_LNM; break; default: break; } i++; } } /* ANSI_SGR -- Set screen attributes on ANSI X3.64 compatible terminals. Return value: 0 -- OK; EOF -- unrecognized attribute request; */ void ansi_sgr_(TERMINAL *t) { short fc, bc, blink, underscore; /* ATTRIBUTES */ short ch, ret = 0; short bright, reverse; WORD i=0; reverse = FALSE; fc = FG(t->att); bc = BG(t->att); blink = (t->att & 0X80) ? TRUE : FALSE; underscore = (fc == 1) ? TRUE: FALSE; bright = fc & 0X8; while (i < t->parmcount || i == 0) { #if 0 printf("Num[%d]=%d", i, t->num[i]); #endif switch(t->num[i]) { case 0: fc = FG(t->d_att); bc = BG(t->d_att); bright = reverse = underscore = blink = FALSE; break; case 1: bright = TRUE; break; case 4: underscore = TRUE; break; case 5: blink = TRUE; break; case 7: /* reverse video on */ fc = FG(t->d_att); bc = BG(t->d_att); bright = underscore = blink = FALSE; reverse = TRUE; break; case 8: /* cancelled on */ fc = bc; break; case 22: /* bright off */ bright = FALSE; break; case 24: /* underline off */ underscore = FALSE; break; case 25: /* blink off */ blink = FALSE; break; case 27: /* display positive image (?) */ reverse = FALSE; ch = fc; fc = bc; bc = ch; break; case 30: /* black foreground */ fc = BLACK; break; case 31: /* red foreground */ fc = RED; break; case 32: /* green foreground */ fc = GREEN; break; case 33: /* yellow foreground */ fc = YELLOW; break; case 34: /* blue foreground */ fc = BLUE; break; case 35: /* magenta foreground */ fc = MAGENTA; break; case 36: /* cyan foreground */ fc = CYAN; break; case 37: /* white foreground */ fc = LIGHTGREY; break; case 40: /* black background */ bc = BLACK; break; case 41: /* red background */ bc = RED; break; case 42: /* green background */ bc = GREEN; break; case 43: /* yellow background */ bc = YELLOW; break; case 44: /* blue background */ bc = BLUE; break; case 45: /* magenta background */ bc = MAGENTA; break; case 46: /* cyan background */ bc = CYAN; break; case 47: /* white background */ bc = LIGHTGREY; break; default: ret = EOF; break; } i++; /* increment to next attribute */ if (ret == EOF) break; } if (reverse) { ch = fc; fc = bc; bc = ch; } if (bright) fc |= 0X08; else if (fc != YELLOW) fc &= 0X7; if (blink) bc |= 0X08; else bc &= 0X7; if (underscore) fc |= 0X1; t->att = 0; /* necessary to fix a TC v2.0 bug */ t->att = (bc << 4) + fc; /* update terminal structure */ #if XDEBUG printf("fc=%d, bc=%d", fc, bc); printf("att=%#x", t->att); #endif } /* ANSI_TBC -- ANSI X3.64 tabulation clear (TBC) ESC [Psg. If Ps = 0 clear tabs at cursor column. If Ps = 3 clear all tabs. */ void ansi_tbc_(TERMINAL *t) { /* CLEAR ALL TABS */ if (t->num[0] == 3) memset(t->tabstop, 0, (size_t) t->d_cols); else t->tabstop[t->ccol] = 0; }