expose cursor from render state
This commit is contained in:
27
src/main/java/dev/jlibghostty/RenderCursorStyle.java
Normal file
27
src/main/java/dev/jlibghostty/RenderCursorStyle.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package dev.jlibghostty;
|
||||
|
||||
public enum RenderCursorStyle {
|
||||
BAR(0),
|
||||
BLOCK(1),
|
||||
UNDERLINE(2),
|
||||
BLOCK_HOLLOW(3);
|
||||
|
||||
private final int nativeValue;
|
||||
|
||||
RenderCursorStyle(int nativeValue) {
|
||||
this.nativeValue = nativeValue;
|
||||
}
|
||||
|
||||
public int nativeValue() {
|
||||
return nativeValue;
|
||||
}
|
||||
|
||||
static RenderCursorStyle fromNative(int value) {
|
||||
for (RenderCursorStyle style : values()) {
|
||||
if (style.nativeValue == value) {
|
||||
return style;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown render cursor style: " + value);
|
||||
}
|
||||
}
|
||||
@@ -24,10 +24,30 @@ public final class RenderState implements AutoCloseable {
|
||||
|
||||
public RenderStateSnapshot snapshot() {
|
||||
ensureOpen();
|
||||
boolean cursorViewportHasValue = library.renderStateGetBoolean(
|
||||
handle,
|
||||
GhosttyLibrary.RENDER_STATE_DATA_CURSOR_VIEWPORT_HAS_VALUE
|
||||
);
|
||||
|
||||
return new RenderStateSnapshot(
|
||||
library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_COLS),
|
||||
library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_ROWS),
|
||||
library.renderStateGetI32(handle, GhosttyLibrary.RENDER_STATE_DATA_DIRTY),
|
||||
RenderCursorStyle.fromNative(
|
||||
library.renderStateGetI32(handle, GhosttyLibrary.RENDER_STATE_DATA_CURSOR_VISUAL_STYLE)
|
||||
),
|
||||
library.renderStateGetBoolean(handle, GhosttyLibrary.RENDER_STATE_DATA_CURSOR_VISIBLE),
|
||||
library.renderStateGetBoolean(handle, GhosttyLibrary.RENDER_STATE_DATA_CURSOR_BLINKING),
|
||||
library.renderStateGetBoolean(handle, GhosttyLibrary.RENDER_STATE_DATA_CURSOR_PASSWORD_INPUT),
|
||||
cursorViewportHasValue,
|
||||
cursorViewportHasValue
|
||||
? library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_CURSOR_VIEWPORT_X)
|
||||
: -1,
|
||||
cursorViewportHasValue
|
||||
? library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_CURSOR_VIEWPORT_Y)
|
||||
: -1,
|
||||
cursorViewportHasValue
|
||||
&& library.renderStateGetBoolean(handle, GhosttyLibrary.RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL),
|
||||
rows()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,20 @@ package dev.jlibghostty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public record RenderStateSnapshot(int columns, int rows, int dirty, List<RenderRow> renderRows) {
|
||||
public record RenderStateSnapshot(
|
||||
int columns,
|
||||
int rows,
|
||||
int dirty,
|
||||
RenderCursorStyle cursorStyle,
|
||||
boolean cursorVisible,
|
||||
boolean cursorBlinking,
|
||||
boolean cursorPasswordInput,
|
||||
boolean cursorViewportHasValue,
|
||||
int cursorViewportX,
|
||||
int cursorViewportY,
|
||||
boolean cursorViewportWideTail,
|
||||
List<RenderRow> renderRows
|
||||
) {
|
||||
public RenderStateSnapshot {
|
||||
renderRows = List.copyOf(renderRows);
|
||||
}
|
||||
|
||||
@@ -70,6 +70,14 @@ public final class GhosttyLibrary {
|
||||
public static final int RENDER_STATE_DATA_ROWS = 2;
|
||||
public static final int RENDER_STATE_DATA_DIRTY = 3;
|
||||
public static final int RENDER_STATE_DATA_ROW_ITERATOR = 4;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_VISUAL_STYLE = 10;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_VISIBLE = 11;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_BLINKING = 12;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_PASSWORD_INPUT = 13;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_VIEWPORT_HAS_VALUE = 14;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_VIEWPORT_X = 15;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_VIEWPORT_Y = 16;
|
||||
public static final int RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL = 17;
|
||||
|
||||
public static final int RENDER_STATE_ROW_DATA_DIRTY = 1;
|
||||
public static final int RENDER_STATE_ROW_DATA_CELLS = 3;
|
||||
@@ -627,6 +635,17 @@ public final class GhosttyLibrary {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean renderStateGetBoolean(MemorySegment state, int key) {
|
||||
try (Arena arena = Arena.ofConfined()) {
|
||||
MemorySegment out = arena.allocate(C_BOOL);
|
||||
int result = (int) renderStateGet.invoke(state, key, out);
|
||||
checkResult("ghostty_render_state_get", result);
|
||||
return out.get(C_BOOL, 0);
|
||||
} catch (Throwable t) {
|
||||
return rethrow(t);
|
||||
}
|
||||
}
|
||||
|
||||
public List<RenderRow> renderStateRows(MemorySegment state) {
|
||||
MemorySegment iterator = renderStateRowIteratorNew();
|
||||
try {
|
||||
|
||||
@@ -43,6 +43,14 @@ public final class GhosttySmokeTest {
|
||||
if (!renderedHello) {
|
||||
throw new AssertionError("render state should contain written text");
|
||||
}
|
||||
if (renderSnapshot.cursorViewportHasValue()) {
|
||||
if (renderSnapshot.cursorViewportX() < 0 || renderSnapshot.cursorViewportX() >= renderSnapshot.columns()
|
||||
|| renderSnapshot.cursorViewportY() < 0 || renderSnapshot.cursorViewportY() >= renderSnapshot.rows()) {
|
||||
throw new AssertionError("cursor viewport position out of bounds: " + renderSnapshot);
|
||||
}
|
||||
} else if (renderSnapshot.cursorViewportX() != -1 || renderSnapshot.cursorViewportY() != -1) {
|
||||
throw new AssertionError("cursor viewport position should be -1 when absent: " + renderSnapshot);
|
||||
}
|
||||
renderSnapshot.renderRows().stream()
|
||||
.flatMap(row -> row.cells().stream())
|
||||
.forEach(cell -> {
|
||||
|
||||
Reference in New Issue
Block a user