/*
* Copyright 2010 jOpenRay, ILM Informatique
* Copyright 2007 ymnk, JCraft,Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package com.jcraft.jcterm;
import java.io.InputStream;
public class EmulatorVT100 extends Emulator{
public EmulatorVT100(Term term, InputStream in){
super(term, in);
}
public void setInputStream(InputStream in){
this.in=in;
}
public void setTerm(Term term){
this.term=term;
}
public void start(){
reset();
int[] intarg=new int[10];
int intargi=0;
x=0;
y=charHeight;
byte b;
try{
while(true){
b=getChar();
//System.out.println("@0: "+ new Character((char)b)+"["+Integer.toHexString(b&0xff)+"]");
//System.out.println("@0: ry="+ry);
/*
outputs from infocmp on RedHat8.0
# Reconstructed via infocmp from file: /usr/share/terminfo/v/vt100
vt100|vt100-am|dec vt100 (w/advanced video),
am, msgr, xenl, xon,
cols#80, it#8, lines#24, vt#3,
acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, blink=\E[5m$<2>, bold=\E[1m$<2>,
clear=\E[H\E[J$<50>, cr=^M, csr=\E[%i%p1%d;%p2%dr,
cub=\E[%p1%dD, cub1=^H, cud=\E[%p1%dB, cud1=^J,
cuf=\E[%p1%dC, cuf1=\E[C$<2>,
cup=\E[%i%p1%d;%p2%dH$<5>, cuu=\E[%p1%dA,
cuu1=\E[A$<2>, ed=\E[J$<50>, el=\E[K$<3>, el1=\E[1K$<3>,
enacs=\E(B\E)0, home=\E[H, ht=^I, hts=\EH, ind=^J, ka1=\EOq,
ka3=\EOs, kb2=\EOr, kbs=^H, kc1=\EOp, kc3=\EOn, kcub1=\EOD,
kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA, kent=\EOM, kf0=\EOy,
kf1=\EOP, kf10=\EOx, kf2=\EOQ, kf3=\EOR, kf4=\EOS, kf5=\EOt,
kf6=\EOu, kf7=\EOv, kf8=\EOl, kf9=\EOw, rc=\E8,
rev=\E[7m$<2>, ri=\EM$<5>, rmacs=^O, rmam=\E[?7l,
rmkx=\E[?1l\E>, rmso=\E[m$<2>, rmul=\E[m$<2>,
rs2=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h, sc=\E7,
sgr=\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\016%e\017%;$<2>,
sgr0=\E[m\017$<2>, smacs=^N, smam=\E[?7h, smkx=\E[?1h\E=,
smso=\E[7m$<2>, smul=\E[4m$<2>, tbc=\E[3g,
*/
/*
am terminal has automatic margnins
msgr safe to move while in standout mode
xenl newline ignored after 80 cols (concept)
xon terminal uses xon/xoff handshake
cols number of columns in a line
it tabs initially every # spaces
lines number of lines on screen of page
vt virstual terminal number(CB/unix)
acsc graphics charset pairs, based on vt100
bel bell
blink turn on blinking
bold turn on bold(extra bright) mode
clear clear screen and home cursor(P*)
cr carriage return (P)(P*)
csr change region to line #1 to line #2(P)
cub move #1 characters to the left (P)
cub1 move left one space
cud down #1 lines (P*)
cud1 down one line
cuf move to #1 characters to the right.
cuf1 non-destructive space (move right one space)
cup move to row #1 columns #2
cuu up #1 lines (P*)
cuu1 up one line
ed clear to end of screen (P*)
el clear to end of line (P)
el1 Clear to begining of line
enacs enable alterate char set
home home cursor (if no cup)
ht tab to next 8-space hardware tab stop
hts set a tab in every row, current columns
ind scroll text up
ka1 upper left of keypad
ka3 upper right of keypad
kb2 center of keypad
kbs backspace key
kc1 lower left of keypad
kc3 lower right of keypad
kcub1 left-arrow key
kcud1 down-arrow key
kcuf1 right-arrow key
kcuu1 up-arrow key
kent enter/sekd key
kf0 F0 function key
kf1 F1 function key
kf10 F10 function key
kf2 F2 function key
kf3 F3 function key
kf4 F4 function key
kf5 F5 function key
kf6 F6 function key
kf7 F7 function key
kf8 F8 function key
kf9 F9 function key
rc restore cursor to position of last save_cursor
rev turn on reverse video mode
ri scroll text down (P)
rmacs end alternate character set
rmam turn off automatic margins
rmkx leave 'keybroad_transmit' mode
rmso exit standout mode
rmul exit underline mode
rs2 reset string
sc save current cursor position (P)
sgr define video attribute #1-#9(PG9)
sgr0 turn off all attributes
smacs start alternate character set (P)
smam turn on automatic margins
smkx enter 'keyborad_transmit' mode
smso begin standout mode
smul begin underline mode
tbc clear all tab stops(P)
*/
if(b==0){
continue;
}
if(b==0x1b){
b=getChar();
//System.out.println("@1: "+ new Character((char)b)+"["+Integer.toHexString(b&0xff)+"]");
if(b=='M'){ // sr \EM sr scroll text down (P)
scrollReverse();
continue;
}
if(b=='D'){ // sf
scrollForward();
continue;
}
if(b=='7'){
saveCursor();
continue;
}
if(b=='('){
b=getChar();
if(b=='B'){
b=getChar();
if(b==0x1b){
b=getChar();
if(b==')'){
b=getChar();
if(b=='0'){ // enacs
ena_acs();
continue;
}
else{
pushChar((byte)'0');
}
}
else{
pushChar((byte)')');
}
}
else{
pushChar((byte)0x1b);
}
}
else{
pushChar((byte)'B');
}
}
if(b=='>'){
b=getChar(); // 0x1b
b=getChar(); // '['
b=getChar(); // '?'
b=getChar(); // '3'
b=getChar(); // 'l'
b=getChar(); // 0x1b
b=getChar(); // '['
b=getChar(); // '?'
b=getChar(); // '4'
b=getChar(); // 'l'
b=getChar(); // 0x1b
b=getChar(); // '['
b=getChar(); // '?'
b=getChar(); // '5'
b=getChar(); // 'l'
b=getChar(); // 0x1b
b=getChar(); // '['
b=getChar(); // '?'
b=getChar(); // '7'
b=getChar(); // 'h'
b=getChar(); // 0x1b
b=getChar(); // '['
b=getChar(); // '?'
b=getChar(); // '8'
b=getChar(); // 'h'
reset_2string();
continue;
}
if(b!='['){
System.out.print("@11: "+new Character((char)b)+"["
+Integer.toHexString(b&0xff)+"]");
pushChar(b);
continue;
}
//System.out.print("@2: "+ new Character((char)b)+"["+Integer.toHexString(b&0xff)+"]");
intargi=0;
intarg[intargi]=0;
int digit=0;
while(true){
b=getChar();
//System.out.print("#"+new Character((char)b)+"["+Integer.toHexString(b&0xff)+"]");
if(b==';'){
if(digit>0){
intargi++;
intarg[intargi]=0;
digit=0;
}
continue;
}
if('0'<=b&&b<='9'){
intarg[intargi]=intarg[intargi]*10+(b-'0');
digit++;
continue;
}
pushChar(b);
break;
}
b=getChar();
//System.out.print("@4: "+ new Character((char)b)+"["+Integer.toHexString(b&0xff)+"]");
if(b=='m'){
/*
b=getChar();
if(b=='$'){
b=getChar(); // <
b=getChar(); // 2
b=getChar(); // >
}
else{
pushChar(b);
}
*/
if(digit==0&&intargi==0){
b=getChar();
if(b==0x0f){ // sgr0
exit_attribute_mode();
continue;
}
else{ // rmso, rmul
exit_underline_mode();
exit_standout_mode();
pushChar(b);
continue;
}
}
for(int i=0; i<=intargi; i++){
Object fg=null;
Object bg=null;
Object tmp=null;
switch(intarg[i]){
case 0: // Reset all attributes
exit_standout_mode();
continue;
case 1: // Bright // bold
enter_bold_mode();
continue;
case 2: // Dim
break;
case 4: // Underline
enter_underline_mode();
continue;
case 5: // Blink
case 8: // Hidden
break;
case 7: // reverse
enter_reverse_mode();
continue;
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
tmp=term.getColor(intarg[i]-30);
if(tmp!=null)
fg=tmp;
break;
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
tmp=term.getColor(intarg[i]-40);
if(tmp!=null)
bg=tmp;
break;
default:
break;
}
if(fg!=null)
term.setForeGround(fg);
if(bg!=null)
term.setBackGround(bg);
}
//System.out.println("fg: "+fg+" bg: "+bg);
continue;
}
if(b=='r'){ // csr
change_scroll_region(intarg[0], intarg[1]);
//System.out.println("r: "+region_y1+", "+region_y2+", intargi="+intargi);
continue;
}
if(b=='H'){ // cup
/*
b=getChar();
if(b!='$'){ // home
pushChar(b);
}
else{
b=getChar(); // <
b=getChar(); // 5
b=getChar(); // >
}
*/
if(digit==0&&intargi==0){
intarg[0]=intarg[1]=1;
}
//System.out.println("H: "+region_y1+", "+region_y2+", intargi="+intargi);
cursor_address(intarg[0], intarg[1]);
continue;
}
if(b=='B'){ // cud
parm_down_cursor(intarg[0]);
continue;
}
if(b=='D'){ // cub
parm_left_cursor(intarg[0]);
continue;
}
if(b=='C'){ // cuf
if(digit==0&&intargi==0){
intarg[0]=1;
}
parm_right_cursor(intarg[0]);
continue;
}
if(b=='K'){ // el
/*
b=getChar(); //
if(b=='$'){
b=getChar(); // <
b=getChar(); // 3
b=getChar(); // >
}
else{
pushChar(b);
}
*/
if(digit==0&&intargi==0){ // el
clr_eol();
}
else{ // el1
clr_bol();
}
continue;
}
if(b=='J'){
//for(int i=0; i<intargi; i++){ System.out.print(intarg[i]+" ");}
//System.out.println(intarg[0]+"<- intargi="+intargi);
clr_eos();
continue;
}
if(b=='A'){ // cuu
if(digit==0&&intargi==0){
intarg[0]=1;
}
parm_up_cursor(intarg[0]);
continue;
}
if(b=='?'){
b=getChar();
if(b=='1'){
b=getChar();
if(b=='l'||b=='h'){
b=getChar();
if(b==0x1b){
b=getChar();
if(b=='>'|| // rmkx , leave 'keybroad_transmit' mode
b=='='){ // smkx , enter 'keyborad_transmit' mode
// TODO
continue;
}
}
}
else if(b=='h'){
b=getChar();
if(b==0x1b){
b=getChar();
if(b=='='){ // smkx enter 'keyborad_transmit' mode
continue;
}
}
}
}
else if(b=='7'){
b=getChar();
if(b=='h'){ // smam
// TODO
//System.out.println("turn on automatic magins");
continue;
}
else if(b=='l'){ // rmam
// TODO
//System.out.println("turn off automatic magins");
continue;
}
pushChar(b);
b='7';
}
else{
}
}
if(b=='h'){ // kh \Eh home key
continue;
}
System.out.println("unknown "+Integer.toHexString(b&0xff)+" "
+new Character((char)b)+", "+intarg[0]+", "+intarg[1]+", "
+intarg[2]+",intargi="+intargi);
continue;
}
if(b==0x07){ // bel ^G
bell();
continue;
}
if(b==0x09){ // ht(^I)
tab();
continue;
}
if(b==0x0f){ // rmacs ^O // end alternate character set (P)
exit_alt_charset_mode();
continue;
}
if(b==0x0e){ // smacs ^N // start alternate character set (P)
enter_alt_charset_mode();
continue;
}
if(b==0x0d){
carriage_return();
continue;
}
if(b==0x08){
cursor_left();
continue;
}
if(b==0x0a){ // '\n'
//System.out.println("x="+x+",y="+y);
cursor_down();
//check_region();
continue;
}
if(b!=0x0a){ // !'\n'
pushChar(b);
draw_text();
continue;
}
}
}
catch(Exception e){
}
}
private static byte[] ENTER= {(byte)0x0d};
private static byte[] UP= {(byte)0x1b, (byte)0x4f, (byte)0x41};
private static byte[] DOWN= {(byte)0x1b, (byte)0x4f, (byte)0x42};
private static byte[] RIGHT= {(byte)0x1b, (byte)/*0x5b*/0x4f, (byte)0x43};
private static byte[] LEFT= {(byte)0x1b, (byte)/*0x5b*/0x4f, (byte)0x44};
private static byte[] F1= {(byte)0x1b, (byte)0x4f, (byte)'P'};
private static byte[] F2= {(byte)0x1b, (byte)0x4f, (byte)'Q'};
private static byte[] F3= {(byte)0x1b, (byte)0x4f, (byte)'R'};
private static byte[] F4= {(byte)0x1b, (byte)0x4f, (byte)'S'};
private static byte[] F5= {(byte)0x1b, (byte)0x4f, (byte)'t'};
private static byte[] F6= {(byte)0x1b, (byte)0x4f, (byte)'u'};
private static byte[] F7= {(byte)0x1b, (byte)0x4f, (byte)'v'};
private static byte[] F8= {(byte)0x1b, (byte)0x4f, (byte)'I'};
private static byte[] F9= {(byte)0x1b, (byte)0x4f, (byte)'w'};
private static byte[] F10= {(byte)0x1b, (byte)0x4f, (byte)'x'};
private static byte[] tab= {(byte)0x09};
public byte[] getCodeENTER(){
return ENTER;
}
public byte[] getCodeUP(){
return UP;
}
public byte[] getCodeDOWN(){
return DOWN;
}
public byte[] getCodeRIGHT(){
return RIGHT;
}
public byte[] getCodeLEFT(){
return LEFT;
}
public byte[] getCodeF1(){
return F1;
}
public byte[] getCodeF2(){
return F2;
}
public byte[] getCodeF3(){
return F3;
}
public byte[] getCodeF4(){
return F4;
}
public byte[] getCodeF5(){
return F5;
}
public byte[] getCodeF6(){
return F6;
}
public byte[] getCodeF7(){
return F7;
}
public byte[] getCodeF8(){
return F8;
}
public byte[] getCodeF9(){
return F9;
}
public byte[] getCodeF10(){
return F10;
}
public byte[] getCodeTAB(){
return tab;
}
}