Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/main/java/org/fusesource/jansi/AnsiConsole.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Locale;

import org.fusesource.jansi.internal.OSInfo;
import org.fusesource.jansi.io.AnsiOutputStream;
import org.fusesource.jansi.io.AnsiProcessor;
import org.fusesource.jansi.io.FastBufferedOutputStream;
Expand Down Expand Up @@ -194,8 +194,7 @@ public static int getTerminalWidth() {
return w;
}

static final boolean IS_WINDOWS =
System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("win");
static final boolean IS_WINDOWS = OSInfo.isWindows();

static final boolean IS_CYGWIN =
IS_WINDOWS && System.getenv("PWD") != null && System.getenv("PWD").startsWith("/");
Expand Down
94 changes: 14 additions & 80 deletions src/main/java/org/fusesource/jansi/ffm/AnsiConsoleSupportFfm.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,93 +18,28 @@
import java.io.IOException;
import java.io.OutputStream;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.GroupLayout;
import java.lang.foreign.Linker;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.VarHandle;

import org.fusesource.jansi.AnsiConsoleSupport;
import org.fusesource.jansi.internal.OSInfo;
import org.fusesource.jansi.io.AnsiProcessor;

import static org.fusesource.jansi.ffm.Kernel32.*;

public class AnsiConsoleSupportFfm implements AnsiConsoleSupport {
static GroupLayout wsLayout;
static MethodHandle ioctl;
static VarHandle ws_col;
static MethodHandle isatty;

static {
wsLayout = MemoryLayout.structLayout(
ValueLayout.JAVA_SHORT.withName("ws_row"),
ValueLayout.JAVA_SHORT.withName("ws_col"),
ValueLayout.JAVA_SHORT,
ValueLayout.JAVA_SHORT);
ws_col = wsLayout.varHandle(MemoryLayout.PathElement.groupElement("ws_col"));
Linker linker = Linker.nativeLinker();
ioctl = linker.downcallHandle(
linker.defaultLookup().find("ioctl").get(),
FunctionDescriptor.of(
ValueLayout.JAVA_INT, ValueLayout.JAVA_INT, ValueLayout.JAVA_LONG, ValueLayout.ADDRESS),
Linker.Option.firstVariadicArg(2));
isatty = linker.downcallHandle(
linker.defaultLookup().find("isatty").get(),
FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.JAVA_INT));
}

@Override
public String getProviderName() {
return "ffm";
}

@Override
public CLibrary getCLibrary() {
return new CLibrary() {
static final int TIOCGWINSZ;

static {
String osName = System.getProperty("os.name");
if (osName.startsWith("Linux")) {
String arch = System.getProperty("os.arch");
boolean isMipsPpcOrSparc =
arch.startsWith("mips") || arch.startsWith("ppc") || arch.startsWith("sparc");
TIOCGWINSZ = isMipsPpcOrSparc ? 0x40087468 : 0x00005413;
} else if (osName.startsWith("Solaris") || osName.startsWith("SunOS")) {
int _TIOC = ('T' << 8);
TIOCGWINSZ = (_TIOC | 104);
} else if (osName.startsWith("Mac") || osName.startsWith("Darwin")) {
TIOCGWINSZ = 0x40087468;
} else if (osName.startsWith("FreeBSD")) {
TIOCGWINSZ = 0x40087468;
} else {
throw new UnsupportedOperationException();
}
}

@Override
public short getTerminalWidth(int fd) {
MemorySegment segment = Arena.ofAuto().allocate(wsLayout);
try {
int res = (int) ioctl.invoke(fd, (long) TIOCGWINSZ, segment);
return (short) ws_col.get(segment);
} catch (Throwable e) {
throw new RuntimeException("Unable to ioctl(TIOCGWINSZ)", e);
}
}

@Override
public int isTty(int fd) {
try {
return (int) isatty.invoke(fd);
} catch (Throwable e) {
throw new RuntimeException("Unable to call isatty", e);
}
}
};
if (OSInfo.isWindows()) {
return new WindowsCLibrary();
} else {
return new PosixCLibrary();
}
}

@Override
Expand All @@ -118,9 +53,11 @@ public int isTty(long console) {

@Override
public int getTerminalWidth(long console) {
CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO();
GetConsoleScreenBufferInfo(MemorySegment.ofAddress(console), info);
return info.windowWidth();
try (Arena arena = Arena.ofConfined()) {
CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(arena);
GetConsoleScreenBufferInfo(MemorySegment.ofAddress(console), info);
return info.windowWidth();
}
}

@Override
Expand All @@ -131,8 +68,8 @@ public long getStdHandle(boolean stdout) {

@Override
public int getConsoleMode(long console, int[] mode) {
try (Arena session = Arena.ofConfined()) {
MemorySegment written = session.allocate(ValueLayout.JAVA_INT);
try (Arena arena = Arena.ofConfined()) {
MemorySegment written = arena.allocate(ValueLayout.JAVA_INT);
int res = GetConsoleMode(MemorySegment.ofAddress(console), written);
mode[0] = written.getAtIndex(ValueLayout.JAVA_INT, 0);
return res;
Expand All @@ -151,10 +88,7 @@ public int getLastError() {

@Override
public String getErrorMessage(int errorCode) {
int bufferSize = 160;
MemorySegment data = Arena.ofAuto().allocate(bufferSize);
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, null, errorCode, 0, data, bufferSize, null);
return data.getUtf8String(0).trim();
return org.fusesource.jansi.ffm.Kernel32.getErrorMessage(errorCode);
}

@Override
Expand Down
Loading