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() {
|
public RenderStateSnapshot snapshot() {
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
|
boolean cursorViewportHasValue = library.renderStateGetBoolean(
|
||||||
|
handle,
|
||||||
|
GhosttyLibrary.RENDER_STATE_DATA_CURSOR_VIEWPORT_HAS_VALUE
|
||||||
|
);
|
||||||
|
|
||||||
return new RenderStateSnapshot(
|
return new RenderStateSnapshot(
|
||||||
library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_COLS),
|
library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_COLS),
|
||||||
library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_ROWS),
|
library.renderStateGetU16(handle, GhosttyLibrary.RENDER_STATE_DATA_ROWS),
|
||||||
library.renderStateGetI32(handle, GhosttyLibrary.RENDER_STATE_DATA_DIRTY),
|
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()
|
rows()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,20 @@ package dev.jlibghostty;
|
|||||||
|
|
||||||
import java.util.List;
|
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 {
|
public RenderStateSnapshot {
|
||||||
renderRows = List.copyOf(renderRows);
|
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_ROWS = 2;
|
||||||
public static final int RENDER_STATE_DATA_DIRTY = 3;
|
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_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_DIRTY = 1;
|
||||||
public static final int RENDER_STATE_ROW_DATA_CELLS = 3;
|
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) {
|
public List<RenderRow> renderStateRows(MemorySegment state) {
|
||||||
MemorySegment iterator = renderStateRowIteratorNew();
|
MemorySegment iterator = renderStateRowIteratorNew();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -43,6 +43,14 @@ public final class GhosttySmokeTest {
|
|||||||
if (!renderedHello) {
|
if (!renderedHello) {
|
||||||
throw new AssertionError("render state should contain written text");
|
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()
|
renderSnapshot.renderRows().stream()
|
||||||
.flatMap(row -> row.cells().stream())
|
.flatMap(row -> row.cells().stream())
|
||||||
.forEach(cell -> {
|
.forEach(cell -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user