001/*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020package org.crsh.telnet.term;
021
022import net.wimpi.telnetd.io.BasicTerminalIO;
023import net.wimpi.telnetd.io.TerminalIO;
024import net.wimpi.telnetd.net.Connection;
025import net.wimpi.telnetd.net.ConnectionData;
026import org.crsh.text.Color;
027import org.crsh.text.Decoration;
028import org.crsh.text.Style;
029import org.crsh.term.*;
030import org.crsh.term.spi.TermIO;
031
032import java.io.EOFException;
033import java.io.IOException;
034import java.net.SocketException;
035import java.util.HashMap;
036
037public class TelnetIO implements TermIO {
038
039  /** . */
040  private final Connection conn;
041
042  /** . */
043  private final BasicTerminalIO termIO;
044
045  /** . */
046  private boolean useAlternate;
047
048  public TelnetIO(Connection conn) {
049    this.conn = conn;
050    this.termIO = conn.getTerminalIO();
051    this.useAlternate = false;
052  }
053
054  public int read() throws IOException {
055    try {
056      return termIO.read();
057    }
058    catch (EOFException e) {
059      return TerminalIO.HANDLED;
060    }
061    catch (SocketException e) {
062      return TerminalIO.HANDLED;
063    }
064  }
065
066  public int getWidth() {
067    return termIO.getColumns();
068  }
069
070  public int getHeight() {
071    return termIO.getRows();
072  }
073
074  public String getProperty(String name) {
075    ConnectionData data = conn.getConnectionData();
076    if (data != null)
077    {
078      HashMap map = data.getEnvironment();
079      if (map != null) {
080        Object value = map.get(name);
081        if (value != null) {
082          return value.toString();
083        }
084      }
085    }
086    return null;
087  }
088
089  public boolean takeAlternateBuffer() throws IOException {
090    if (!useAlternate) {
091      useAlternate = true;
092      termIO.write("\033[?47h");
093    }
094    return true;
095  }
096
097  public boolean releaseAlternateBuffer() throws IOException {
098    if (useAlternate) {
099      useAlternate = false;
100      termIO.write("\033[?47l"); // Switches back to the normal screen
101    }
102    return true;
103  }
104
105  public CodeType decode(int code) {
106    switch (code) {
107      case 1304:
108        return CodeType.BEGINNING_OF_LINE;
109      case 5:
110        return CodeType.END_OF_LINE;
111      case 3:
112        return CodeType.BREAK;
113      case TerminalIO.TABULATOR:
114        return CodeType.TAB;
115      case TerminalIO.DELETE:
116      case TerminalIO.BACKSPACE:
117        return CodeType.BACKSPACE;
118      case TerminalIO.UP:
119        return CodeType.UP;
120      case TerminalIO.DOWN:
121        return CodeType.DOWN;
122      case TerminalIO.RIGHT:
123        return CodeType.RIGHT;
124      case TerminalIO.LEFT:
125        return CodeType.LEFT;
126      case TerminalIO.HANDLED:
127        return CodeType.CLOSE;
128      default:
129        return CodeType.CHAR;
130    }
131  }
132
133  public void close() {
134    conn.close();
135  }
136
137  public void flush() throws IOException {
138    termIO.flush();
139  }
140
141  public void write(CharSequence s) throws IOException {
142    termIO.write(s.toString());
143  }
144
145  public void write(Style style) throws IOException {
146    if (style == Style.reset) {
147      termIO.resetAttributes();
148      termIO.write("");
149    } else {
150      //
151      if (style instanceof Style.Composite) {
152        Style.Composite composite = (Style.Composite)style;
153        if (composite.getBold() != null) {
154          termIO.setBold(composite.getBold());
155        }
156        if (composite.getUnderline() != null) {
157          termIO.setUnderlined(composite.getUnderline());
158        }
159        if (composite.getBlink() != null) {
160          termIO.setBlink(composite.getBlink());
161        }
162        Color fg = composite.getForeground();
163        if (fg != null) {
164          termIO.setForegroundColor(30 + fg.code);
165        }
166        Color bg = composite.getBackground();
167        if (bg != null) {
168          termIO.setBackgroundColor(30 + bg.code);
169        }
170      } else {
171        termIO.resetAttributes();
172      }
173    }
174  }
175
176  public void write(char c) throws IOException {
177    termIO.write(c);
178  }
179
180  public void writeDel() throws IOException {
181    termIO.moveLeft(1);
182    termIO.write(' ');
183    termIO.moveLeft(1);
184    termIO.flush();
185  }
186
187  public void writeCRLF() throws IOException {
188    termIO.write("\r\n");
189  }
190
191  public boolean moveRight(char c) throws IOException {
192    termIO.moveRight(1);
193    return true;
194  }
195
196  public boolean moveLeft() throws IOException {
197    termIO.moveLeft(1);
198    return true;
199  }
200
201  public void cls() throws IOException {
202    termIO.eraseScreen();
203    termIO.setCursor(0, 0);
204  }
205}