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    
020    package org.crsh.telnet.term;
021    
022    import net.wimpi.telnetd.io.BasicTerminalIO;
023    import net.wimpi.telnetd.io.TerminalIO;
024    import net.wimpi.telnetd.net.Connection;
025    import net.wimpi.telnetd.net.ConnectionData;
026    import org.crsh.text.Color;
027    import org.crsh.text.Decoration;
028    import org.crsh.text.Style;
029    import org.crsh.term.*;
030    import org.crsh.term.spi.TermIO;
031    
032    import java.io.EOFException;
033    import java.io.IOException;
034    import java.net.SocketException;
035    import java.util.HashMap;
036    
037    public 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    }