private Tuple2<Attributes, Map<Signal, SignalHandler>> prepareTerminal() { final Terminal terminal = client.getTerminal(); final Attributes prevAttributes = terminal.getAttributes(); // adopted from org.jline.builtins.Nano // see also https://en.wikibooks.org/wiki/Serial_Programming/termios#Basic_Configuration_of_a_Serial_Interface // no line processing // canonical mode off, echo off, echo newline off, extended input processing off Attributes newAttr = new Attributes(prevAttributes); newAttr.setLocalFlags(EnumSet.of(LocalFlag.ICANON, LocalFlag.ECHO, LocalFlag.IEXTEN), false); // turn off input processing newAttr.setInputFlags(EnumSet.of(Attributes.InputFlag.IXON, Attributes.InputFlag.ICRNL, Attributes.InputFlag.INLCR), false); // one input byte is enough to return from read, inter-character timer off newAttr.setControlChar(Attributes.ControlChar.VMIN, 1); newAttr.setControlChar(Attributes.ControlChar.VTIME, 0); newAttr.setControlChar(Attributes.ControlChar.VINTR, 0); terminal.setAttributes(newAttr); final Map<Signal, SignalHandler> prevSignals = new HashMap<>(); prevSignals.put(Signal.WINCH, terminal.handle(Signal.WINCH, this::handleSignal)); prevSignals.put(Signal.INT, terminal.handle(Signal.INT, this::handleSignal)); prevSignals.put(Signal.QUIT, terminal.handle(Signal.QUIT, this::handleSignal)); return Tuple2.of(prevAttributes, prevSignals); }
c_iflag = setFlag(t.getInputFlag(InputFlag.IGNBRK), IGNBRK, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.BRKINT), BRKINT, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.IGNPAR), IGNPAR, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.PARMRK), PARMRK, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.INPCK), INPCK, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.ISTRIP), ISTRIP, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.INLCR), INLCR, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.IGNCR), IGNCR, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.ICRNL), ICRNL, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.IXON), IXON, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.IXOFF), IXOFF, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.IXANY), IXANY, c_iflag); c_iflag = setFlag(t.getInputFlag(InputFlag.IMAXBEL), IMAXBEL, c_iflag); c_oflag = setFlag(t.getOutputFlag(OutputFlag.OPOST), OPOST, c_oflag); c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLCR), ONLCR, c_oflag); c_oflag = setFlag(t.getOutputFlag(OutputFlag.OCRNL), OCRNL, c_oflag); c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLRET), ONLRET, c_oflag); c_oflag = setFlag(t.getOutputFlag(OutputFlag.TABDLY), TABDLY, c_oflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.CS5), CS5, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.CS6), CS6, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.CS7), CS7, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.CS8), CS8, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.CSTOPB), CSTOPB, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.CREAD), CREAD, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.PARENB), PARENB, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.PARODD), PARODD, c_cflag); c_cflag = setFlag(t.getControlFlag(ControlFlag.HUPCL), HUPCL, c_cflag);
public Attributes toAttributes() { Attributes attr = new Attributes(); EnumSet<InputFlag> iflag = attr.getInputFlags(); addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); addFlag(c_iflag, iflag, InputFlag.IMAXBEL, IMAXBEL); EnumSet<OutputFlag> oflag = attr.getOutputFlags(); addFlag(c_oflag, oflag, OutputFlag.OPOST, OPOST); addFlag(c_oflag, oflag, OutputFlag.ONLCR, ONLCR); addFlag(c_oflag, oflag, OutputFlag.TABDLY, TABDLY); EnumSet<ControlFlag> cflag = attr.getControlFlags(); addFlag(c_cflag, cflag, ControlFlag.CS5, CS5); addFlag(c_cflag, cflag, ControlFlag.CS6, CS6); addFlag(c_cflag, cflag, ControlFlag.CLOCAL, CLOCAL); EnumSet<LocalFlag> lflag = attr.getLocalFlags(); addFlag(c_lflag, lflag, LocalFlag.ECHOKE, ECHOKE); addFlag(c_lflag, lflag, LocalFlag.ECHOE, ECHOE); EnumMap<ControlChar, Integer> cc = attr.getControlChars(); cc.put(ControlChar.VEOF, (int) c_cc[VEOF]); cc.put(ControlChar.VEOL, (int) c_cc[VEOL]);
switch (e.getKey()) { case VINTR: attr.setControlChar(Attributes.ControlChar.VINTR, e.getValue()); break; case VQUIT: attr.setControlChar(Attributes.ControlChar.VQUIT, e.getValue()); break; case VERASE: attr.setControlChar(Attributes.ControlChar.VERASE, e.getValue()); break; case VKILL: attr.setControlChar(Attributes.ControlChar.VKILL, e.getValue()); break; case VEOF: attr.setControlChar(Attributes.ControlChar.VEOF, e.getValue()); break; case VEOL: attr.setControlChar(Attributes.ControlChar.VEOL, e.getValue()); break; case VEOL2: attr.setControlChar(Attributes.ControlChar.VEOL2, e.getValue()); break; case VSTART: attr.setControlChar(Attributes.ControlChar.VSTART, e.getValue()); break; case VSTOP: attr.setControlChar(Attributes.ControlChar.VSTOP, e.getValue()); break; case VSUSP:
public void copy(Attributes attributes) { setControlFlags(attributes.getControlFlags()); setInputFlags(attributes.getInputFlags()); setLocalFlags(attributes.getLocalFlags()); setOutputFlags(attributes.getOutputFlags()); setControlChars(attributes.getControlChars()); }
static Attributes doGetAttr(String cfg) throws IOException { Attributes attributes = new Attributes(); for (InputFlag flag : InputFlag.values()) { Boolean value = doGetFlag(cfg, flag); if (value != null) { attributes.setInputFlag(flag, value); Boolean value = doGetFlag(cfg, flag); if (value != null) { attributes.setOutputFlag(flag, value); Boolean value = doGetFlag(cfg, flag); if (value != null) { attributes.setControlFlag(flag, value); Boolean value = doGetFlag(cfg, flag); if (value != null) { attributes.setLocalFlag(flag, value); attributes.setControlChar(cchar, parseControlChar(matcher.group(1).toUpperCase()));
public void processInputChar(char c) throws IOException { if (attributes.getLocalFlag(Attributes.LocalFlag.ISIG)) { if (c == attributes.getControlChar(Attributes.ControlChar.VINTR)) { raise(Signal.INT); return; } else if (c == attributes.getControlChar(Attributes.ControlChar.VQUIT)) { raise(Signal.QUIT); return; } else if (c == attributes.getControlChar(Attributes.ControlChar.VSUSP)) { raise(Signal.TSTP); return; } else if (c == attributes.getControlChar(Attributes.ControlChar.VSTATUS)) { raise(Signal.INFO); if (attributes.getInputFlag(Attributes.InputFlag.IGNCR)) { return; if (attributes.getInputFlag(Attributes.InputFlag.ICRNL)) { c = '\n'; } else if (c == '\n' && attributes.getInputFlag(Attributes.InputFlag.INLCR)) { c = '\r';
private String display(ControlChar c) { String value; int ch = getControlChar(c); if (c == ControlChar.VMIN || c == ControlChar.VTIME) { value = Integer.toString(ch); } else if (ch < 0) { value = "<undef>"; } else if (ch < 32) { value = "^" + (char) (ch + 'A' - 1); } else if (ch == 127) { value = "^?"; } else if (ch >= 128) { value = String.format("\\u%04x", ch); } else { value = String.valueOf((char) ch); } return c.name().toLowerCase().substring(1) + "=" + value; }
private void setNonBlocking() { if (current == null || current.getControlChar(Attributes.ControlChar.VMIN) != 0 || current.getControlChar(Attributes.ControlChar.VTIME) != 1) { try { Attributes attr = getAttr(); attr.setControlChar(Attributes.ControlChar.VMIN, 0); attr.setControlChar(Attributes.ControlChar.VTIME, 1); setAttr(attr); } catch (IOException e) { throw new IOError(e); } } } }
} else { Attributes attr = new Attributes(originalAttributes); attr.setInputFlag(Attributes.InputFlag.IGNCR, true); terminal.setAttributes(attr); if (buf.length() == 0 && getLastBinding().charAt(0) == originalAttributes.getControlChar(ControlChar.VEOF)) { throw new EndOfFileException();
private static int getFlag(Attributes attributes, LocalFlag flag) { return attributes.getLocalFlag(flag) ? 1 : 0; }
this.reader = NonBlocking.nonBlocking(getName(), input, encoding()); this.writer = new PrintWriter(new OutputStreamWriter(output, encoding())); this.attributes = new Attributes(); this.attributes.setControlChar(ControlChar.VERASE, (char) 127); this.attributes.setControlChar(ControlChar.VWERASE, (char) 23); this.attributes.setControlChar(ControlChar.VKILL, (char) 21); this.attributes.setControlChar(ControlChar.VLNEXT, (char) 22); this.size = new Size(); parseInfoCmp();
private static int getFlag(Attributes attributes, OutputFlag flag) { return attributes.getOutputFlag(flag) ? 1 : 0; }
public Attributes getAttributes() { int mode = getConsoleMode(); if ((mode & ENABLE_ECHO_INPUT) != 0) { attributes.setLocalFlag(Attributes.LocalFlag.ECHO, true); } if ((mode & ENABLE_LINE_INPUT) != 0) { attributes.setLocalFlag(Attributes.LocalFlag.ICANON, true); } return new Attributes(attributes); }
attributes.setLocalFlag(Attributes.LocalFlag.ISIG, true); attributes.setControlChar(Attributes.ControlChar.VINTR, ctrl('C')); attributes.setControlChar(Attributes.ControlChar.VEOF, ctrl('D')); attributes.setControlChar(Attributes.ControlChar.VSUSP, ctrl('Z'));
private static int getFlag(Attributes attributes, InputFlag flag) { return attributes.getInputFlag(flag) ? 1 : 0; }
public boolean echo(boolean echo) { Attributes attr = getAttributes(); boolean prev = attr.getLocalFlag(LocalFlag.ECHO); if (prev != echo) { attr.setLocalFlag(LocalFlag.ECHO, echo); setAttributes(attr); } return prev; }
public Attributes getAttributes() { Attributes attr = new Attributes(); attr.copy(attributes); return attr; }
@Override public void setAttr(Attributes attr) throws IOException { current = new Attributes(attr); doSetAttr(attr); }
termAttrs.setLocalFlag(Attributes.LocalFlag.ECHO, false); term.setAttributes(termAttrs);