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.Style;
028    import org.crsh.telnet.term.spi.TermIO;
029    
030    import java.io.EOFException;
031    import java.io.IOException;
032    import java.net.SocketException;
033    import java.util.HashMap;
034    
035    public 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    }