1 /*
   2  * Copyright (c) 2002-2012, the original author or authors.
   3  *
   4  * This software is distributable under the BSD license. See the terms of the
   5  * BSD license in the documentation provided with this software.
   6  *
   7  * http://www.opensource.org/licenses/bsd-license.php
   8  */
   9 package jline;
  10 
  11 import java.io.IOException;
  12 import java.io.InputStream;
  13 import java.io.OutputStream;
  14 
  15 import jline.internal.Log;
  16 import jline.internal.ShutdownHooks;
  17 import jline.internal.ShutdownHooks.Task;
  18 
  19 /**
  20  * Provides support for {@link Terminal} instances.
  21  *
  22  * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
  23  * @since 2.0
  24  */
  25 public abstract class TerminalSupport
  26     implements Terminal
  27 {
  28     public static final int DEFAULT_WIDTH = 80;
  29 
  30     public static final int DEFAULT_HEIGHT = 24;
  31 
  32     private Task shutdownTask;
  33 
  34     private boolean supported;
  35 
  36     private boolean echoEnabled;
  37 
  38     private boolean ansiSupported;
  39 
  40     protected TerminalSupport(final boolean supported) {
  41         this.supported = supported;
  42     }
  43 
  44     public void init() throws Exception {
  45         if (shutdownTask != null) {
  46             ShutdownHooks.remove(shutdownTask);
  47         }
  48         // Register a task to restore the terminal on shutdown
  49         this.shutdownTask = ShutdownHooks.add(new Task()
  50         {
  51             public void run() throws Exception {
  52                 restore();
  53             }
  54         });
  55     }
  56 
  57     public void restore() throws Exception {
  58         TerminalFactory.resetIf(this);
  59         if (shutdownTask != null) {
  60           ShutdownHooks.remove(shutdownTask);
  61           shutdownTask = null;
  62         }
  63     }
  64 
  65     public void reset() throws Exception {
  66         restore();
  67         init();
  68     }
  69 
  70     public final boolean isSupported() {
  71         return supported;
  72     }
  73 
  74     public synchronized boolean isAnsiSupported() {
  75         return ansiSupported;
  76     }
  77 
  78     protected synchronized void setAnsiSupported(final boolean supported) {
  79         this.ansiSupported = supported;
  80         Log.debug("Ansi supported: ", supported);
  81     }
  82 
  83     /**
  84      * Subclass to change behavior if needed.
  85      * @return the passed out
  86      */
  87     public OutputStream wrapOutIfNeeded(OutputStream out) {
  88         return out;
  89     }
  90 
  91     /**
  92      * Defaults to true which was the behaviour before this method was added.
  93      */
  94     public boolean hasWeirdWrap() {
  95         return true;
  96     }
  97 
  98     public int getWidth() {
  99         return DEFAULT_WIDTH;
 100     }
 101 
 102     public int getHeight() {
 103         return DEFAULT_HEIGHT;
 104     }
 105 
 106     public synchronized boolean isEchoEnabled() {
 107         return echoEnabled;
 108     }
 109 
 110     public synchronized void setEchoEnabled(final boolean enabled) {
 111         this.echoEnabled = enabled;
 112         Log.debug("Echo enabled: ", enabled);
 113     }
 114 
 115     public InputStream wrapInIfNeeded(InputStream in) throws IOException {
 116         return in;
 117     }
 118 
 119     public String getOutputEncoding() {
 120         // null for unknown
 121         return null;
 122     }
 123 }