Skip to content

Commit

Permalink
Add TerminalExt interface
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet committed Oct 9, 2023
1 parent d0e1ce1 commit 8685b2a
Show file tree
Hide file tree
Showing 37 changed files with 659 additions and 259 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ public void testConEmuLineReaderClearScreen() throws IOException {
StringWriter sw = new StringWriter();
AbstractWindowsTerminal<?> terminal =
new AbstractWindowsTerminal<Object>(
null,
null,
new BufferedWriter(sw),
"name",
TYPE_WINDOWS_CONEMU,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ private void process(TestTerminal terminal, int c) {
private static class TestTerminal extends AbstractWindowsTerminal<Object> {
public TestTerminal(StringWriter sw) throws IOException {
super(
null,
null,
new AnsiWriter(new BufferedWriter(sw)),
"name",
AbstractWindowsTerminal.TYPE_DUMB,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.jline.terminal.Attributes;
import org.jline.terminal.Size;
import org.jline.terminal.spi.Pty;
import org.jline.terminal.spi.TerminalProvider;

@SuppressWarnings("preview")
class CLibrary {
Expand Down Expand Up @@ -482,7 +483,7 @@ static String ttyName(int fd) {
}
}

static Pty openpty(Attributes attr, Size size) {
static Pty openpty(TerminalProvider provider, Attributes attr, Size size) {
try {
java.lang.foreign.MemorySegment buf =
java.lang.foreign.Arena.ofAuto().allocate(64);
Expand All @@ -504,7 +505,8 @@ static Pty openpty(Attributes attr, Size size) {
len++;
}
String device = new String(str, 0, len);
return new FfmNativePty(master.get(ValueLayout.JAVA_INT, 0), slave.get(ValueLayout.JAVA_INT, 0), device);
return new FfmNativePty(
provider, null, master.get(ValueLayout.JAVA_INT, 0), slave.get(ValueLayout.JAVA_INT, 0), device);
} catch (Throwable e) {
throw new RuntimeException("Unable to call openpty()", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.jline.terminal.Attributes;
import org.jline.terminal.Size;
import org.jline.terminal.impl.AbstractPty;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;

class FfmNativePty extends AbstractPty {
Expand All @@ -29,18 +30,30 @@ class FfmNativePty extends AbstractPty {
private final FileDescriptor slaveFD;
private final FileDescriptor slaveOutFD;

public FfmNativePty(int master, int slave, String name) {
this(master, newDescriptor(master), slave, newDescriptor(slave), slave, newDescriptor(slave), name);
public FfmNativePty(TerminalProvider provider, SystemStream systemStream, int master, int slave, String name) {
this(
provider,
systemStream,
master,
newDescriptor(master),
slave,
newDescriptor(slave),
slave,
newDescriptor(slave),
name);
}

public FfmNativePty(
TerminalProvider provider,
SystemStream systemStream,
int master,
FileDescriptor masterFD,
int slave,
FileDescriptor slaveFD,
int slaveOut,
FileDescriptor slaveOutFD,
String name) {
super(provider, systemStream);
this.master = master;
this.slave = slave;
this.slaveOut = slaveOut;
Expand Down Expand Up @@ -129,7 +142,7 @@ public String toString() {
return "FfmNativePty[" + getName() + "]";
}

public static boolean isPosixSystemStream(TerminalProvider.Stream stream) {
public static boolean isPosixSystemStream(SystemStream stream) {
switch (stream) {
case Input:
return CLibrary.isTty(0);
Expand All @@ -142,7 +155,7 @@ public static boolean isPosixSystemStream(TerminalProvider.Stream stream) {
}
}

public static String posixSystemStreamName(TerminalProvider.Stream stream) {
public static String posixSystemStreamName(SystemStream stream) {
switch (stream) {
case Input:
return CLibrary.ttyName(0);
Expand All @@ -154,4 +167,9 @@ public static String posixSystemStreamName(TerminalProvider.Stream stream) {
throw new IllegalArgumentException();
}
}

public static int systemStreamWidth(SystemStream systemStream) {
int fd = systemStream == SystemStream.Output ? 1 : 2;
return CLibrary.getTerminalSize(fd).getColumns();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.jline.terminal.impl.PosixPtyTerminal;
import org.jline.terminal.impl.PosixSysTerminal;
import org.jline.terminal.spi.Pty;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;
import org.jline.utils.OSUtils;

Expand All @@ -46,19 +47,21 @@ public Terminal sysTerminal(
boolean nativeSignals,
Terminal.SignalHandler signalHandler,
boolean paused,
Stream consoleStream)
SystemStream systemStream)
throws IOException {
if (OSUtils.IS_WINDOWS) {
return NativeWinSysTerminal.createTerminal(
name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused, consoleStream);
this, systemStream, name, type, ansiPassThrough, encoding, nativeSignals, signalHandler, paused);
} else {
Pty pty = new FfmNativePty(
this,
systemStream,
-1,
null,
0,
FileDescriptor.in,
consoleStream == Stream.Output ? 1 : 2,
consoleStream == Stream.Output ? FileDescriptor.out : FileDescriptor.err,
systemStream == SystemStream.Output ? 1 : 2,
systemStream == SystemStream.Output ? FileDescriptor.out : FileDescriptor.err,
CLibrary.ttyName(0));
return new PosixSysTerminal(name, type, pty, encoding, nativeSignals, signalHandler);
}
Expand All @@ -76,29 +79,34 @@ public Terminal newTerminal(
Attributes attributes,
Size size)
throws IOException {
Pty pty = CLibrary.openpty(attributes, size);
Pty pty = CLibrary.openpty(this, attributes, size);
return new PosixPtyTerminal(name, type, pty, in, out, encoding, signalHandler, paused);
}

@Override
public boolean isSystemStream(Stream stream) {
public boolean isSystemStream(SystemStream stream) {
if (OSUtils.IS_WINDOWS) {
return isWindowsSystemStream(stream);
} else {
return isPosixSystemStream(stream);
}
}

public boolean isWindowsSystemStream(Stream stream) {
public boolean isWindowsSystemStream(SystemStream stream) {
return NativeWinSysTerminal.isWindowsSystemStream(stream);
}

public boolean isPosixSystemStream(Stream stream) {
public boolean isPosixSystemStream(SystemStream stream) {
return FfmNativePty.isPosixSystemStream(stream);
}

@Override
public String systemStreamName(Stream stream) {
public String systemStreamName(SystemStream stream) {
return FfmNativePty.posixSystemStreamName(stream);
}

@Override
public int systemStreamWidth(SystemStream stream) {
return FfmNativePty.systemStreamWidth(stream);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.jline.terminal.Cursor;
import org.jline.terminal.Size;
import org.jline.terminal.impl.AbstractWindowsTerminal;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;
import org.jline.utils.OSUtils;

Expand All @@ -41,14 +42,15 @@
public class NativeWinSysTerminal extends AbstractWindowsTerminal<java.lang.foreign.MemorySegment> {

public static NativeWinSysTerminal createTerminal(
TerminalProvider provider,
SystemStream systemStream,
String name,
String type,
boolean ansiPassThrough,
Charset encoding,
boolean nativeSignals,
SignalHandler signalHandler,
boolean paused,
TerminalProvider.Stream consoleStream)
boolean paused)
throws IOException {
try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) {
// Get input console mode
Expand All @@ -59,15 +61,15 @@ public static NativeWinSysTerminal createTerminal(
}
// Get output console and mode
java.lang.foreign.MemorySegment console;
switch (consoleStream) {
switch (systemStream) {
case Output:
console = GetStdHandle(STD_OUTPUT_HANDLE);
break;
case Error:
console = GetStdHandle(STD_ERROR_HANDLE);
break;
default:
throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream);
throw new IllegalArgumentException("Unsupport stream for console: " + systemStream);
}
java.lang.foreign.MemorySegment outMode = allocateInt(arena);
if (GetConsoleMode(console, outMode) == 0) {
Expand All @@ -93,6 +95,8 @@ public static NativeWinSysTerminal createTerminal(
}
// Create terminal
NativeWinSysTerminal terminal = new NativeWinSysTerminal(
provider,
systemStream,
writer,
name,
type,
Expand All @@ -115,7 +119,7 @@ private static boolean enableVtp(java.lang.foreign.MemorySegment console, int m)
return SetConsoleMode(console, m | AbstractWindowsTerminal.ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0;
}

public static boolean isWindowsSystemStream(TerminalProvider.Stream stream) {
public static boolean isWindowsSystemStream(SystemStream stream) {
try (java.lang.foreign.Arena arena = java.lang.foreign.Arena.ofConfined()) {
java.lang.foreign.MemorySegment console;
java.lang.foreign.MemorySegment mode = allocateInt(arena);
Expand All @@ -141,6 +145,8 @@ private static java.lang.foreign.MemorySegment allocateInt(java.lang.foreign.Are
}

NativeWinSysTerminal(
TerminalProvider provider,
SystemStream systemStream,
Writer writer,
String name,
String type,
Expand All @@ -153,6 +159,8 @@ private static java.lang.foreign.MemorySegment allocateInt(java.lang.foreign.Are
int outConsoleMode)
throws IOException {
super(
provider,
systemStream,
writer,
name,
type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
import java.io.OutputStream;

import org.fusesource.jansi.internal.CLibrary;
import org.fusesource.jansi.internal.Kernel32;
import org.jline.terminal.Attributes;
import org.jline.terminal.Size;
import org.jline.terminal.impl.AbstractPty;
import org.jline.terminal.impl.jansi.win.JansiWinSysTerminal;
import org.jline.terminal.spi.Pty;
import org.jline.terminal.spi.SystemStream;
import org.jline.terminal.spi.TerminalProvider;
import org.jline.utils.OSUtils;

Expand All @@ -38,18 +41,28 @@ public abstract class JansiNativePty extends AbstractPty implements Pty {
private final FileDescriptor slaveFD;
private final FileDescriptor slaveOutFD;

public JansiNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) {
this(master, masterFD, slave, slaveFD, slave, slaveFD, name);
public JansiNativePty(
TerminalProvider provider,
SystemStream systemStream,
int master,
FileDescriptor masterFD,
int slave,
FileDescriptor slaveFD,
String name) {
this(provider, systemStream, master, masterFD, slave, slaveFD, slave, slaveFD, name);
}

public JansiNativePty(
TerminalProvider provider,
SystemStream systemStream,
int master,
FileDescriptor masterFD,
int slave,
FileDescriptor slaveFD,
int slaveOut,
FileDescriptor slaveOutFD,
String name) {
super(provider, systemStream);
this.master = master;
this.slave = slave;
this.slaveOut = slaveOut;
Expand Down Expand Up @@ -174,29 +187,44 @@ public String toString() {
return "JansiNativePty[" + getName() + "]";
}

public static boolean isPosixSystemStream(TerminalProvider.Stream stream) {
switch (stream) {
case Input:
return CLibrary.isatty(0) == 1;
case Output:
return CLibrary.isatty(1) == 1;
case Error:
return CLibrary.isatty(2) == 1;
default:
return false;
public static boolean isPosixSystemStream(SystemStream stream) {
return CLibrary.isatty(fd(stream)) == 1;
}

public static String posixSystemStreamName(SystemStream systemStream) {
return CLibrary.ttyname(fd(systemStream));
}

public static int systemStreamWidth(SystemStream systemStream) {
try {
if (OSUtils.IS_WINDOWS) {
Kernel32.CONSOLE_SCREEN_BUFFER_INFO info = new Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
long outConsole = JansiWinSysTerminal.getConsole(systemStream);
Kernel32.GetConsoleScreenBufferInfo(outConsole, info);
return info.windowWidth();
} else {
CLibrary.WinSize sz = new CLibrary.WinSize();
int res = CLibrary.ioctl(fd(systemStream), CLibrary.TIOCGWINSZ, sz);
if (res != 0) {
throw new IOException("Error calling ioctl(TIOCGWINSZ): return code is " + res);
}
return sz.ws_col;
}
} catch (Throwable t) {
return -1;
}
}

public static String posixSystemStreamName(TerminalProvider.Stream stream) {
switch (stream) {
private static int fd(SystemStream systemStream) {
switch (systemStream) {
case Input:
return CLibrary.ttyname(0);
return 0;
case Output:
return CLibrary.ttyname(1);
return 1;
case Error:
return CLibrary.ttyname(2);
return 2;
default:
return null;
return -1;
}
}
}

0 comments on commit 8685b2a

Please sign in to comment.