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 */
9package jdk.internal.jline;
10
11import java.io.IOException;
12import java.io.InputStream;
13import java.io.OutputStream;
14
15import jdk.internal.jline.internal.Log;
16import jdk.internal.jline.internal.ShutdownHooks;
17import jdk.internal.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 */
25public 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}
124