This commit is contained in:
@@ -86,6 +86,10 @@ public class StatusBar extends JPanel {
|
||||
public void setClient(Telnet3270Client client, TerminalPanel terminalPanel) {
|
||||
this.client = client;
|
||||
this.terminalPanel = terminalPanel;
|
||||
if (terminalPanel != null) {
|
||||
terminalPanel.setOnLightPenToggle(this::updateStatus);
|
||||
}
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
public void updateStatus() {
|
||||
|
||||
@@ -159,11 +159,20 @@ public class TerminalPanel extends JPanel {
|
||||
col = Math.max(0, Math.min(col, displayCols - 1));
|
||||
row = Math.max(0, Math.min(row, displayRows - 1));
|
||||
|
||||
// Start selection
|
||||
selectionStartRow = row;
|
||||
selectionStartCol = col;
|
||||
selectionEndRow = row;
|
||||
selectionEndCol = col;
|
||||
// IMPORTANT ARCHITECTURE NOTE:
|
||||
// 1. In GDDM Graphic Cursor Mode (3179G / GOCA), mouse events represent graphic light-pen touches.
|
||||
// Text drag-selection is explicitly suppressed so blue selection boxes do not artifact over graphics.
|
||||
// 2. In Text Light Pen mode (Alt+L on 3270 formatted screens), clicks toggle selectable fields.
|
||||
// 3. In standard alphanumeric mode, click-drag selects text for copy-paste.
|
||||
boolean isGraphic = client.getGocaDecoder() != null && client.getGocaDecoder().isGraphicsCursorActive();
|
||||
if (isGraphic || lightPenMode) {
|
||||
clearSelection();
|
||||
} else {
|
||||
selectionStartRow = row;
|
||||
selectionStartCol = col;
|
||||
selectionEndRow = row;
|
||||
selectionEndCol = col;
|
||||
}
|
||||
isDragging = true;
|
||||
repaint();
|
||||
}
|
||||
@@ -172,16 +181,29 @@ public class TerminalPanel extends JPanel {
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent e) {
|
||||
if (isDragging && client != null && client.getConnectionState().isFullSession()) {
|
||||
ScreenBuffer sb = client.getScreenBuffer();
|
||||
int ox = getRenderOffsetX();
|
||||
int oy = getRenderOffsetY();
|
||||
int col = (e.getX() - ox) / cellWidth;
|
||||
int row = (e.getY() - oy) / cellHeight;
|
||||
col = Math.max(0, Math.min(col, sb.getDisplayCols() - 1));
|
||||
row = Math.max(0, Math.min(row, sb.getDisplayRows() - 1));
|
||||
ScreenBuffer sb = client.getScreenBuffer();
|
||||
boolean isGraphic = client.getGocaDecoder() != null && client.getGocaDecoder().isGraphicsCursorActive();
|
||||
if (isGraphic && client.getGraphicsPlane() != null) {
|
||||
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);
|
||||
px = Math.max(0, Math.min(px, gWidth - 1));
|
||||
py = Math.max(0, Math.min(py, gHeight - 1));
|
||||
client.getGocaDecoder().setGraphicCursorFromPixel(px, py);
|
||||
} else if (!lightPenMode) {
|
||||
int col = (e.getX() - ox) / cellWidth;
|
||||
int row = (e.getY() - oy) / cellHeight;
|
||||
col = Math.max(0, Math.min(col, sb.getDisplayCols() - 1));
|
||||
row = Math.max(0, Math.min(row, sb.getDisplayRows() - 1));
|
||||
|
||||
selectionEndRow = row;
|
||||
selectionEndCol = col;
|
||||
selectionEndRow = row;
|
||||
selectionEndCol = col;
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
@@ -198,6 +220,8 @@ public class TerminalPanel extends JPanel {
|
||||
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);
|
||||
px = Math.max(0, Math.min(px, gWidth - 1));
|
||||
py = Math.max(0, Math.min(py, gHeight - 1));
|
||||
client.getGocaDecoder().setGraphicCursorFromPixel(px, py);
|
||||
}
|
||||
}
|
||||
@@ -206,51 +230,63 @@ public class TerminalPanel extends JPanel {
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (isDragging) {
|
||||
isDragging = false;
|
||||
// If start == end, treat as a click (position cursor, clear selection)
|
||||
if (selectionStartRow == selectionEndRow && selectionStartCol == selectionEndCol) {
|
||||
if (client != null && client.getConnectionState().isFullSession()) {
|
||||
ScreenBuffer sb = client.getScreenBuffer();
|
||||
int displayCols = sb.getDisplayCols();
|
||||
int newAddr = selectionStartRow * displayCols + selectionStartCol;
|
||||
sb.setCursorAddress(newAddr);
|
||||
if (client != null && client.getConnectionState().isFullSession()) {
|
||||
ScreenBuffer sb = client.getScreenBuffer();
|
||||
int ox = getRenderOffsetX();
|
||||
int oy = getRenderOffsetY();
|
||||
int displayCols = sb.getDisplayCols();
|
||||
int displayRows = sb.getDisplayRows();
|
||||
int col = (e.getX() - ox) / cellWidth;
|
||||
int row = (e.getY() - oy) / cellHeight;
|
||||
col = Math.max(0, Math.min(col, displayCols - 1));
|
||||
row = Math.max(0, Math.min(row, displayRows - 1));
|
||||
int clickAddr = row * displayCols + col;
|
||||
|
||||
boolean isGraphic = client.getGocaDecoder() != null && client.getGocaDecoder().isGraphicsCursorActive() && client.getGraphicsPlane() != null;
|
||||
|
||||
if (isGraphic) {
|
||||
clearSelection();
|
||||
if (lightPenMode) {
|
||||
System.out.println("LP click: row=" + selectionStartRow + " col=" + selectionStartCol
|
||||
+ " addr=" + newAddr + " mouseY=" + e.getY() + " oy=" + getRenderOffsetY()
|
||||
+ " cellH=" + cellHeight);
|
||||
boolean result = client.getInputProcessor().lightPenSelect(newAddr);
|
||||
System.out.println("LP lightPenSelect result: " + result);
|
||||
if (result) {
|
||||
refreshScreen();
|
||||
return;
|
||||
}
|
||||
int gridW = displayCols * cellWidth;
|
||||
int gridH = displayRows * 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);
|
||||
px = Math.max(0, Math.min(px, gWidth - 1));
|
||||
py = Math.max(0, Math.min(py, gHeight - 1));
|
||||
client.getGocaDecoder().setGraphicCursorFromPixel(px, py);
|
||||
|
||||
int gx = client.getGocaDecoder().getGraphicCursorX();
|
||||
int gy = client.getGocaDecoder().getGraphicCursorY();
|
||||
int button = javax.swing.SwingUtilities.isRightMouseButton(e) ? 2 : 1;
|
||||
System.err.println(String.format(
|
||||
"TerminalPanel.mouseReleased: mouse=(%d, %d) offset=(%d, %d) grid=(%dx%d) px=(%d, %d) goca=(%d, %d) btn=%d",
|
||||
e.getX(), e.getY(), ox, oy, gridW, gridH, px, py, gx, gy, button
|
||||
));
|
||||
|
||||
client.getInputProcessor().sendGraphicMouseAid(
|
||||
org.lib3270j.protocol.DS3270Constants.AID_ENTER,
|
||||
button,
|
||||
e.isShiftDown(),
|
||||
e.isControlDown()
|
||||
);
|
||||
refreshScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
if (lightPenMode) {
|
||||
clearSelection();
|
||||
sb.setCursorAddress(clickAddr);
|
||||
boolean result = client.getInputProcessor().lightPenSelect(clickAddr);
|
||||
if (result) {
|
||||
refreshScreen();
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (selectionStartRow == selectionEndRow && selectionStartCol == selectionEndCol) {
|
||||
sb.setCursorAddress(clickAddr);
|
||||
clearSelection();
|
||||
refreshScreen();
|
||||
return;
|
||||
}
|
||||
@@ -1140,9 +1176,18 @@ public class TerminalPanel extends JPanel {
|
||||
if (blinkTimer != null)
|
||||
blinkTimer.stop();
|
||||
}
|
||||
private Runnable onLightPenToggle;
|
||||
|
||||
public void setOnLightPenToggle(Runnable callback) {
|
||||
this.onLightPenToggle = callback;
|
||||
}
|
||||
|
||||
public void toggleLightPen() {
|
||||
this.lightPenMode = !this.lightPenMode;
|
||||
System.out.println("Light Pen mode: " + (this.lightPenMode ? "ON" : "OFF"));
|
||||
if (onLightPenToggle != null) {
|
||||
onLightPenToggle.run();
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user