ADMOPSLA and ADMCHART are happier
Build and Test j3270 / Build JAR & Run Tests (push) Successful in 1m7s

This commit is contained in:
2026-08-23 01:27:45 +00:00
parent 42eef519a6
commit 0837de8db3
19 changed files with 792 additions and 114 deletions
@@ -180,6 +180,22 @@ public class TerminalPanel extends JPanel {
}
}
@Override
public void mouseMoved(MouseEvent e) {
if (client != null && client.getGocaDecoder() != null && client.getGocaDecoder().isGraphicsCursorActive() && client.getGraphicsPlane() != null) {
int ox = getRenderOffsetX();
int oy = getRenderOffsetY();
ScreenBuffer sb = client.getScreenBuffer();
int gridW = sb.getDisplayCols() * cellWidth;
int gridH = sb.getDisplayRows() * cellHeight;
int gWidth = client.getGraphicsPlane().getCanvasWidth();
int gHeight = client.getGraphicsPlane().getCanvasHeight();
int px = (gridW > 0 && gWidth > 0) ? (int) Math.round((double) (e.getX() - ox) * gWidth / gridW) : (e.getX() - ox);
int py = (gridH > 0 && gHeight > 0) ? (int) Math.round((double) (e.getY() - oy) * gHeight / gridH) : (e.getY() - oy);
client.getGocaDecoder().setGraphicCursorFromPixel(px, py);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (isDragging) {
@@ -188,8 +204,35 @@ public class TerminalPanel extends JPanel {
if (selectionStartRow == selectionEndRow && selectionStartCol == selectionEndCol) {
if (client != null && client.getConnectionState().isFullSession()) {
ScreenBuffer sb = client.getScreenBuffer();
sb.setCursorAddress(selectionStartRow * sb.getCols() + selectionStartCol);
int newAddr = selectionStartRow * sb.getCols() + selectionStartCol;
sb.setCursorAddress(newAddr);
clearSelection();
if (client.getGocaDecoder() != null && client.getGraphicsPlane() != null) {
int ox = getRenderOffsetX();
int oy = getRenderOffsetY();
int gridW = sb.getDisplayCols() * cellWidth;
int gridH = sb.getDisplayRows() * cellHeight;
int gWidth = client.getGraphicsPlane().getCanvasWidth();
int gHeight = client.getGraphicsPlane().getCanvasHeight();
int px = (gridW > 0 && gWidth > 0) ? (int) Math.round((double) (e.getX() - ox) * gWidth / gridW) : (e.getX() - ox);
int py = (gridH > 0 && gHeight > 0) ? (int) Math.round((double) (e.getY() - oy) * gHeight / gridH) : (e.getY() - oy);
client.getGocaDecoder().setGraphicCursorFromPixel(px, py);
if (client.getGocaDecoder().isGraphicsCursorActive()) {
// Light-pen / Graphic cursor touch event (matches IBM Host On-Demand PS3179G)
int button = javax.swing.SwingUtilities.isRightMouseButton(e) ? 2 : 1;
client.getInputProcessor().sendGraphicMouseAid(
org.lib3270j.protocol.DS3270Constants.AID_ENTER,
button,
e.isShiftDown(),
e.isControlDown()
);
refreshScreen();
return;
}
}
refreshScreen();
return;
}
@@ -849,6 +892,20 @@ public class TerminalPanel extends JPanel {
int cols = sb.getDisplayCols();
boolean isColorModel = client.getConfig().getModel().isColor();
// Draw Vector Graphics Plane under text if present
if (client.getGraphicsPlane() != null && client.getGraphicsPlane().hasContent()) {
int gridW = cols * cellWidth;
int gridH = rows * cellHeight;
int gWidth = client.getGraphicsPlane().getCanvasWidth();
int gHeight = client.getGraphicsPlane().getCanvasHeight();
int[] rgb = client.getGraphicsPlane().getRgbBuffer();
if (rgb != null && gWidth > 0 && gHeight > 0) {
java.awt.image.BufferedImage img = new java.awt.image.BufferedImage(gWidth, gHeight, java.awt.image.BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, gWidth, gHeight, rgb, 0, gWidth);
g2.drawImage(img, ox, oy, gridW, gridH, null);
}
}
// Track current field attribute for monochrome color decisions
byte currentFA = 0;
ExtendedAttribute currentFieldEa = null;
@@ -940,7 +997,8 @@ public class TerminalPanel extends JPanel {
if (cs >= 0x40 && client.getProgramSymbolManager() != null) {
org.lib3270j.graphics.ProgramSymbolSet.SymbolSlot slot = client.getProgramSymbolManager().getSymbol(cs, ea.ec & 0xFF);
if (slot != null) {
java.awt.image.BufferedImage img = slot.getScaledImage(cellWidth, cellHeight, fgColor.getRGB(), bgColor.getRGB());
int symBg = (!bgColor.equals(this.bgColor) || reverse) ? bgColor.getRGB() : 0;
java.awt.image.BufferedImage img = slot.getScaledImage(cellWidth, cellHeight, fgColor.getRGB(), symBg);
if (img != null) {
g2.drawImage(img, x, y, null);
drawnAsPs = true;
@@ -977,20 +1035,22 @@ public class TerminalPanel extends JPanel {
}
}
// Draw Vector Graphics Plane overlay if present
if (client.getGraphicsPlane() != null && client.getGraphicsPlane().hasContent()) {
int gridW = cols * cellWidth;
int gridH = rows * cellHeight;
client.getGraphicsPlane().resize(gridW, gridH);
int[] rgb = client.getGraphicsPlane().getRgbBuffer();
if (rgb != null) {
java.awt.image.BufferedImage img = new java.awt.image.BufferedImage(gridW, gridH, java.awt.image.BufferedImage.TYPE_INT_ARGB);
img.setRGB(0, 0, gridW, gridH, rgb, 0, gridW);
g2.drawImage(img, ox, oy, gridW, gridH, null);
}
// Draw Graphic Cursor (Light-Pen / interactive graphics pointer) if active
if (client.getGocaDecoder() != null && client.getGocaDecoder().isGraphicsCursorActive() && client.getGraphicsPlane() != null) {
int gocaX = client.getGocaDecoder().getGraphicCursorX();
int gocaY = client.getGocaDecoder().getGraphicCursorY();
int px = ox + client.getGraphicsPlane().mapX(gocaX);
int py = oy + client.getGraphicsPlane().mapY(gocaY);
g2.setColor(Color.WHITE);
g2.setXORMode(Color.BLACK);
// Draw a crosshair cursor for the light-pen / graphic cursor
g2.drawLine(px - 6, py, px + 6, py);
g2.drawLine(px, py - 6, px, py + 6);
g2.setPaintMode();
}
// Draw cursor
// Draw 3270 text cursor
if (cursorVisible && client.getConnectionState().isFullSession()) {
int curAddr = sb.getDisplayCursorAddress();
int curRow = curAddr / cols;