Add missing menus back

This commit is contained in:
2026-08-30 23:46:29 +00:00
parent a3c4b95379
commit 27976dd31f
6 changed files with 62 additions and 56 deletions
@@ -18,9 +18,9 @@ public class QueryReplyBuilder {
private static final int SW_3279_2 = 0x09;
private static final int SH_3279_2 = 0x0c;
// Usable Area physical dimensions matching IBM Host On-Demand QR_USEAREA_STRING (Inches)
private static final int Xr_HOD = 0x00020089;
private static final int Yr_HOD = 0x00020085;
// Usable Area physical dimensions matching IBM Host On-Demand DS3270.java (Inches, 96 dpi: 0x00010060)
private static final int Xr_HOD = 0x00010060;
private static final int Yr_HOD = 0x00010060;
private final ScreenBuffer screen;
private GraphicsMode graphicsMode = GraphicsMode.BOTH;
@@ -309,7 +309,7 @@ public class QueryReplyBuilder {
private byte[] buildUsableArea(int maxCols, int maxRows, int bufferSize) {
ByteArrayOutputStream out = new ByteArrayOutputStream(19);
out.write(0x01); // 12/14-bit addressing
out.write(graphicsMode.isVectorGraphicsEnabled() ? 0x03 : 0x01); // 12/14-bit addressing + graphics flag (matching HOD DS3270.java)
out.write(0x00); // no special character features
out.write((maxCols >> 8) & 0xFF); // usable width high
out.write(maxCols & 0xFF); // usable width low
@@ -380,8 +380,8 @@ public class QueryReplyBuilder {
cpgid = screen.getTranslator().getCpgid();
}
if (graphicsMode.isProgrammedSymbolsEnabled()) {
// Programmed Symbols mode (3279 PS with LoadPS 0x0A, flags1 = 0xA2 for GE + PS + CGCSGID)
if (graphicsMode == GraphicsMode.PROGRAMMED_SYMBOLS) {
// Programmed Symbols only mode (3279 PS with LoadPS 0x0A, flags1 = 0xA2 for GE + PS + CGCSGID)
ByteArrayOutputStream out = new ByteArrayOutputStream(65);
out.write(0xa2); // flags: GE (0x80), PS/Loadable Charsets (0x20), CGCSGID present (0x02)
out.write(0x00); // more flags
@@ -615,11 +615,10 @@ public class QueryReplyBuilder {
cgcsgid = screen.getTranslator().getCgcsgid();
cpgid = screen.getTranslator().getCpgid();
}
// HOD QueryReply3270Constants.java QR_GRSYMBOLSET_S_STRING ("\u0000!\u0081\u00b6...")
return new byte[]{
0x00, 0x00, (byte) charW, (byte) charH, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12,
0x01, 0x00, 0x00, (byte) 0xF0, (byte) ((cgcsgid >> 8) & 0xFF), (byte) (cgcsgid & 0xFF), 0x00, 0x00,
(byte) charW, (byte) charH, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
(byte) charW, (byte) charH, 0x00, 0x00, (byte) 0xF0, (byte) ((cgcsgid >> 8) & 0xFF), (byte) (cgcsgid & 0xFF), 0x00, 0x00
};
}
@@ -60,10 +60,9 @@ public final class GocaConstants {
public static final int G_GSCR = 0x35; // Set Character Shear
public static final int G_GSMCEL = 0x37; // Set Marker Cell
public static final int G_GSCS = 0x38; // Set Character Set
public static final int G_GSMP = 0x39; // Set Marker Precision
public static final int G_GSETAG = 0x39; // Set Pick Identifier / Tag
public static final int G_GSCC = 0x39; // Set Character Precision
public static final int G_GSCD = 0x3A; // Set Character Direction
public static final int G_GSCC = 0x3B; // Set Character Precision
public static final int G_GSMP = 0x3B; // Set Marker Precision
public static final int G_GSMS_SET = 0x3C; // Set Marker Set
public static final int G_ENDPROLOGUE = 0x3E; // End Prologue
public static final int G_GPOP = 0x3F; // Pop Attribute
@@ -27,6 +27,7 @@ public class GocaDecoder {
private int markerType = GocaConstants.MK_PLUS;
private int markerSize = 5;
private int markerColor = GocaConstants.GOCA_COLORS[0];
private int markerPrecision = 0;
private int pattern = GocaConstants.PT_SOLID;
private int patternSet = 0;
private int fillColor = GocaConstants.GOCA_COLORS[0];
@@ -225,6 +226,7 @@ public class GocaDecoder {
markerType = GocaConstants.MK_PLUS;
markerSize = 5;
markerColor = curColor;
markerPrecision = 0;
pattern = GocaConstants.PT_SOLID;
patternSet = 0;
fillColor = curColor;
@@ -281,7 +283,7 @@ public class GocaDecoder {
// Flexible 1-byte attribute orders (support both short 2-byte or long 3-byte if len byte == 1)
if (order == GocaConstants.G_GSPT || order == GocaConstants.G_GSMT ||
order == GocaConstants.G_GSCS || order == GocaConstants.G_GSCD ||
order == GocaConstants.G_GSCC ||
order == GocaConstants.G_GSCC || order == GocaConstants.G_GSMP ||
order == GocaConstants.G_GSMS_SET || order == GocaConstants.G_GBAR) {
return (data[idx + 1] == 0x01 && idx + 2 < end) ? 3 : 2;
}
@@ -536,17 +538,7 @@ public class GocaDecoder {
}
break;
}
case GocaConstants.G_GSETAG: { // Set Pick Identifier / Tag (0x39)
if (currentSegId != 0 && payloadLen >= 2 && idx + 3 < end) {
int tag = ((inputData[idx + 2] & 0xFF) << 8) | (inputData[idx + 3] & 0xFF);
SegmentBounds sb = segmentBoundsMap.get(currentSegId);
if (sb != null) {
sb.tag = tag;
}
}
idx += orderLen;
break;
}
case GocaConstants.G_ENDPROLOGUE: { // End Prologue (0x3E)
idx += orderLen;
break;
@@ -706,16 +698,22 @@ public class GocaDecoder {
break;
}
case GocaConstants.G_GSCS: { // Set Character Set (0x38)
charSet = (orderLen == 3) ? (inputData[idx + 2] & 0xFF) : (inputData[idx + 1] & 0xFF);
int cs = (orderLen == 3) ? (inputData[idx + 2] & 0xFF) : (inputData[idx + 1] & 0xFF);
charSet = (cs == 0xF0) ? 0 : cs;
idx += orderLen;
break;
}
case GocaConstants.G_GSCC: { // Set Character Precision (0x3B)
case GocaConstants.G_GSCC: { // Set Character Precision (0x39)
charPrecision = (orderLen == 3) ? (inputData[idx + 2] & 0xFF) : (inputData[idx + 1] & 0xFF);
if (charPrecision == 0) charPrecision = GocaConstants.CP_STRING;
idx += orderLen;
break;
}
case GocaConstants.G_GSMP: { // Set Marker Precision (0x3B)
markerPrecision = (orderLen == 3) ? (inputData[idx + 2] & 0xFF) : (inputData[idx + 1] & 0xFF);
idx += orderLen;
break;
}
case GocaConstants.G_GSMX:
case GocaConstants.G_GSMS_SET:
case GocaConstants.G_GPOP: {
@@ -1393,7 +1391,15 @@ public class GocaDecoder {
break;
}
if (charSet != 0 && programSymbolManager != null) {
if (charSet == 0xF8 || charPrecision == GocaConstants.CP_STROKE) {
char[] chars = new char[textLen];
for (int i = 0; i < textLen; i++) {
chars[i] = EbcdicTranslator.ebcdicToAscii(data[pos + i]);
}
String text = new String(chars);
plane.drawVectorText(plane.mapXDouble(startX), plane.mapYDouble(startY), text,
curColor, cw, ch, charDir, charAngle);
} else if (charSet != 0 && programSymbolManager != null) {
for (int i = 0; i < textLen; i++) {
int code = data[pos + i] & 0xFF;
double px = plane.mapXDouble(startX);
@@ -1417,27 +1423,18 @@ public class GocaDecoder {
}
}
}
} else {
char c = EbcdicTranslator.ebcdicToAscii(data[pos + i]);
plane.drawVectorText(px, py, String.valueOf(c), curColor, cw, ch, charDir, charAngle);
}
startX += (charWidth > 0 ? charWidth : 9);
}
curX = startX;
curY = startY;
return;
}
char[] chars = new char[textLen];
for (int i = 0; i < textLen; i++) {
chars[i] = EbcdicTranslator.ebcdicToAscii(data[pos + i]);
}
String text = new String(chars);
if (charPrecision == GocaConstants.CP_STROKE) {
plane.drawVectorText(plane.mapXDouble(startX), plane.mapYDouble(startY), text,
curColor, cw, ch, charDir, charAngle);
} else {
char[] chars = new char[textLen];
for (int i = 0; i < textLen; i++) {
chars[i] = EbcdicTranslator.ebcdicToAscii(data[pos + i]);
}
String text = new String(chars);
plane.drawText(plane.mapXDouble(startX), plane.mapYDouble(startY), text,
curColor, cw, ch, charDir, charAngle);
}