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.Style;
028import org.crsh.telnet.term.spi.TermIO;
029
030import java.io.EOFException;
031import java.io.IOException;
032import java.net.SocketException;
033import java.util.HashMap;
034
035public class TelnetIO implements TermIO {
036
037  /** . */
038  private final Connection conn;
039
040  /** . */
041  private final BasicTerminalIO termIO;
042
043  /** . */
044  private boolean useAlternate;
045
046  public TelnetIO(Connection conn) {
047    this.conn = conn;
048    this.termIO = conn.getTerminalIO();
049    this.useAlternate = false;
050  }
051
052  public int read() throws IOException {
053    try {
054      return termIO.read();
055    }
056    catch (EOFException e) {
057      return TerminalIO.HANDLED;
058    }
059    catch (SocketException e) {
060      return TerminalIO.HANDLED;
061    }
062  }
063
064  public int getWidth() {
065    return termIO.getColumns();
066  }
067
068  public int getHeight() {
069    return termIO.getRows();
070  }
071
072  public String getProperty(String name) {
073    ConnectionData data = conn.getConnectionData();
074    if (data != null)
075    {
076      HashMap map = data.getEnvironment();
077      if (map != null) {
078        Object value = map.get(name);
079        if (value != null) {
080          return value.toString();
081        }
082      }
083    }
084    return null;
085  }
086
087  public boolean takeAlternateBuffer() throws IOException {
088    if (!useAlternate) {
089      useAlternate = true;
090      termIO.write("\033[?47h");
091    }
092    return true;
093  }
094
095  public boolean releaseAlternateBuffer() throws IOException {
096    if (useAlternate) {
097      useAlternate = false;
098      termIO.write("\033[?47l"); // Switches back to the normal screen
099    }
100    return true;
101  }
102
103  public CodeType decode(int code) {
104    switch (code) {
105      case 1304:
106        return CodeType.BEGINNING_OF_LINE;
107      case 5:
108        return CodeType.END_OF_LINE;
109      case 3:
110        return CodeType.BREAK;
111      case TerminalIO.TABULATOR:
112        return CodeType.TAB;
113      case TerminalIO.DELETE:
114      case TerminalIO.BACKSPACE:
115        return CodeType.BACKSPACE;
116      case TerminalIO.UP:
117        return CodeType.UP;
118      case TerminalIO.DOWN:
119        return CodeType.DOWN;
120      case TerminalIO.RIGHT:
121        return CodeType.RIGHT;
122      case TerminalIO.LEFT:
123        return CodeType.LEFT;
124      case TerminalIO.HANDLED:
125        return CodeType.CLOSE;
126      default:
127        return CodeType.CHAR;
128    }
129  }
130
131  public void close() {
132    conn.close();
133  }
134
135  public void flush() throws IOException {
136    termIO.flush();
137  }
138
139  public void write(CharSequence s) throws IOException {
140    termIO.write(s.toString());
141  }
142
143  public void write(Style style) throws IOException {
144    if (style == Style.reset) {
145      termIO.resetAttributes();
146      termIO.write("");
147    } else {
148      //
149      if (style instanceof Style.Composite) {
150        Style.Composite composite = (Style.Composite)style;
151        if (composite.getBold() != null) {
152          termIO.setBold(composite.getBold());
153        }
154        if (composite.getUnderline() != null) {
155          termIO.setUnderlined(composite.getUnderline());
156        }
157        if (composite.getBlink() != null) {
158          termIO.setBlink(composite.getBlink());
159        }
160        Color fg = composite.getForeground();
161        if (fg != null) {
162          termIO.setForegroundColor(30 + fg.code);
163        }
164        Color bg = composite.getBackground();
165        if (bg != null) {
166          termIO.setBackgroundColor(30 + bg.code);
167        }
168      } else {
169        termIO.resetAttributes();
170      }
171    }
172  }
173
174  public void write(char c) throws IOException {
175    termIO.write(c);
176  }
177
178  public void writeDel() throws IOException {
179    termIO.moveLeft(1);
180    termIO.write(' ');
181    termIO.moveLeft(1);
182    termIO.flush();
183  }
184
185  public void writeCRLF() throws IOException {
186    termIO.write("\r\n");
187  }
188
189  public boolean moveRight(char c) throws IOException {
190    termIO.moveRight(1);
191    return true;
192  }
193
194  public boolean moveLeft() throws IOException {
195    termIO.moveLeft(1);
196    return true;
197  }
198
199  public void cls() throws IOException {
200    termIO.eraseScreen();
201    termIO.setCursor(0, 0);
202  }
203}