IBM-DYNAMIC
Release j3270 / Build & Publish Release (push) Successful in 1m23s
Build and Test j3270 / Build JAR & Run Tests (push) Successful in 1m28s

This commit is contained in:
2026-09-03 16:27:01 -04:00
parent db6043cb39
commit 6296cf4341
210 changed files with 16655 additions and 299 deletions
@@ -18,6 +18,16 @@ public class ConnectionConfig {
private boolean tlsVerifyCert = true;
private haus.nightmare.lib3270j.tls.TlsCertificateVerifier certificateVerifier = null;
private String sslProtocol = "TLS";
private String keyStorePath = null;
private String keyStorePassword = null;
private String keyStoreType = null;
private String keyStoreAlias = null;
private String trustStorePath = null;
private String trustStorePassword = null;
private String trustStoreType = null;
private ClassLoader customizedCAsClassLoader = null;
private java.util.List<String> enabledProtocols = new java.util.ArrayList<>();
private java.util.List<String> enabledCipherSuites = new java.util.ArrayList<>();
private int connectTimeoutMs = 15000;
private int nopIntervalSeconds = 0;
private String terminalName = null; // override terminal type string
@@ -27,8 +37,8 @@ public class ConnectionConfig {
private int soTimeoutMs = 0;
private java.util.List<String> luNames = new java.util.ArrayList<>();
private boolean dynamicModel = false;
private int dynamicRows = 24;
private int dynamicCols = 80;
private int dynamicRows = 62;
private int dynamicCols = 160;
private haus.nightmare.lib3270j.graphics.GraphicsMode graphicsMode = haus.nightmare.lib3270j.graphics.GraphicsMode.BOTH;
private String codePage = "037";
private String associatedPrinterLu = null;
@@ -81,7 +91,12 @@ public class ConnectionConfig {
public void setPort(int port) { this.port = port; }
public TerminalModel getModel() { return model; }
public void setModel(TerminalModel model) { this.model = model; }
public void setModel(TerminalModel model) {
this.model = model;
if (model != null && model.isDynamic()) {
this.dynamicModel = true;
}
}
public String getLuName() { return luName; }
public void setLuName(String luName) { this.luName = luName; }
@@ -104,6 +119,52 @@ public class ConnectionConfig {
public String getSslProtocol() { return sslProtocol; }
public void setSslProtocol(String protocol) { this.sslProtocol = protocol; }
public String getKeyStorePath() { return keyStorePath; }
public void setKeyStorePath(String path) { this.keyStorePath = path; }
public String getKeyStorePassword() { return keyStorePassword; }
public void setKeyStorePassword(String password) { this.keyStorePassword = password; }
public String getKeyStoreType() { return keyStoreType; }
public void setKeyStoreType(String type) { this.keyStoreType = type; }
public String getKeyStoreAlias() { return keyStoreAlias; }
public void setKeyStoreAlias(String alias) { this.keyStoreAlias = alias; }
public String getTrustStorePath() { return trustStorePath; }
public void setTrustStorePath(String path) { this.trustStorePath = path; }
public String getTrustStorePassword() { return trustStorePassword; }
public void setTrustStorePassword(String password) { this.trustStorePassword = password; }
public String getTrustStoreType() { return trustStoreType; }
public void setTrustStoreType(String type) { this.trustStoreType = type; }
public ClassLoader getCustomizedCAsClassLoader() { return customizedCAsClassLoader; }
public void setCustomizedCAsClassLoader(ClassLoader cl) { this.customizedCAsClassLoader = cl; }
public java.util.List<String> getEnabledProtocols() { return enabledProtocols; }
public void setEnabledProtocols(java.util.List<String> protocols) {
this.enabledProtocols = protocols != null ? new java.util.ArrayList<>(protocols) : new java.util.ArrayList<>();
}
public void setEnabledProtocols(String... protocols) {
this.enabledProtocols = new java.util.ArrayList<>();
if (protocols != null) {
for (String p : protocols) if (p != null) this.enabledProtocols.add(p);
}
}
public java.util.List<String> getEnabledCipherSuites() { return enabledCipherSuites; }
public void setEnabledCipherSuites(java.util.List<String> cipherSuites) {
this.enabledCipherSuites = cipherSuites != null ? new java.util.ArrayList<>(cipherSuites) : new java.util.ArrayList<>();
}
public void setEnabledCipherSuites(String... cipherSuites) {
this.enabledCipherSuites = new java.util.ArrayList<>();
if (cipherSuites != null) {
for (String c : cipherSuites) if (c != null) this.enabledCipherSuites.add(c);
}
}
public int getConnectTimeoutMs() { return connectTimeoutMs; }
public void setConnectTimeoutMs(int ms) { this.connectTimeoutMs = ms; }
@@ -145,15 +206,30 @@ public class ConnectionConfig {
}
}
public boolean isDynamicModel() { return dynamicModel; }
public void setDynamicModel(boolean dynamicModel) { this.dynamicModel = dynamicModel; }
public boolean isDynamicModel() {
return dynamicModel || (model != null && model.isDynamic());
}
public void setDynamicModel(boolean dynamicModel) {
this.dynamicModel = dynamicModel;
if (dynamicModel && (model == null || !model.isDynamic())) {
this.model = TerminalModel.IBM_DYNAMIC;
} else if (!dynamicModel && model != null && model.isDynamic()) {
this.model = TerminalModel.IBM_3279_4;
}
}
public void setDynamic(boolean dynamic) {
setDynamicModel(dynamic);
}
public int getDynamicRows() { return dynamicRows; }
public int getDynamicCols() { return dynamicCols; }
public void setDynamicDimensions(int rows, int cols) {
this.dynamicModel = true;
this.dynamicRows = rows;
this.dynamicCols = cols;
this.dynamicRows = Math.max(1, rows);
this.dynamicCols = Math.max(1, cols);
this.model = TerminalModel.IBM_DYNAMIC;
}
public ProxyType getProxyType() { return proxyType; }
@@ -216,6 +292,9 @@ public class ConnectionConfig {
String s = hostStr.trim();
boolean tls = false;
boolean tn3270e = true;
boolean dynamic = false;
int dynRows = 62;
int dynCols = 160;
// Parse --proxy=<url> or -proxy=<url> flags
ProxyType pType = ProxyType.NONE;
@@ -287,6 +366,29 @@ public class ConnectionConfig {
int colon = s.indexOf(':');
s = s.substring(colon + 1);
prefixFound = true;
} else if (s.startsWith("D:") || s.startsWith("d:")) {
dynamic = true;
s = s.substring(2);
prefixFound = true;
} else if (s.toLowerCase().startsWith("dyn:") || s.toLowerCase().startsWith("dynamic:") ||
s.toLowerCase().startsWith("dyn[") || s.toLowerCase().startsWith("dynamic[")) {
int colon = s.indexOf(':');
if (colon > 0) {
String prefix = s.substring(0, colon);
s = s.substring(colon + 1);
prefixFound = true;
dynamic = true;
if (prefix.contains("[") && prefix.contains("]")) {
String dim = prefix.substring(prefix.indexOf('[') + 1, prefix.indexOf(']'));
String[] parts = dim.toLowerCase().split("x");
if (parts.length == 2) {
try {
dynRows = Integer.parseInt(parts[0].trim());
dynCols = Integer.parseInt(parts[1].trim());
} catch (NumberFormatException ignored) {}
}
}
}
}
}
@@ -315,6 +417,9 @@ public class ConnectionConfig {
ConnectionConfig config = new ConnectionConfig(host, port, defaultModel != null ? defaultModel : TerminalModel.IBM_3279_4);
config.setUseTls(tls);
config.setTn3270eEnabled(tn3270e);
if (dynamic) {
config.setDynamicDimensions(dynRows, dynCols);
}
if (pType != ProxyType.NONE && pHost != null) {
config.setProxy(pType, pHost, pPort, pUser, pPass);
}
@@ -328,7 +433,7 @@ public class ConnectionConfig {
if (terminalName != null) {
return terminalName;
}
if (dynamicModel) {
if (isDynamicModel()) {
return extendedDataStream ? "IBM-DYNAMIC-E" : "IBM-DYNAMIC";
}
return extendedDataStream ? model.getTerminalType() : model.getBaseTerminalType();
@@ -47,7 +47,16 @@ public class Telnet3270Client {
public Telnet3270Client(ConnectionConfig config) {
this.config = config;
this.translator = new EbcdicTranslator(config.getCodePage());
this.screenBuffer = new ScreenBuffer(config.getModel(), translator);
if (config.isDynamicModel() || (config.getModel() != null && config.getModel().isDynamic())) {
this.screenBuffer = new ScreenBuffer(
haus.nightmare.lib3270j.protocol.DS3270Constants.MODEL_2_ROWS,
haus.nightmare.lib3270j.protocol.DS3270Constants.MODEL_2_COLS,
config.getDynamicRows(),
config.getDynamicCols(),
translator);
} else {
this.screenBuffer = new ScreenBuffer(config.getModel(), translator);
}
this.dsProcessor = new DataStreamProcessor(screenBuffer, translator);
this.dsProcessor.getQueryReplyBuilder().setGraphicsMode(config.getGraphicsMode());
this.fsm = new TelnetFSM(config, screenBuffer, dsProcessor);
@@ -244,6 +253,9 @@ public class Telnet3270Client {
/** Get the data stream processor. */
public DataStreamProcessor getDataStreamProcessor() { return dsProcessor; }
/** Get the underlying telnet connection. */
public TelnetConnection getConnection() { return connection; }
/** Get the connection config. */
public ConnectionConfig getConfig() { return config; }
@@ -14,7 +14,8 @@ public enum TerminalModel {
IBM_3279_2(2, true, MODEL_2_ROWS, MODEL_2_COLS, MODEL_2_ROWS, MODEL_2_COLS),
IBM_3279_3(3, true, MODEL_2_ROWS, MODEL_2_COLS, MODEL_3_ROWS, MODEL_3_COLS),
IBM_3279_4(4, true, MODEL_2_ROWS, MODEL_2_COLS, MODEL_4_ROWS, MODEL_4_COLS),
IBM_3279_5(5, true, MODEL_2_ROWS, MODEL_2_COLS, MODEL_5_ROWS, MODEL_5_COLS);
IBM_3279_5(5, true, MODEL_2_ROWS, MODEL_2_COLS, MODEL_5_ROWS, MODEL_5_COLS),
IBM_DYNAMIC(0, true, MODEL_2_ROWS, MODEL_2_COLS, 62, 160);
private final int modelNumber;
private final boolean color;
@@ -40,12 +41,17 @@ public enum TerminalModel {
public int getDefaultCols() { return defaultCols; }
public int getAlternateRows() { return alternateRows; }
public int getAlternateCols() { return alternateCols; }
public boolean isDynamic() { return modelNumber == 0; }
/**
* Returns the terminal type string for TN3270E negotiation.
* e.g., "IBM-3279-4-E" for a color model 4 with extended data stream.
* e.g., "IBM-3279-4-E" for a color model 4 with extended data stream,
* or "IBM-DYNAMIC-E" for dynamic model.
*/
public String getTerminalType() {
if (modelNumber == 0) {
return "IBM-DYNAMIC-E";
}
return String.format("IBM-327%c-%d-E", color ? '9' : '8', modelNumber);
}
@@ -53,6 +59,9 @@ public enum TerminalModel {
* Returns the base terminal type without "-E" suffix (for non-extended mode).
*/
public String getBaseTerminalType() {
if (modelNumber == 0) {
return "IBM-DYNAMIC";
}
return String.format("IBM-327%c-%d", color ? '9' : '8', modelNumber);
}
@@ -60,6 +69,9 @@ public enum TerminalModel {
* Look up a model by number and color mode.
*/
public static TerminalModel forModel(int number, boolean isColor) {
if (number == 0) {
return IBM_DYNAMIC;
}
for (TerminalModel m : values()) {
if (m.modelNumber == number && m.color == isColor) {
return m;
@@ -69,4 +69,88 @@ public interface CodePage {
* Returns -1 if unmappable.
*/
int unicodeToDbcs(char unicode);
/**
* Convert an EBCDIC byte buffer to a char array matching IBM HoD conversion.
*/
default char[] convBuffByte2Char(byte[] buf, int offset, int length) {
if (buf == null || length <= 0) return new char[0];
char[] out = new char[length];
for (int i = 0; i < length; i++) {
out[i] = ebcdicToUnicode(buf[offset + i] & 0xFF);
}
return out;
}
/**
* Convert a char array to an EBCDIC byte array matching IBM HoD conversion.
*/
default byte[] convBuffChar2Byte(char[] buf, int offset, int length) {
if (buf == null || length <= 0) return new byte[0];
byte[] out = new byte[length];
for (int i = 0; i < length; i++) {
out[i] = unicodeToEbcdicSafe(buf[offset + i]);
}
return out;
}
/**
* Get a HODByteToCharConverter instance backed by this CodePage.
*/
default haus.nightmare.lib3270j.converters.HODByteToCharConverter getByteToCharConverter() {
if (isDBCS()) {
return new haus.nightmare.lib3270j.converters.ByteToCharDBCS_EBCDIC(this);
} else {
return new haus.nightmare.lib3270j.converters.ByteToCharSingleByte(this);
}
}
/**
* Get a HODCharToByteConverter instance backed by this CodePage.
*/
default haus.nightmare.lib3270j.converters.HODCharToByteConverter getCharToByteConverter() {
if (isDBCS()) {
return new haus.nightmare.lib3270j.converters.CharToByteDBCS_EBCDIC(this);
} else {
return new haus.nightmare.lib3270j.converters.CharToByteSingleByte(this);
}
}
/**
* Helper to test if a pair of characters forms a Unicode surrogate pair.
*/
static boolean isSurrogate(char high, char low) {
return Character.isSurrogatePair(high, low);
}
/**
* Helper to test if a character is a high surrogate.
*/
static boolean isHighSurrogate(char c) {
return Character.isHighSurrogate(c);
}
/**
* Helper to test if a character is a low surrogate.
*/
static boolean isLowSurrogate(char c) {
return Character.isLowSurrogate(c);
}
/**
* Helper matching IBM HoD CodePage.ComposeChar to combine characters.
*/
static boolean ComposeChar(char[] chars) {
if (chars == null || chars.length < 2) return false;
if (chars[1] >= '\u0300' && chars[1] <= '\u036F') {
String decomposed = new String(chars, 0, 2);
String normalized = java.text.Normalizer.normalize(decomposed, java.text.Normalizer.Form.NFC);
if (normalized.length() == 1) {
chars[0] = normalized.charAt(0);
return true;
}
}
return false;
}
}
@@ -157,7 +157,25 @@ public class CodePageRegistry {
public static String normalizeKey(String name) {
if (name == null) return "";
String s = name.trim().toLowerCase();
String s = name.trim();
// Strip package qualifiers if present (e.g. com.ibm.eNetwork.HOD.converters.onea.ByteToCharCp273)
int lastDot = Math.max(s.lastIndexOf('.'), s.lastIndexOf('/'));
if (lastDot >= 0 && lastDot < s.length() - 1) {
s = s.substring(lastDot + 1);
}
// Strip HoD converter class prefixes
for (String pfx : new String[]{
"HODByteToChar", "HODCharToByte", "ByteToChar", "CharToByte",
"ConverterBIDIPrinter", "ConverterFT", "ConverterJDK", "ConverterVT", "PrtConverter"
}) {
if (s.startsWith(pfx)) {
s = s.substring(pfx.length());
break;
}
}
s = s.toLowerCase();
s = s.replace("_", "").replace("-", "");
if (s.startsWith("ebcdiccp")) {
s = s.substring(8);
@@ -174,13 +192,12 @@ public class CodePageRegistry {
}
/**
* Look up a code page by ID or alias.
* If not found in built-ins, attempts to load via java.nio.charset.Charset.
* Falls back to CP037 if completely unresolvable.
* Look up a code page by ID, alias, or converter name without fallback to CP037.
* Returns null if unresolvable.
*/
public static CodePage getCodePage(String name) {
public static CodePage resolveCodePage(String name) {
if (name == null || name.trim().isEmpty()) {
return CODE_PAGES.get("037");
return null;
}
String raw = name.trim();
@@ -198,6 +215,9 @@ public class CodePageRegistry {
if (targetId != null) {
cp = CODE_PAGES.get(targetId);
if (cp != null) return cp;
String normTarget = normalizeKey(targetId);
cp = CODE_PAGES.get(normTarget);
if (cp != null) return cp;
}
// Try standard NIO Charset dynamic adapter
@@ -205,18 +225,55 @@ public class CodePageRegistry {
if (Charset.isSupported(raw)) {
return new NioCodePageAdapter(raw);
}
if (Charset.isSupported(norm)) {
return new NioCodePageAdapter(norm);
}
String ibmName = "IBM" + norm;
if (Charset.isSupported(ibmName)) {
return new NioCodePageAdapter(ibmName);
}
String ibmDashName = "IBM-" + norm;
if (Charset.isSupported(ibmDashName)) {
return new NioCodePageAdapter(ibmDashName);
}
String cpName = "Cp" + norm;
if (Charset.isSupported(cpName)) {
return new NioCodePageAdapter(cpName);
}
String isoName = "ISO-8859-" + norm.replace("8859", "");
if (Charset.isSupported(isoName)) {
return new NioCodePageAdapter(isoName);
}
String winName = "windows-" + norm;
if (Charset.isSupported(winName)) {
return new NioCodePageAdapter(winName);
}
} catch (Exception e) {
log.fine("Dynamic charset loading failed for " + name + ": " + e.getMessage());
}
return null;
}
/**
* Look up a code page by ID or alias.
* If not found in built-ins, attempts to load via java.nio.charset.Charset.
* Falls back to CP037 if completely unresolvable.
*/
public static CodePage get(String name) {
return getCodePage(name);
}
public static CodePage getDefault() {
return getCodePage("037");
}
public static CodePage getCodePage(String name) {
CodePage cp = resolveCodePage(name);
if (cp != null) {
return cp;
}
log.warning("CodePage not recognized: '" + name + "'; falling back to CP037");
return CODE_PAGES.get("037");
}
@@ -301,18 +358,82 @@ public class CodePageRegistry {
addAlias("chinese-ext-traditional", "1371");
addAlias("zh-traditional-ext", "1371");
addAlias("zh-tw-ext", "1371");
// HoD Converter aliases mapping all HoD converter names to CodePage / Charset
addAlias("1390", "930");
addAlias("1390jis2004", "930");
addAlias("1399", "939");
addAlias("1399jis2004", "939");
addAlias("937macau", "937");
addAlias("1364", "933");
addAlias("1379", "937");
addAlias("274", "500");
addAlias("275", "037");
addAlias("924", "1047");
addAlias("1153", "870");
addAlias("1156", "1025");
addAlias("1157", "1025");
addAlias("1158", "1025");
addAlias("1166", "1025");
addAlias("1112", "1025");
addAlias("1122", "1025");
addAlias("1137", "037");
addAlias("1008", "420");
addAlias("449", "420");
addAlias("1089", "420");
addAlias("1134", "424");
addAlias("1349", "424");
addAlias("8585", "875");
addAlias("8586", "875");
addAlias("220", "284");
addAlias("big5550", "937");
addAlias("cns", "937");
addAlias("tca", "937");
addAlias("ks25550", "933");
addAlias("jis", "930");
addAlias("euc", "937");
addAlias("singlebyte", "037");
addAlias("dbcsebcdic", "930");
addAlias("dbcsebcdicnibm", "930");
addAlias("dbcsebcdicibm", "930");
addAlias("dbcsascii", "930");
addAlias("encodings", "037");
addAlias("1011", "037");
addAlias("1012", "037");
addAlias("1020", "037");
addAlias("1021", "037");
addAlias("1023", "037");
addAlias("1090", "037");
addAlias("1101", "037");
addAlias("1102", "037");
addAlias("1103", "037");
addAlias("1104", "037");
addAlias("1105", "037");
addAlias("1106", "037");
}
/**
* Check if a code page is registered.
* Check if a code page or converter is registered or resolvable.
*/
public static boolean hasCodePage(String name) {
if (name == null || name.trim().isEmpty()) return false;
String raw = name.trim();
if (CODE_PAGES.containsKey(raw)) return true;
String norm = normalizeKey(raw);
if (CODE_PAGES.containsKey(norm)) return true;
return ALIASES.containsKey(norm);
return resolveCodePage(name) != null;
}
/**
* Convenience factory method to get a HODByteToCharConverter by name or alias.
*/
public static haus.nightmare.lib3270j.converters.HODByteToCharConverter getByteToCharConverter(String name)
throws haus.nightmare.lib3270j.converters.HODUnsupportedCodepageException {
return haus.nightmare.lib3270j.converters.HODByteToCharConverter.getHODConverter(name);
}
/**
* Convenience factory method to get a HODCharToByteConverter by name or alias.
*/
public static haus.nightmare.lib3270j.converters.HODCharToByteConverter getCharToByteConverter(String name)
throws haus.nightmare.lib3270j.converters.HODUnsupportedCodepageException {
return haus.nightmare.lib3270j.converters.HODCharToByteConverter.getHODConverter(name);
}
/**
@@ -0,0 +1,178 @@
package haus.nightmare.lib3270j.converters;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.charset.CodePageRegistry;
/**
* Concrete converter implementing mixed SBCS/DBCS byte-to-char conversion with transparent
* Shift-Out (0x0E) and Shift-In (0x0F) state management.
* Conforms to com.ibm.eNetwork.HOD.converters.ByteToCharDBCS_EBCDIC.
*/
public class ByteToCharDBCS_EBCDIC extends HODByteToCharConverter {
public ByteToCharDBCS_EBCDIC() {
this(CodePageRegistry.getCodePage("930"));
}
public ByteToCharDBCS_EBCDIC(CodePage codePage) {
super(codePage != null ? codePage : CodePageRegistry.getCodePage("930"));
}
@Override
public int convert(byte[] in, int inOff, int inEnd, char[] out, int outOff, int outEnd)
throws HODCharConversionException {
if (in == null || inEnd <= inOff) {
return 0;
}
if (out == null) {
throw new HODCharConversionException("Output buffer cannot be null");
}
this.byteOff = inOff;
this.charOff = outOff;
while (this.byteOff < inEnd || this.savedBytePresent) {
int b;
boolean isSaved = false;
if (this.savedBytePresent) {
b = this.savedByte & 0xFF;
this.savedBytePresent = false;
isSaved = true;
} else {
b = in[this.byteOff] & 0xFF;
}
// Handle Shift-Out (0x0E) -> DBCS mode
if (b == SO) {
this.currentState = 1;
if (this.preserveSOSI) {
if (this.charOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow writing SO at " + this.charOff);
}
out[this.charOff++] = (char) SO;
}
if (!isSaved) this.byteOff++;
continue;
}
// Handle Shift-In (0x0F) -> SBCS mode
if (b == SI) {
this.currentState = 0;
if (this.preserveSOSI) {
if (this.charOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow writing SI at " + this.charOff);
}
out[this.charOff++] = (char) SI;
}
if (!isSaved) this.byteOff++;
continue;
}
// SBCS mode conversion
if (this.currentState == 0) {
if (this.charOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow at position " + this.charOff);
}
char c = this.codePage.ebcdicToUnicode(b);
if (c == '\uFFFD') {
if (this.subMode) {
c = this.subChars[0];
} else {
this.badInputLength = 1;
throw new HODCharConversionException("Unmappable byte 0x" + Integer.toHexString(b) + " at index " + this.byteOff);
}
}
out[this.charOff++] = c;
if (!isSaved) this.byteOff++;
} else {
// DBCS mode conversion (requires 2 bytes)
int b2;
if (isSaved) {
if (this.byteOff >= inEnd) {
// Incomplete DBCS pair at end of buffer
this.savedByte = (byte) b;
this.savedBytePresent = true;
break;
}
b2 = in[this.byteOff++] & 0xFF;
} else {
if (this.byteOff + 1 >= inEnd) {
// Trailing single byte inside DBCS shift
this.savedByte = (byte) b;
this.savedBytePresent = true;
this.byteOff++;
break;
}
b2 = in[this.byteOff + 1] & 0xFF;
this.byteOff += 2;
}
// Check for premature Shift-In
if (b2 == SI) {
this.currentState = 0;
if (this.charOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow at position " + this.charOff);
}
out[this.charOff++] = this.codePage.ebcdicToUnicode(b);
if (this.preserveSOSI) {
if (this.charOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow at position " + this.charOff);
}
out[this.charOff++] = (char) SI;
}
continue;
}
char c = this.codePage.dbcsToUnicode(b, b2);
if (c == '?' || c == '\uFFFD') {
if (this.subMode) {
c = this.subChars[0];
} else {
this.badInputLength = 2;
throw new HODCharConversionException("Unmappable DBCS pair 0x" + Integer.toHexString(b) + ", 0x" + Integer.toHexString(b2));
}
}
if (this.charOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow at position " + this.charOff);
}
out[this.charOff++] = c;
}
}
return this.charOff - outOff;
}
@Override
public int flush(char[] out, int outOff, int outEnd) throws HODCharConversionException {
int count = 0;
if (this.savedBytePresent) {
if (!this.subMode) {
reset();
this.badInputLength = 1;
throw new HODCharConversionException("Unclosed trailing DBCS byte at end of input");
}
if (outOff < outEnd) {
out[outOff] = this.subChars[0];
count = 1;
}
}
reset();
return count;
}
@Override
public void reset() {
this.byteOff = 0;
this.charOff = 0;
this.currentState = 0;
this.savedBytePresent = false;
this.savedByte = 0;
this.badInputLength = 0;
}
@Override
public String getCharacterEncoding() {
return this.codePage != null ? "Cp" + this.codePage.getCodePageId() : "DBCS_EBCDIC";
}
}
@@ -0,0 +1,74 @@
package haus.nightmare.lib3270j.converters;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.charset.CodePageRegistry;
/**
* Concrete converter implementing single-byte character set (SBCS) byte-to-char conversion.
* Conforms to com.ibm.eNetwork.HOD.converters.ByteToCharSingleByte.
*/
public class ByteToCharSingleByte extends HODByteToCharConverter {
public ByteToCharSingleByte() {
this(CodePageRegistry.getDefault());
}
public ByteToCharSingleByte(CodePage codePage) {
super(codePage != null ? codePage : CodePageRegistry.getDefault());
}
@Override
public int convert(byte[] in, int inOff, int inEnd, char[] out, int outOff, int outEnd)
throws HODCharConversionException {
if (in == null || inEnd <= inOff) {
return 0;
}
if (out == null) {
throw new HODCharConversionException("Output buffer cannot be null");
}
this.byteOff = inOff;
this.charOff = outOff;
while (this.byteOff < inEnd) {
if (this.charOff >= outEnd) {
throw new HODCharConversionException("Output char buffer overflow at position " + this.charOff);
}
int b = in[this.byteOff] & 0xFF;
char c = this.codePage.ebcdicToUnicode(b);
if (c == '\uFFFD') {
if (this.subMode) {
c = this.subChars[0];
} else {
this.badInputLength = 1;
throw new HODCharConversionException("Unmappable byte 0x" + Integer.toHexString(b) + " at input index " + this.byteOff);
}
}
out[this.charOff++] = c;
this.byteOff++;
}
return this.charOff - outOff;
}
@Override
public int flush(char[] out, int outOff, int outEnd) {
reset();
return 0;
}
@Override
public void reset() {
this.byteOff = 0;
this.charOff = 0;
this.badInputLength = 0;
}
@Override
public String getCharacterEncoding() {
return this.codePage != null ? "Cp" + this.codePage.getCodePageId() : "SingleByte";
}
}
@@ -0,0 +1,137 @@
package haus.nightmare.lib3270j.converters;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.charset.CodePageRegistry;
/**
* Concrete converter implementing mixed SBCS/DBCS char-to-byte conversion with transparent
* Shift-Out (0x0E) and Shift-In (0x0F) state generation.
* Conforms to com.ibm.eNetwork.HOD.converters.CharToByteDBCS_EBCDIC.
*/
public class CharToByteDBCS_EBCDIC extends HODCharToByteConverter {
public CharToByteDBCS_EBCDIC() {
this(CodePageRegistry.getCodePage("930"));
}
public CharToByteDBCS_EBCDIC(CodePage codePage) {
super(codePage != null ? codePage : CodePageRegistry.getCodePage("930"));
}
@Override
public int convert(char[] in, int inOff, int inEnd, byte[] out, int outOff, int outEnd)
throws HODCharConversionException {
if (in == null || inEnd <= inOff) {
return 0;
}
if (out == null) {
throw new HODCharConversionException("Output buffer cannot be null");
}
this.charOff = inOff;
this.byteOff = outOff;
while (this.charOff < inEnd) {
char c = in[this.charOff];
// Explicit Shift-Out control character handling
if (c == (char) SO) {
if (this.currentState == 0) {
if (this.byteOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow writing SO at " + this.byteOff);
}
out[this.byteOff++] = SO;
this.currentState = 1;
}
this.charOff++;
continue;
}
// Explicit Shift-In control character handling
if (c == (char) SI) {
if (this.currentState == 1) {
if (this.byteOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow writing SI at " + this.byteOff);
}
out[this.byteOff++] = SI;
this.currentState = 0;
}
this.charOff++;
continue;
}
int dbcs = this.codePage.unicodeToDbcs(c);
if (dbcs >= 0) {
// Character is DBCS: ensure in DBCS mode
int needed = (this.currentState == 0) ? 3 : 2;
if (this.byteOff + needed > outEnd) {
throw new HODCharConversionException("Output buffer overflow writing DBCS character at " + this.byteOff);
}
if (this.currentState == 0) {
out[this.byteOff++] = SO;
this.currentState = 1;
}
out[this.byteOff++] = (byte) ((dbcs >> 8) & 0xFF);
out[this.byteOff++] = (byte) (dbcs & 0xFF);
} else {
// Character is SBCS: ensure in SBCS mode
int needed = (this.currentState == 1) ? 2 : 1;
if (this.byteOff + needed > outEnd) {
throw new HODCharConversionException("Output buffer overflow writing SBCS character at " + this.byteOff);
}
if (this.currentState == 1) {
out[this.byteOff++] = SI;
this.currentState = 0;
}
int ebc = this.codePage.unicodeToEbcdic(c);
if (ebc < 0) {
if (this.subMode) {
out[this.byteOff++] = this.subBytes[0];
} else {
this.badInputLength = 1;
throw new HODCharConversionException("Unmappable character '\\u" + Integer.toHexString(c) + "' at input index " + this.charOff);
}
} else {
out[this.byteOff++] = (byte) (ebc & 0xFF);
}
}
this.charOff++;
}
return this.byteOff - outOff;
}
@Override
public int flush(byte[] out, int outOff, int outEnd) throws HODCharConversionException {
int flushed = 0;
if (this.currentState == 1) {
if (outOff >= outEnd) {
throw new HODCharConversionException("Output buffer overflow during flush at " + outOff);
}
out[outOff] = SI;
flushed = 1;
this.currentState = 0;
}
reset();
return flushed;
}
@Override
public void reset() {
this.charOff = 0;
this.byteOff = 0;
this.currentState = 0;
this.badInputLength = 0;
}
@Override
public String getCharacterEncoding() {
return this.codePage != null ? "Cp" + this.codePage.getCodePageId() : "DBCS_EBCDIC";
}
}
@@ -0,0 +1,75 @@
package haus.nightmare.lib3270j.converters;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.charset.CodePageRegistry;
/**
* Concrete converter implementing single-byte character set (SBCS) char-to-byte conversion.
* Conforms to com.ibm.eNetwork.HOD.converters.CharToByteSingleByte.
*/
public class CharToByteSingleByte extends HODCharToByteConverter {
public CharToByteSingleByte() {
this(CodePageRegistry.getDefault());
}
public CharToByteSingleByte(CodePage codePage) {
super(codePage != null ? codePage : CodePageRegistry.getDefault());
}
@Override
public int convert(char[] in, int inOff, int inEnd, byte[] out, int outOff, int outEnd)
throws HODCharConversionException {
if (in == null || inEnd <= inOff) {
return 0;
}
if (out == null) {
throw new HODCharConversionException("Output buffer cannot be null");
}
this.charOff = inOff;
this.byteOff = outOff;
while (this.charOff < inEnd) {
if (this.byteOff >= outEnd) {
throw new HODCharConversionException("Output byte buffer overflow at position " + this.byteOff);
}
char c = in[this.charOff];
int ebc = this.codePage.unicodeToEbcdic(c);
if (ebc < 0) {
if (this.subMode) {
out[this.byteOff++] = this.subBytes[0];
} else {
this.badInputLength = 1;
throw new HODCharConversionException("Unmappable character '\\u" + Integer.toHexString(c) + "' at input index " + this.charOff);
}
} else {
out[this.byteOff++] = (byte) (ebc & 0xFF);
}
this.charOff++;
}
return this.byteOff - outOff;
}
@Override
public int flush(byte[] out, int outOff, int outEnd) {
reset();
return 0;
}
@Override
public void reset() {
this.charOff = 0;
this.byteOff = 0;
this.badInputLength = 0;
}
@Override
public String getCharacterEncoding() {
return this.codePage != null ? "Cp" + this.codePage.getCodePageId() : "SingleByte";
}
}
@@ -0,0 +1,184 @@
package haus.nightmare.lib3270j.converters;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.charset.CodePageRegistry;
import java.util.Objects;
/**
* High-performance adapter and bridge converting byte streams (EBCDIC, ASCII, ISO, UTF)
* to Unicode characters conforming to IBM Host On-Demand (HoD) converter specifications.
* <p>
* Supports dynamic factory resolution for all 275 HoD converter class names and transparent
* Shift-In (0x0F) / Shift-Out (0x0E) DBCS transitions.
*/
public abstract class HODByteToCharConverter {
public static final int SO = 0x0E;
public static final int SI = 0x0F;
protected int byteOff = 0;
protected int charOff = 0;
protected int badInputLength = 0;
protected boolean subMode = true;
protected char[] subChars = new char[]{'\uFFFD'};
protected CodePage codePage;
// DBCS State
protected int currentState = 0; // 0 = SBCS, 1 = DBCS
protected boolean savedBytePresent = false;
protected byte savedByte = 0;
protected boolean preserveSOSI = false;
public HODByteToCharConverter() {
}
public HODByteToCharConverter(CodePage codePage) {
this.codePage = Objects.requireNonNull(codePage, "codePage cannot be null");
}
/**
* Look up and instantiate a ByteToChar converter matching the given encoding,
* codepage ID, alias, or HoD converter class name (e.g. "Cp037", "037", "ByteToCharCp1047", "ConverterFT1047").
*
* @param encoding encoding identifier or class name
* @return initialized HODByteToCharConverter instance
* @throws HODUnsupportedCodepageException if the codepage cannot be resolved
*/
public static HODByteToCharConverter getHODConverter(String encoding) throws HODUnsupportedCodepageException {
if (encoding == null || encoding.trim().isEmpty()) {
throw new HODUnsupportedCodepageException("Encoding name cannot be null or empty");
}
CodePage cp = CodePageRegistry.resolveCodePage(encoding);
if (cp == null) {
throw new HODUnsupportedCodepageException("Unsupported codepage / converter: " + encoding);
}
if (cp.isDBCS()) {
return new ByteToCharDBCS_EBCDIC(cp);
} else {
return new ByteToCharSingleByte(cp);
}
}
/**
* Standard converter lookup alias conforming to Java/HoD converter factory patterns.
*/
public static HODByteToCharConverter getConverter(String encoding) throws HODUnsupportedCodepageException {
return getHODConverter(encoding);
}
/**
* Convert an array of bytes into an array of characters.
*
* @param in source byte buffer
* @param inOff start offset in input buffer
* @param inEnd end offset in input buffer (exclusive)
* @param out destination char buffer
* @param outOff start offset in output buffer
* @param outEnd end offset in output buffer (exclusive)
* @return number of characters converted and written into out
* @throws HODCharConversionException if an unmappable byte is encountered with substitution disabled,
* or if the output buffer overflows
*/
public abstract int convert(byte[] in, int inOff, int inEnd, char[] out, int outOff, int outEnd)
throws HODCharConversionException;
/**
* Overload supporting an extra boolean flag matching HoD CFR decompiled signature.
*/
public int convert(byte[] in, int inOff, int inEnd, char[] out, int outOff, int outEnd, boolean bl)
throws HODCharConversionException {
return convert(in, inOff, inEnd, out, outOff, outEnd);
}
/**
* Flush any buffered / trailing state into the output char buffer.
*
* @param out destination char buffer
* @param outOff start offset
* @param outEnd end offset
* @return number of characters flushed
* @throws HODCharConversionException if flush fails or trailing incomplete sequence cannot be converted
*/
public abstract int flush(char[] out, int outOff, int outEnd) throws HODCharConversionException;
/**
* Reset converter state and offsets to defaults.
*/
public abstract void reset();
/**
* Get the canonical character encoding name (e.g. "Cp037", "Cp930").
*/
public abstract String getCharacterEncoding();
/**
* Convert an entire byte array to a char array matching IBM HoD's hodConvertAll API.
*/
public char[] hodConvertAll(byte[] in) throws HODCharConversionException {
if (in == null) return new char[0];
reset();
char[] buf = new char[Math.max(16, in.length * 2 + 16)];
int converted = convert(in, 0, in.length, buf, 0, buf.length);
int flushed = flush(buf, converted, buf.length);
int total = converted + flushed;
char[] result = new char[total];
System.arraycopy(buf, 0, result, 0, total);
return result;
}
/**
* Convenience alias for hodConvertAll.
*/
public char[] convertAll(byte[] in) throws HODCharConversionException {
return hodConvertAll(in);
}
public void setSubstitutionMode(boolean mode) {
this.subMode = mode;
}
public boolean getSubstitutionMode() {
return this.subMode;
}
public void setSubstitutionChars(char[] subChars) {
if (subChars != null && subChars.length > 0) {
this.subChars = subChars;
}
}
public char[] getSubstitutionChars() {
return this.subChars;
}
public int getBadInputLength() {
return this.badInputLength;
}
public int nextByteIndex() {
return this.byteOff;
}
public int nextCharIndex() {
return this.charOff;
}
public CodePage getCodePage() {
return this.codePage;
}
public void setPreserveSOSI(boolean preserve) {
this.preserveSOSI = preserve;
}
public boolean isPreserveSOSI() {
return this.preserveSOSI;
}
public int getCurrentState() {
return this.currentState;
}
}
@@ -0,0 +1,20 @@
package haus.nightmare.lib3270j.converters;
import java.io.CharConversionException;
/**
* Exception thrown when character conversion fails during Host On-Demand converter processing.
* Conforms to com.ibm.eNetwork.HOD.common.HODCharConversionException.
*/
public class HODCharConversionException extends CharConversionException {
private static final long serialVersionUID = 1L;
public HODCharConversionException() {
super();
}
public HODCharConversionException(String message) {
super(message);
}
}
@@ -0,0 +1,169 @@
package haus.nightmare.lib3270j.converters;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.charset.CodePageRegistry;
import java.util.Objects;
/**
* High-performance adapter and bridge converting Unicode characters to byte streams
* (EBCDIC, ASCII, ISO, UTF) conforming to IBM Host On-Demand (HoD) converter specifications.
* <p>
* Supports dynamic factory resolution for all 275 HoD converter class names and transparent
* Shift-In (0x0F) / Shift-Out (0x0E) DBCS transitions.
*/
public abstract class HODCharToByteConverter {
public static final byte SO = 0x0E;
public static final byte SI = 0x0F;
protected int byteOff = 0;
protected int charOff = 0;
protected int badInputLength = 0;
protected boolean subMode = true;
protected byte[] subBytes = new byte[]{(byte) 0x6F}; // 0x6F '?' in EBCDIC (or safe fallback)
protected CodePage codePage;
// DBCS State
protected int currentState = 0; // 0 = SBCS, 1 = DBCS
public HODCharToByteConverter() {
}
public HODCharToByteConverter(CodePage codePage) {
this.codePage = Objects.requireNonNull(codePage, "codePage cannot be null");
}
/**
* Look up and instantiate a CharToByte converter matching the given encoding,
* codepage ID, alias, or HoD converter class name (e.g. "Cp037", "037", "CharToByteCp1047", "ConverterFT1047").
*
* @param encoding encoding identifier or class name
* @return initialized HODCharToByteConverter instance
* @throws HODUnsupportedCodepageException if the codepage cannot be resolved
*/
public static HODCharToByteConverter getHODConverter(String encoding) throws HODUnsupportedCodepageException {
if (encoding == null || encoding.trim().isEmpty()) {
throw new HODUnsupportedCodepageException("Encoding name cannot be null or empty");
}
CodePage cp = CodePageRegistry.resolveCodePage(encoding);
if (cp == null) {
throw new HODUnsupportedCodepageException("Unsupported codepage / converter: " + encoding);
}
if (cp.isDBCS()) {
return new CharToByteDBCS_EBCDIC(cp);
} else {
return new CharToByteSingleByte(cp);
}
}
/**
* Standard converter lookup alias conforming to Java/HoD converter factory patterns.
*/
public static HODCharToByteConverter getConverter(String encoding) throws HODUnsupportedCodepageException {
return getHODConverter(encoding);
}
/**
* Convert an array of characters into an array of bytes.
*
* @param in source char buffer
* @param inOff start offset in input buffer
* @param inEnd end offset in input buffer (exclusive)
* @param out destination byte buffer
* @param outOff start offset in output buffer
* @param outEnd end offset in output buffer (exclusive)
* @return number of bytes converted and written into out
* @throws HODCharConversionException if an unmappable char is encountered with substitution disabled,
* or if the output buffer overflows
*/
public abstract int convert(char[] in, int inOff, int inEnd, byte[] out, int outOff, int outEnd)
throws HODCharConversionException;
/**
* Flush any buffered / trailing shift state into the output byte buffer.
*
* @param out destination byte buffer
* @param outOff start offset
* @param outEnd end offset
* @return number of bytes flushed
* @throws HODCharConversionException if output buffer overflows
*/
public abstract int flush(byte[] out, int outOff, int outEnd) throws HODCharConversionException;
/**
* Reset converter state and offsets to defaults.
*/
public abstract void reset();
/**
* Get the canonical character encoding name (e.g. "Cp037", "Cp930").
*/
public abstract String getCharacterEncoding();
/**
* Convert an entire char array to a byte array matching IBM HoD's hodConvertAll API.
*/
public byte[] hodConvertAll(char[] in) throws HODCharConversionException {
if (in == null) return new byte[0];
reset();
byte[] buf = new byte[Math.max(16, in.length * 3 + 16)];
int converted = convert(in, 0, in.length, buf, 0, buf.length);
int flushed = flush(buf, converted, buf.length);
int total = converted + flushed;
byte[] result = new byte[total];
System.arraycopy(buf, 0, result, 0, total);
return result;
}
/**
* Convenience alias for hodConvertAll.
*/
public byte[] convertAll(char[] in) throws HODCharConversionException {
return hodConvertAll(in);
}
public void setSubstitutionMode(boolean mode) {
this.subMode = mode;
}
public boolean getSubstitutionMode() {
return this.subMode;
}
public void setSubstitutionBytes(byte[] subBytes) {
if (subBytes != null && subBytes.length > 0) {
this.subBytes = subBytes;
}
}
public byte[] getSubstitutionBytes() {
return this.subBytes;
}
public int getBadInputLength() {
return this.badInputLength;
}
public int nextByteIndex() {
return this.byteOff;
}
public int nextCharIndex() {
return this.charOff;
}
public int getMaxBytesPerChar() {
return (codePage != null && codePage.isDBCS()) ? 3 : 1; // At most 3 bytes (SO + 2-byte DBCS)
}
public CodePage getCodePage() {
return this.codePage;
}
public int getCurrentState() {
return this.currentState;
}
}
@@ -0,0 +1,20 @@
package haus.nightmare.lib3270j.converters;
import java.io.UnsupportedEncodingException;
/**
* Exception thrown when a requested character encoding or codepage identifier cannot be resolved.
* Conforms to com.ibm.eNetwork.HOD.common.HODUnsupportedCodepageException.
*/
public class HODUnsupportedCodepageException extends UnsupportedEncodingException {
private static final long serialVersionUID = 1L;
public HODUnsupportedCodepageException() {
super();
}
public HODUnsupportedCodepageException(String encoding) {
super(encoding);
}
}
@@ -63,6 +63,14 @@ public class DataStreamProcessor {
this.graphicsPlane.setProgramSymbolManager(programSymbolManager);
}
public ScreenBuffer getScreen() {
return screen;
}
public ScreenBuffer getScreenBuffer() {
return screen;
}
public QueryReplyBuilder getQueryReplyBuilder() {
return qrBuilder;
}
@@ -81,6 +89,13 @@ public class DataStreamProcessor {
public void setOutputSender(OutputSender sender) {
this.outputSender = sender;
if (inputProcessor != null) {
inputProcessor.setOutputSender(sender);
}
}
public OutputSender getOutputSender() {
return outputSender;
}
public void setFTDft(haus.nightmare.lib3270j.ft.FTDft ftDft) {
@@ -99,6 +114,9 @@ public class DataStreamProcessor {
public void setInputProcessor(haus.nightmare.lib3270j.input.InputProcessor inputProcessor) {
this.inputProcessor = inputProcessor;
if (inputProcessor != null && outputSender != null) {
inputProcessor.setOutputSender(outputSender);
}
}
public haus.nightmare.lib3270j.input.InputProcessor getInputProcessor() {
@@ -1516,4 +1534,233 @@ public class DataStreamProcessor {
public void processNullStructuredField() {
log.fine("Processed null structured field");
}
// ========== Phase 3: HoD DS3270 Order & Data Stream Functions ==========
/** Process Write Control Character (WCC). */
public void processWCC(int wcc) {
boolean alarm = wccSoundAlarm(wcc);
boolean kbdRestore = wccKeyboardRestore(wcc);
boolean resetMdt = wccResetMDT(wcc);
log.fine("processWCC: " + String.format("0x%02x", wcc) +
" reset=" + wccReset(wcc) + " alarm=" + alarm + " kbdRestore=" + kbdRestore + " resetMdt=" + resetMdt);
if (kbdRestore && inputProcessor != null) {
inputProcessor.setKeyboardLocked(false);
}
if (resetMdt) {
resetAllMDT();
}
if (wccReset(wcc)) {
log.fine("WCC reset: clearing default attributes");
}
}
public void processWCC(short wcc) {
processWCC(wcc & 0xFFFF);
}
/** Process Set Buffer Address (SBA) order. */
public void processSBA(int baddr) {
int size = screen.getRows() * screen.getCols();
if (size > 0) {
screen.setBufferAddress(baddr % size);
}
}
public void processSBA(int b1, int b2) {
processSBA(decodeAddress(b1, b2));
}
public void processSBA() {
// No-op or maintains current buffer address
}
/** Process Start Field (SF) order. */
public void processSF(byte fa) {
int size = screen.getRows() * screen.getCols();
if (size <= 0) return;
int baddr = screen.getBufferAddress();
ExtendedAttribute ea = screen.getCell(baddr);
ea.clear();
ea.fa = (byte) (fa & FA_MASK);
ea.ec = 0;
ea.ucs4 = ' ';
screen.setFormatted(true);
screen.setBufferAddress((baddr + 1) % size);
}
public void processSF() {
processSF((byte) FA_PRINTABLE);
}
/** Process Start Field Extended (SFE) order. */
public void processSFE(byte[] pairs) {
int size = screen.getRows() * screen.getCols();
if (size <= 0) return;
int baddr = screen.getBufferAddress();
ExtendedAttribute ea = screen.getCell(baddr);
ea.clear();
ea.ec = 0;
ea.ucs4 = ' ';
if (pairs != null) {
for (int i = 0; i + 1 < pairs.length; i += 2) {
int attrType = pairs[i] & 0xFF;
int attrValue = pairs[i + 1] & 0xFF;
applyExtendedAttribute(ea, attrType, attrValue);
}
}
if (ea.fa == 0) {
ea.fa = (byte) FA_PRINTABLE;
}
screen.setFormatted(true);
screen.setBufferAddress((baddr + 1) % size);
}
public void processSFE() {
processSFE(new byte[0]);
}
/** Process Set Attribute (SA) order. */
public void processSA(int attrType, int attrValue) {
int baddr = screen.getBufferAddress();
ExtendedAttribute ea = screen.getCell(baddr);
applyExtendedAttribute(ea, attrType, attrValue);
}
public void processSA() {
// Default attributes
}
/** Process Modify Field (MF) order. */
public void processMF(byte[] pairs) {
int baddr = screen.getBufferAddress();
int faAddr = screen.findFieldAttribute(baddr);
if (faAddr >= 0 && pairs != null) {
ExtendedAttribute ea = screen.getCell(faAddr);
for (int i = 0; i + 1 < pairs.length; i += 2) {
int attrType = pairs[i] & 0xFF;
int attrValue = pairs[i + 1] & 0xFF;
applyExtendedAttribute(ea, attrType, attrValue);
}
}
}
public void processMF() {
processMF(new byte[0]);
}
/** Process Insert Cursor (IC) order. */
public void processIC() {
screen.setCursorAddress(screen.getBufferAddress());
}
/** Process Program Tab (PT) order. */
public void processPT() {
int baddr = screen.findNextUnprotected(screen.getBufferAddress());
screen.setBufferAddress(baddr);
}
/** Process Repeat to Address (RA) order. */
public void processRA(int toAddr, int fillChar) {
int size = screen.getRows() * screen.getCols();
if (size <= 0) return;
toAddr = ((toAddr % size) + size) % size;
int baddr = screen.getBufferAddress();
char ucs4 = (translator != null) ? translator.ebcdicToUnicode(fillChar & 0xFF) : (char) fillChar;
do {
ExtendedAttribute ea = screen.getCell(baddr);
ea.fa = 0;
ea.ec = (byte) fillChar;
ea.ucs4 = ucs4;
baddr = (baddr + 1) % size;
} while (baddr != toAddr);
screen.setBufferAddress(baddr);
}
public void processRA() {
processRA(0, 0);
}
/** Process Erase Unprotected to Address (EUA) order. */
public void processEUA(int toAddr) {
int size = screen.getRows() * screen.getCols();
if (size <= 0) return;
toAddr = ((toAddr % size) + size) % size;
int baddr = screen.getBufferAddress();
do {
ExtendedAttribute ea = screen.getCell(baddr);
if (!ea.isFieldAttribute()) {
int faAddr = screen.findFieldAttribute(baddr);
byte faVal = faAddr >= 0 ? screen.getCell(faAddr).fa : 0;
if (!faIsProtected(faVal & 0xFF)) {
ea.ec = 0;
ea.ucs4 = 0;
ea.fg = 0;
ea.bg = 0;
ea.gr = 0;
ea.cs = 0;
}
}
baddr = (baddr + 1) % size;
} while (baddr != toAddr);
screen.setBufferAddress(baddr);
}
public void processEUA() {
processEUA(0);
}
/** Process Graphic Escape (GE) order. */
public void processGE(int geChar) {
int size = screen.getRows() * screen.getCols();
if (size <= 0) return;
int baddr = screen.getBufferAddress();
ExtendedAttribute ea = screen.getCell(baddr);
ea.fa = 0;
ea.ec = (byte) geChar;
ea.cs = CS_GE;
ea.ucs4 = (translator != null) ? translator.mapAPL(geChar) : (char) geChar;
screen.setBufferAddress((baddr + 1) % size);
}
public void processGE() {
processGE(0);
}
/** Process Write Structured Field (WSF) from short buffer. */
public void processWSF(short[] data, int off, int len) {
if (data == null || len <= 0) return;
byte[] bdata = new byte[len];
for (int i = 0; i < len; i++) {
bdata[i] = (byte) (data[off + i] & 0xFF);
}
processWriteStructuredField(bdata, 0, len);
}
public void processWSF(byte[] data, int off, int len) {
processWriteStructuredField(data, off, len);
}
/** Process raw inbound data stream chunk (short[] representation). */
public void processData(short[] data, int off, int len) {
if (data == null || len <= 0) return;
byte[] bdata = new byte[len];
for (int i = 0; i < len; i++) {
bdata[i] = (byte) (data[off + i] & 0xFF);
}
processRecord(bdata, 0, len, true);
}
public void processData(byte[] data, int off, int len) {
processRecord(data, off, len, true);
}
/** Send AID key with explicit cursor address. */
public void sendAid(short aid, int cursorAddress) {
if (inputProcessor != null) {
inputProcessor.sendAid(aid & 0xFFFF, cursorAddress);
}
}
}
@@ -7,6 +7,22 @@ import haus.nightmare.lib3270j.Telnet3270Client;
*/
public class ECLConnection extends haus.nightmare.lib3270j.ecl.ECLConnection {
public ECLConnection() {
super();
}
public ECLConnection(haus.nightmare.lib3270j.ecl.ECLSession session) {
super((haus.nightmare.lib3270j.ecl.ECLSession) session, session != null ? session.getClient() : null);
}
public ECLConnection(String host, int port) {
super(host, port);
}
public ECLConnection(java.util.Properties props) {
super(props);
}
public ECLConnection(haus.nightmare.lib3270j.ecl.ECLSession session, Telnet3270Client client) {
super(session, client);
}
@@ -0,0 +1,33 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLErr.
*/
public class ECLErr extends haus.nightmare.lib3270j.ecl.ECLErr {
private static final long serialVersionUID = 1L;
public ECLErr() {
super();
}
public ECLErr(String text) {
super(text);
}
public ECLErr(String tag, String id, String text) {
super(tag, id, text);
}
public ECLErr(String tag, String id, String text, String extra) {
super(tag, id, text, extra);
}
public ECLErr(Throwable cause) {
super(cause);
}
public ECLErr(String message, Throwable cause) {
super(message, cause);
}
}
@@ -12,4 +12,8 @@ public class ECLOIA extends haus.nightmare.lib3270j.ecl.ECLOIA {
public ECLOIA(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
super(screen, inputProcessor, fsm);
}
public ECLOIA(haus.nightmare.lib3270j.eNetwork.ECL.ECLSession session) {
super(session);
}
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLOIANotify.
*/
public interface ECLOIANotify extends haus.nightmare.lib3270j.ecl.ECLOIANotify {
}
@@ -12,4 +12,8 @@ public class ECLPS extends haus.nightmare.lib3270j.ecl.ECLPS {
public ECLPS(ScreenBuffer screen, InputProcessor inputProcessor, EbcdicTranslator translator) {
super(screen, inputProcessor, translator);
}
public ECLPS(haus.nightmare.lib3270j.eNetwork.ECL.ECLSession session) {
super(session);
}
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLPSBIDIServices.
*/
public interface ECLPSBIDIServices extends haus.nightmare.lib3270j.ecl.ECLPSBIDIServices {
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLPSGraphicsServices.
*/
public interface ECLPSGraphicsServices extends haus.nightmare.lib3270j.ecl.ECLPSGraphicsServices {
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLPSHindiServices.
*/
public interface ECLPSHindiServices extends haus.nightmare.lib3270j.ecl.ECLPSHindiServices {
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLPSTHAIServices.
*/
public interface ECLPSTHAIServices extends haus.nightmare.lib3270j.ecl.ECLPSTHAIServices {
}
@@ -0,0 +1,18 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLPSUpdate.
*/
public class ECLPSUpdate extends haus.nightmare.lib3270j.ecl.ECLPSUpdate {
private static final long serialVersionUID = 1L;
public ECLPSUpdate(haus.nightmare.lib3270j.ecl.ECLPS ps, int startRow, int startCol,
int endRow, int endCol, int start, int end, boolean fullUpdate, String text) {
super(ps, startRow, startCol, endRow, endCol, start, end, fullUpdate, text);
}
public ECLPSUpdate(int startRow, int startCol, int endRow, int endCol, boolean fullUpdate) {
super(startRow, startCol, endRow, endCol, fullUpdate);
}
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLScreenNotify.
*/
public interface ECLScreenNotify extends haus.nightmare.lib3270j.ecl.ECLScreenNotify {
}
@@ -0,0 +1,19 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLScreenReco.
*/
public class ECLScreenReco extends haus.nightmare.lib3270j.ecl.ECLScreenReco {
public ECLScreenReco() {
super();
}
public ECLScreenReco(haus.nightmare.lib3270j.ecl.ECLSession session) {
super(session);
}
public ECLScreenReco(haus.nightmare.lib3270j.ecl.ECLPS ps) {
super(ps);
}
}
@@ -0,0 +1,13 @@
package haus.nightmare.lib3270j.eNetwork.ECL;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLScreenRecoEvent.
*/
public class ECLScreenRecoEvent extends haus.nightmare.lib3270j.ecl.ECLScreenRecoEvent {
public ECLScreenRecoEvent(haus.nightmare.lib3270j.ecl.ECLScreenReco source,
haus.nightmare.lib3270j.ecl.ECLScreenDesc screenDesc,
haus.nightmare.lib3270j.ecl.ECLPS ps) {
super(source, screenDesc, ps);
}
}
@@ -0,0 +1,15 @@
package haus.nightmare.lib3270j.eNetwork.ECL.bidi;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
import haus.nightmare.lib3270j.telnet.TelnetFSM;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLOIABIDI.
*/
public class ECLOIABIDI extends haus.nightmare.lib3270j.ecl.ECLOIABIDI {
public ECLOIABIDI(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
super(screen, inputProcessor, fsm);
}
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL.event;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLOIANotify in event package.
*/
public interface ECLOIANotify extends haus.nightmare.lib3270j.ecl.ECLOIANotify {
}
@@ -1,5 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL.event;
import haus.nightmare.lib3270j.ecl.ECLPSUpdate;
/**
* IBM Host On-Demand ECLPSEvent compatibility class.
*/
@@ -7,6 +9,15 @@ public class ECLPSEvent extends haus.nightmare.lib3270j.ecl.ECLPSEvent {
private static final long serialVersionUID = 1L;
public ECLPSEvent(Object source, int eventType, int type, int startRow, int startCol,
int endRow, int endCol, int oldCursorAddress, int newCursorAddress,
int rows, int cols, boolean fullUpdate, boolean cursorVisible,
int ringCounter, boolean startPrinterBit, ECLPSUpdate psUpdate) {
super(source, eventType, type, startRow, startCol, endRow, endCol,
oldCursorAddress, newCursorAddress, rows, cols, fullUpdate,
cursorVisible, ringCounter, startPrinterBit, psUpdate);
}
public ECLPSEvent(Object source, int eventType, int startRow, int startCol, int endRow, int endCol,
int oldCursorAddress, int newCursorAddress, int rows, int cols, boolean fullUpdate) {
super(source, eventType, startRow, startCol, endRow, endCol, oldCursorAddress, newCursorAddress, rows, cols, fullUpdate);
@@ -0,0 +1,22 @@
package haus.nightmare.lib3270j.eNetwork.ECL.event;
import java.awt.Image;
import java.awt.Rectangle;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLPSGraphicsEvent.
*/
public class ECLPSGraphicsEvent extends haus.nightmare.lib3270j.ecl.ECLPSGraphicsEvent {
public ECLPSGraphicsEvent(haus.nightmare.lib3270j.ecl.ECLPS source, int id) {
super(source, id);
}
public ECLPSGraphicsEvent(haus.nightmare.lib3270j.ecl.ECLPS source, int id, Image image) {
super(source, id, image);
}
public ECLPSGraphicsEvent(haus.nightmare.lib3270j.ecl.ECLPS source, int id, Image image, Rectangle rectangle) {
super(source, id, image, rectangle);
}
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL.event;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLPSGraphicsListener.
*/
public interface ECLPSGraphicsListener extends haus.nightmare.lib3270j.ecl.ECLPSGraphicsListener {
}
@@ -0,0 +1,15 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hindi;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
import haus.nightmare.lib3270j.telnet.TelnetFSM;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLOIAHindi.
*/
public class ECLOIAHindi extends haus.nightmare.lib3270j.ecl.ECLOIAHindi {
public ECLOIAHindi(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
super(screen, inputProcessor, fsm);
}
}
@@ -0,0 +1,10 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
/**
* Drop-in IBM Host On-Demand compatible facade for Edge.
*/
public class Edge extends haus.nightmare.lib3270j.graphics.Edge {
public Edge(int x1, int y1, int x2, int y2) {
super(x1, y1, x2, y2);
}
}
@@ -0,0 +1,20 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
import java.awt.Color;
/**
* Drop-in IBM Host On-Demand compatible facade for FillArea.
*/
public class FillArea extends haus.nightmare.lib3270j.graphics.FillArea {
public FillArea() {
super();
}
public FillArea(int fillRule) {
super(fillRule);
}
public FillArea(int[] px, int[] py, int[] polyCounts, int numPolys, Color color) {
super(px, py, polyCounts, numPolys, color);
}
}
@@ -0,0 +1,10 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
/**
* Drop-in IBM Host On-Demand compatible facade for FilletPts.
*/
public class FilletPts extends haus.nightmare.lib3270j.graphics.FilletPts {
public FilletPts() {
super();
}
}
@@ -0,0 +1,12 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
import java.awt.Component;
/**
* Drop-in IBM Host On-Demand compatible facade for HODBitImage.
*/
public class HODBitImage extends haus.nightmare.lib3270j.graphics.HODBitImage {
public HODBitImage(Component comp, int width, int height, byte[] data, int baseColor, int depth, boolean useGraphicColors) {
super(comp, width, height, data, baseColor, depth, useGraphicColors);
}
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
/**
* Drop-in IBM Host On-Demand compatible facade for HODBounds.
*/
public class HODBounds extends haus.nightmare.lib3270j.graphics.HODBounds {
}
@@ -0,0 +1,10 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
/**
* Drop-in IBM Host On-Demand compatible facade for HODColorChangeFilter.
*/
public class HODColorChangeFilter extends haus.nightmare.lib3270j.graphics.HODColorChangeFilter {
public HODColorChangeFilter(int color) {
super(color);
}
}
@@ -0,0 +1,20 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
import haus.nightmare.lib3270j.graphics.GraphicsPlane;
/**
* Drop-in IBM Host On-Demand compatible facade for HODGraphicsPlane.
*/
public class HODGraphicsPlane extends haus.nightmare.lib3270j.graphics.HODGraphicsPlane {
public HODGraphicsPlane() {
super();
}
public HODGraphicsPlane(int width, int height) {
super(width, height);
}
public HODGraphicsPlane(GraphicsPlane delegate) {
super(delegate);
}
}
@@ -0,0 +1,30 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Rectangle;
/**
* Drop-in IBM Host On-Demand compatible facade for HODPart.
*/
public class HODPart extends haus.nightmare.lib3270j.graphics.HODPart {
public HODPart() {
super();
}
public HODPart(Component component) {
super(component);
}
public HODPart(Component component, Dimension dimension) {
super(component, dimension);
}
public HODPart(Component component, Rectangle rectangle) {
super(component, rectangle);
}
public HODPart(HODPart hODPart) {
super(hODPart);
}
}
@@ -0,0 +1,16 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
import haus.nightmare.lib3270j.graphics.ProgramSymbolManager;
/**
* Drop-in IBM Host On-Demand compatible facade for HODProgramSymbolManager.
*/
public class HODProgramSymbolManager extends haus.nightmare.lib3270j.graphics.HODProgramSymbolManager {
public HODProgramSymbolManager() {
super();
}
public HODProgramSymbolManager(ProgramSymbolManager delegate) {
super(delegate);
}
}
@@ -0,0 +1,10 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
/**
* Drop-in IBM Host On-Demand compatible facade for HODTransform.
*/
public class HODTransform extends haus.nightmare.lib3270j.graphics.HODTransform {
public HODTransform(int charW, int charH, int defaultCharW, int defaultCharH) {
super(charW, charH, defaultCharW, defaultCharH);
}
}
@@ -0,0 +1,10 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
/**
* Drop-in IBM Host On-Demand compatible facade for HODTransparentColorFilter.
*/
public class HODTransparentColorFilter extends haus.nightmare.lib3270j.graphics.HODTransparentColorFilter {
public HODTransparentColorFilter(int transparentColor) {
super(transparentColor);
}
}
@@ -0,0 +1,20 @@
package haus.nightmare.lib3270j.eNetwork.ECL.hostgraphics;
import java.awt.Image;
/**
* Drop-in IBM Host On-Demand compatible facade for HODWallpaper.
*/
public class HODWallpaper extends haus.nightmare.lib3270j.graphics.HODWallpaper {
public HODWallpaper() {
super();
}
public HODWallpaper(int displayMode) {
super(displayMode);
}
public HODWallpaper(Image image, int displayMode) {
super(image, displayMode);
}
}
@@ -0,0 +1,15 @@
package haus.nightmare.lib3270j.eNetwork.ECL.thai;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
import haus.nightmare.lib3270j.telnet.TelnetFSM;
/**
* Drop-in IBM Host On-Demand compatible facade for ECLOIATHAI.
*/
public class ECLOIATHAI extends haus.nightmare.lib3270j.ecl.ECLOIATHAI {
public ECLOIATHAI(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
super(screen, inputProcessor, fsm);
}
}
@@ -0,0 +1,29 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.datastream.DataStreamProcessor;
import haus.nightmare.lib3270j.ecl.ECLPS;
import haus.nightmare.lib3270j.ecl.ECLSession;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270.DS3270.
*/
public class DS3270 extends haus.nightmare.lib3270j.tn3270.DS3270 {
public DS3270() {
super();
}
public DS3270(ScreenBuffer screen, EbcdicTranslator translator) {
super(screen, translator);
}
public DS3270(DataStreamProcessor delegate) {
super(delegate);
}
public DS3270(ECLSession session, ECLPS ps) {
super(session, ps);
}
}
@@ -0,0 +1,23 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270;
import haus.nightmare.lib3270j.ecl.ECLPS;
import haus.nightmare.lib3270j.ecl.ECLSession;
import haus.nightmare.lib3270j.nvt.NvtProcessor;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270.NVT3270.
*/
public class NVT3270 extends haus.nightmare.lib3270j.tn3270.NVT3270 {
public NVT3270() {
super();
}
public NVT3270(NvtProcessor nvtProcessor) {
super(nvtProcessor);
}
public NVT3270(String host, ECLSession session, ECLPS ps, haus.nightmare.lib3270j.tn3270.DS3270 ds) {
super(host, session, ps, ds);
}
}
@@ -0,0 +1,24 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.ecl.ECLSession;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270.PS3270.
*/
public class PS3270 extends haus.nightmare.lib3270j.tn3270.PS3270 {
public PS3270() {
super();
}
public PS3270(ECLSession session) {
super(session);
}
public PS3270(ScreenBuffer screen, InputProcessor inputProcessor, EbcdicTranslator translator) {
super(screen, inputProcessor, translator);
}
}
@@ -0,0 +1,24 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270;
import haus.nightmare.lib3270j.ecl.ECLPS;
import haus.nightmare.lib3270j.ecl.ECLSession;
import haus.nightmare.lib3270j.telnet.TelnetConnection;
import haus.nightmare.lib3270j.telnet.TelnetFSM;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270.Telnet3270E.
*/
public class Telnet3270E extends haus.nightmare.lib3270j.tn3270.Telnet3270E {
public Telnet3270E() {
super();
}
public Telnet3270E(TelnetFSM fsm, TelnetConnection connection) {
super(fsm, connection);
}
public Telnet3270E(String host, ECLSession session, ECLPS ps, haus.nightmare.lib3270j.tn3270.DS3270 ds) {
super(host, session, ps, ds);
}
}
@@ -0,0 +1,19 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270.qr_elem.
*/
public class qr_elem extends haus.nightmare.lib3270j.tn3270.qr_elem {
public qr_elem() {
super();
}
public qr_elem(int type, int sendFlag) {
super(type, sendFlag);
}
public qr_elem(byte type, byte sendFlag) {
super(type, sendFlag);
}
}
@@ -0,0 +1,31 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.printer.PD3270;
import haus.nightmare.lib3270j.printer.PrintPS3270;
import haus.nightmare.lib3270j.printer.PrintSCS3270;
import haus.nightmare.lib3270j.printer.PrinterConfig;
import haus.nightmare.lib3270j.printer.Telnet3270EP;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.DS3270P.
*/
public class DS3270P extends haus.nightmare.lib3270j.printer.DS3270P {
public DS3270P() {
super();
}
public DS3270P(PrinterConfig config) {
super(config);
}
public DS3270P(PrinterConfig config, PD3270 pd, EbcdicTranslator translator) {
super(config, pd, translator);
}
public DS3270P(Telnet3270EP telnet, PrinterConfig config, PD3270 pd,
PrintSCS3270 scs, PrintPS3270 printPs, EbcdicTranslator translator) {
super(telnet, config, pd, scs, printPs, translator);
}
}
@@ -0,0 +1,17 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.printer.PrinterConfig;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.PD3270.
*/
public class PD3270 extends haus.nightmare.lib3270j.printer.PD3270 {
public PD3270() {
super();
}
public PD3270(PrinterConfig config) {
super(config);
}
}
@@ -0,0 +1,11 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.PDT.
*/
public class PDT extends PrinterDefinitionTable {
public PDT(String name, String description) {
super(name, description);
}
}
@@ -0,0 +1,15 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.printer.PD3270;
import haus.nightmare.lib3270j.printer.PrinterConfig;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.PrintPS3270.
*/
public class PrintPS3270 extends haus.nightmare.lib3270j.printer.PrintPS3270 {
public PrintPS3270(PrinterConfig config, PD3270 pd, EbcdicTranslator translator) {
super(config, pd, translator);
}
}
@@ -0,0 +1,19 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.printer.PD3270;
import haus.nightmare.lib3270j.printer.PrinterConfig;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.PrintPS3270DB.
*/
public class PrintPS3270DB extends haus.nightmare.lib3270j.printer.PrintPS3270DB {
public PrintPS3270DB(PrinterConfig config) {
super(config);
}
public PrintPS3270DB(PrinterConfig config, PD3270 pd, EbcdicTranslator translator) {
super(config, pd, translator);
}
}
@@ -0,0 +1,15 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.printer.PD3270;
import haus.nightmare.lib3270j.printer.PrinterConfig;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.PrintSCS3270.
*/
public class PrintSCS3270 extends haus.nightmare.lib3270j.printer.PrintSCS3270 {
public PrintSCS3270(PrinterConfig config, PD3270 pd, EbcdicTranslator translator) {
super(config, pd, translator);
}
}
@@ -0,0 +1,19 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.printer.PD3270;
import haus.nightmare.lib3270j.printer.PrinterConfig;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.PrintSCS3270DB.
*/
public class PrintSCS3270DB extends haus.nightmare.lib3270j.printer.PrintSCS3270DB {
public PrintSCS3270DB(PrinterConfig config) {
super(config);
}
public PrintSCS3270DB(PrinterConfig config, PD3270 pd, EbcdicTranslator translator) {
super(config, pd, translator);
}
}
@@ -0,0 +1,11 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.PrinterDefinitionTable.
*/
public class PrinterDefinitionTable extends haus.nightmare.lib3270j.printer.PrinterDefinitionTable {
public PrinterDefinitionTable(String name, String description) {
super(name, description);
}
}
@@ -0,0 +1,19 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.printer.PD3270;
import haus.nightmare.lib3270j.printer.PrinterConfig;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.Telnet3270EP.
*/
public class Telnet3270EP extends haus.nightmare.lib3270j.printer.Telnet3270EP {
public Telnet3270EP(PrinterConfig config) {
super(config);
}
public Telnet3270EP(PrinterConfig config, PD3270 pd, EbcdicTranslator translator) {
super(config, pd, translator);
}
}
@@ -0,0 +1,29 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
import haus.nightmare.lib3270j.printer.TimerListener;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.Timer.
*/
public class Timer extends haus.nightmare.lib3270j.printer.Timer {
public Timer() {
super();
}
public Timer(long intervalMs) {
super(intervalMs);
}
public Timer(long intervalMs, TimerListener listener) {
super(intervalMs, listener);
}
public Timer(long intervalMs, TimerListener listener, boolean repeating) {
super(intervalMs, listener, repeating);
}
public Timer(long intervalMs, TimerListener listener, boolean repeating, String timerId) {
super(intervalMs, listener, repeating, timerId);
}
}
@@ -0,0 +1,21 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.TimerEvent.
*/
public class TimerEvent extends haus.nightmare.lib3270j.printer.TimerEvent {
private static final long serialVersionUID = 1L;
public TimerEvent(Object source) {
super(source);
}
public TimerEvent(Object source, String timerId) {
super(source, timerId);
}
public TimerEvent(Object source, String timerId, long timestamp) {
super(source, timerId, timestamp);
}
}
@@ -0,0 +1,7 @@
package haus.nightmare.lib3270j.eNetwork.ECL.tn3270p;
/**
* Drop-in IBM Host On-Demand compatible facade for com.ibm.eNetwork.ECL.tn3270p.TimerListener.
*/
public interface TimerListener extends haus.nightmare.lib3270j.printer.TimerListener {
}
@@ -0,0 +1,34 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
import haus.nightmare.lib3270j.ft.FTConfig;
/**
* Drop-in IBM Host On-Demand compatibility class for
* com.ibm.eNetwork.ECL.xfer.FileTransferFileObject.
*/
public class FileTransferFileObject extends haus.nightmare.lib3270j.xfer.FileTransferFileObject {
public FileTransferFileObject() {
super();
}
public FileTransferFileObject(String name) {
super(name);
}
public FileTransferFileObject(String name, long size) {
super(name, size);
}
public FileTransferFileObject(String name, long size, boolean isDirectory) {
super(name, size, isDirectory);
}
public FileTransferFileObject(String localFile, String hostDatasetName) {
super(localFile, hostDatasetName);
}
public FileTransferFileObject(FTConfig config) {
super(config);
}
}
@@ -0,0 +1,8 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
/**
* Drop-in IBM Host On-Demand compatibility interface for
* com.ibm.eNetwork.ECL.xfer.FileTransferHostDirectoryInterface.
*/
public interface FileTransferHostDirectoryInterface extends haus.nightmare.lib3270j.xfer.FileTransferHostDirectoryInterface {
}
@@ -0,0 +1,8 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
/**
* Drop-in IBM Host On-Demand compatibility interface for
* com.ibm.eNetwork.ECL.xfer.FileTransferInterface.
*/
public interface FileTransferInterface extends haus.nightmare.lib3270j.xfer.FileTransferInterface {
}
@@ -0,0 +1,8 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
/**
* Drop-in IBM Host On-Demand compatibility interface for
* com.ibm.eNetwork.ECL.xfer.FileTransferStatusInterface.
*/
public interface FileTransferStatusInterface extends haus.nightmare.lib3270j.xfer.FileTransferStatusInterface {
}
@@ -0,0 +1,27 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
import java.io.File;
import java.io.FileNotFoundException;
/**
* Drop-in IBM Host On-Demand compatibility class for
* com.ibm.eNetwork.ECL.xfer.XferFileInputStream.
*/
public class XferFileInputStream extends haus.nightmare.lib3270j.xfer.XferFileInputStream {
public XferFileInputStream(String name, boolean nonIbmText, byte[] nonIbmTerminator, boolean asciiTransfer) throws FileNotFoundException {
super(name, nonIbmText, nonIbmTerminator, asciiTransfer);
}
public XferFileInputStream(File file, boolean nonIbmText, byte[] nonIbmTerminator, boolean asciiTransfer) throws FileNotFoundException {
super(file, nonIbmText, nonIbmTerminator, asciiTransfer);
}
public XferFileInputStream(String name, byte[] terminators) throws FileNotFoundException {
super(name, terminators);
}
public XferFileInputStream(File file, byte[] terminators) throws FileNotFoundException {
super(file, terminators);
}
}
@@ -0,0 +1,25 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
import haus.nightmare.lib3270j.charset.CodePage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
/**
* Drop-in IBM Host On-Demand compatibility class for
* com.ibm.eNetwork.ECL.xfer.XferFileInputUnicode.
*/
public class XferFileInputUnicode extends haus.nightmare.lib3270j.xfer.XferFileInputUnicode {
public XferFileInputUnicode(String filename, byte[] terminators, CodePage cp,
int unicodeType, int sessionType, boolean noso)
throws FileNotFoundException, UnsupportedEncodingException {
super(filename, terminators, cp, unicodeType, sessionType, noso);
}
public XferFileInputUnicode(File file, byte[] terminators, CodePage cp,
int unicodeType, int sessionType, boolean noso)
throws FileNotFoundException, UnsupportedEncodingException {
super(file, terminators, cp, unicodeType, sessionType, noso);
}
}
@@ -0,0 +1,27 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
import java.io.File;
import java.io.FileNotFoundException;
/**
* Drop-in IBM Host On-Demand compatibility class for
* com.ibm.eNetwork.ECL.xfer.XferFileOutputStream.
*/
public class XferFileOutputStream extends haus.nightmare.lib3270j.xfer.XferFileOutputStream {
public XferFileOutputStream(String name, boolean nonIbmText, byte[] nonIbmTerminator, boolean asciiTransfer) throws FileNotFoundException {
super(name, nonIbmText, nonIbmTerminator, asciiTransfer);
}
public XferFileOutputStream(File file, boolean nonIbmText, byte[] nonIbmTerminator, boolean asciiTransfer) throws FileNotFoundException {
super(file, nonIbmText, nonIbmTerminator, asciiTransfer);
}
public XferFileOutputStream(String name, boolean append, boolean nonIbmText, byte[] nonIbmTerminator, boolean asciiTransfer) throws FileNotFoundException {
super(name, append, nonIbmText, nonIbmTerminator, asciiTransfer);
}
public XferFileOutputStream(File file, boolean append, boolean nonIbmText, byte[] nonIbmTerminator, boolean asciiTransfer) throws FileNotFoundException {
super(file, append, nonIbmText, nonIbmTerminator, asciiTransfer);
}
}
@@ -0,0 +1,27 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer;
import haus.nightmare.lib3270j.charset.CodePage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
/**
* Drop-in IBM Host On-Demand compatibility class for
* com.ibm.eNetwork.ECL.xfer.XferFileOutputUnicode.
*/
public class XferFileOutputUnicode extends haus.nightmare.lib3270j.xfer.XferFileOutputUnicode {
public XferFileOutputUnicode(String filename, boolean append, byte[] terminators,
boolean asciiTransfer, CodePage cp, int unicodeType,
boolean soFlag, boolean soAlt)
throws FileNotFoundException, UnsupportedEncodingException {
super(filename, append, terminators, asciiTransfer, cp, unicodeType, soFlag, soAlt);
}
public XferFileOutputUnicode(File file, boolean append, byte[] terminators,
boolean asciiTransfer, CodePage cp, int unicodeType,
boolean soFlag, boolean soAlt)
throws FileNotFoundException, UnsupportedEncodingException {
super(file, append, terminators, asciiTransfer, cp, unicodeType, soFlag, soAlt);
}
}
@@ -0,0 +1,27 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer3270;
import haus.nightmare.lib3270j.charset.EbcdicTranslator;
import haus.nightmare.lib3270j.ecl.ECLXfer;
/**
* Drop-in IBM Host On-Demand compatibility class for
* com.ibm.eNetwork.ECL.xfer3270.CMSPrintXfer.
*/
public class CMSPrintXfer extends haus.nightmare.lib3270j.xfer3270.CMSPrintXfer {
public CMSPrintXfer() {
super();
}
public CMSPrintXfer(ECLXfer xfer) {
super(xfer);
}
public CMSPrintXfer(ECLXfer xfer, EbcdicTranslator translator) {
super(xfer, translator);
}
public CMSPrintXfer(Xfer3270 xfer3270) {
super(xfer3270);
}
}
@@ -0,0 +1,37 @@
package haus.nightmare.lib3270j.eNetwork.ECL.xfer3270;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.datastream.DataStreamProcessor;
import haus.nightmare.lib3270j.ecl.ECLSession;
import haus.nightmare.lib3270j.ecl.ECLXfer;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
import java.net.URL;
/**
* Drop-in IBM Host On-Demand compatibility class for
* com.ibm.eNetwork.ECL.xfer3270.Xfer3270.
*/
public class Xfer3270 extends haus.nightmare.lib3270j.xfer3270.Xfer3270 {
public Xfer3270() {
super();
}
public Xfer3270(ECLSession session) {
super(session);
}
public Xfer3270(ECLSession session, URL url) {
super(session, url);
}
public Xfer3270(ECLXfer xfer) {
super(xfer);
}
public Xfer3270(ScreenBuffer screen, InputProcessor input,
DataStreamProcessor dsProcessor, CodePage codePage) {
super(screen, input, dsProcessor, codePage);
}
}
@@ -0,0 +1,28 @@
package haus.nightmare.lib3270j.eNetwork.HOD.common;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.converters.HODUnsupportedCodepageException;
/**
* IBM Host On-Demand drop-in compatibility facade for HODByteToCharConverter.
*/
public abstract class HODByteToCharConverter extends haus.nightmare.lib3270j.converters.HODByteToCharConverter {
public HODByteToCharConverter() {
super();
}
public HODByteToCharConverter(CodePage codePage) {
super(codePage);
}
public static haus.nightmare.lib3270j.converters.HODByteToCharConverter getHODConverter(String encoding)
throws HODUnsupportedCodepageException {
return haus.nightmare.lib3270j.converters.HODByteToCharConverter.getHODConverter(encoding);
}
public static haus.nightmare.lib3270j.converters.HODByteToCharConverter getConverter(String encoding)
throws HODUnsupportedCodepageException {
return haus.nightmare.lib3270j.converters.HODByteToCharConverter.getConverter(encoding);
}
}
@@ -0,0 +1,17 @@
package haus.nightmare.lib3270j.eNetwork.HOD.common;
/**
* IBM Host On-Demand drop-in compatibility facade for HODCharConversionException.
*/
public class HODCharConversionException extends haus.nightmare.lib3270j.converters.HODCharConversionException {
private static final long serialVersionUID = 1L;
public HODCharConversionException() {
super();
}
public HODCharConversionException(String message) {
super(message);
}
}
@@ -0,0 +1,28 @@
package haus.nightmare.lib3270j.eNetwork.HOD.common;
import haus.nightmare.lib3270j.charset.CodePage;
import haus.nightmare.lib3270j.converters.HODUnsupportedCodepageException;
/**
* IBM Host On-Demand drop-in compatibility facade for HODCharToByteConverter.
*/
public abstract class HODCharToByteConverter extends haus.nightmare.lib3270j.converters.HODCharToByteConverter {
public HODCharToByteConverter() {
super();
}
public HODCharToByteConverter(CodePage codePage) {
super(codePage);
}
public static haus.nightmare.lib3270j.converters.HODCharToByteConverter getHODConverter(String encoding)
throws HODUnsupportedCodepageException {
return haus.nightmare.lib3270j.converters.HODCharToByteConverter.getHODConverter(encoding);
}
public static haus.nightmare.lib3270j.converters.HODCharToByteConverter getConverter(String encoding)
throws HODUnsupportedCodepageException {
return haus.nightmare.lib3270j.converters.HODCharToByteConverter.getConverter(encoding);
}
}
@@ -0,0 +1,17 @@
package haus.nightmare.lib3270j.eNetwork.HOD.common;
/**
* IBM Host On-Demand drop-in compatibility facade for HODUnsupportedCodepageException.
*/
public class HODUnsupportedCodepageException extends haus.nightmare.lib3270j.converters.HODUnsupportedCodepageException {
private static final long serialVersionUID = 1L;
public HODUnsupportedCodepageException() {
super();
}
public HODUnsupportedCodepageException(String encoding) {
super(encoding);
}
}
@@ -0,0 +1,33 @@
package haus.nightmare.lib3270j.eNetwork.security.ssl;
import haus.nightmare.lib3270j.ConnectionConfig;
import haus.nightmare.lib3270j.ecl.ECLConnection;
import haus.nightmare.lib3270j.ecl.ECLSession;
import java.util.Properties;
/**
* IBM Host On-Demand (HoD) canonical package compatibility drop-in facade for
* com.ibm.eNetwork.security.ssl.HODSSLECLSessionImpl.
*/
public class HODSSLECLSessionImpl extends haus.nightmare.lib3270j.security.ssl.HODSSLECLSessionImpl {
public HODSSLECLSessionImpl() {
super();
}
public HODSSLECLSessionImpl(ConnectionConfig config) {
super(config);
}
public HODSSLECLSessionImpl(ECLSession session) {
super(session);
}
public HODSSLECLSessionImpl(ECLConnection connection) {
super(connection);
}
public HODSSLECLSessionImpl(Properties props) {
super(props);
}
}
@@ -0,0 +1,131 @@
package haus.nightmare.lib3270j.ecl;
/**
* Standard implementation of ECLPSBIDIServices conforming to IBM Host On-Demand ECL.
*/
public class DefaultPSBIDIServices implements ECLPSBIDIServices {
private final ECLPS ps;
private String numeralShape = NOMINAL;
private String textType = VISUAL;
private String textOrientation = LEFT_TO_RIGHT;
private String roundTrip = ROUNDTRIP_OFF;
private String lamAlef = LAMALEF_ON;
private String rtlUnicode = RTLUNICODE_ON;
private boolean macroBidiEnabled = false;
private boolean numericSwap = false;
private boolean symmetricSwap = false;
public DefaultPSBIDIServices(ECLPS ps) {
this.ps = ps;
}
@Override
public void SetNumeralShape(String shape) throws ECLErr {
this.numeralShape = shape != null ? shape : NOMINAL;
}
@Override
public String GetNumeralShape() {
return numeralShape;
}
@Override
public void SetTextType(String type) throws ECLErr {
this.textType = type != null ? type : VISUAL;
}
@Override
public String GetTextType() {
return textType;
}
@Override
public void SetTextOrientation(String orientation) throws ECLErr {
this.textOrientation = orientation != null ? orientation : LEFT_TO_RIGHT;
}
@Override
public String GetTextOrientation() {
return textOrientation;
}
@Override
public void setMacroBidiEnabled(boolean enabled) {
this.macroBidiEnabled = enabled;
}
@Override
public boolean isMacroBidiEnabled() {
return macroBidiEnabled;
}
@Override
public void SetRoundTrip(String rt) throws ECLErr {
this.roundTrip = rt != null ? rt : ROUNDTRIP_OFF;
}
@Override
public String GetRoundTrip() {
return roundTrip;
}
@Override
public void SetBIDICursorPos(int pos, boolean visual) throws ECLErr {
if (ps != null) {
ps.setCursorPos(pos - 1);
}
}
@Override
public void SetBIDICursorPos(int pos) throws ECLErr {
SetBIDICursorPos(pos, false);
}
@Override
public void SetBIDICursorPos(int row, int col) throws ECLErr {
if (ps != null) {
ps.setCursorPos(row - 1, col - 1);
}
}
@Override
public void SetLamAlef(String mode) throws ECLErr {
this.lamAlef = mode != null ? mode : LAMALEF_ON;
}
@Override
public String GetLamAlef() {
return lamAlef;
}
@Override
public void SetRTLUnicode(String mode) throws ECLErr {
this.rtlUnicode = mode != null ? mode : RTLUNICODE_ON;
}
@Override
public String GetRTLUnicode() {
return rtlUnicode;
}
@Override
public void setNumericSwap(boolean swap) {
this.numericSwap = swap;
}
@Override
public boolean getNumericSwap() {
return numericSwap;
}
@Override
public void setSymmetricSwap(boolean swap) {
this.symmetricSwap = swap;
}
@Override
public boolean getSymmetricSwap() {
return symmetricSwap;
}
}
@@ -0,0 +1,73 @@
package haus.nightmare.lib3270j.ecl;
import java.awt.Color;
import java.awt.Component;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* Standard implementation of ECLPSGraphicsServices conforming to IBM Host On-Demand ECL.
*/
public class DefaultPSGraphicsServices implements ECLPSGraphicsServices {
private final ECLPS ps;
private Component visualComponent;
private Color[] colors;
private final List<ECLPSGraphicsListener> listeners = new CopyOnWriteArrayList<>();
public DefaultPSGraphicsServices(ECLPS ps) {
this.ps = ps;
}
@Override
public void setVisualComponent(Component comp) {
this.visualComponent = comp;
}
public Component getVisualComponent() {
return visualComponent;
}
@Override
public void setGraphicColor(Color[] colors, boolean b) {
this.colors = (colors != null) ? colors.clone() : null;
}
public Color[] getGraphicColors() {
return (colors != null) ? colors.clone() : null;
}
@Override
public void mousePressed(int x, int y, int button) {
if (ps != null && ps.getInputProcessor() != null) {
ps.getInputProcessor().sendGraphicMouseAid(x, y, button == 1, false);
}
ECLPSGraphicsEvent event = new ECLPSGraphicsEvent(ps, ECLPSGraphicsEvent.GRAPHICS_UPDATED);
for (ECLPSGraphicsListener l : listeners) {
try {
l.graphicsUpdated(event);
} catch (Exception ignored) {}
}
}
@Override
public void addGraphicsListener(ECLPSGraphicsListener listener) {
if (listener != null && !listeners.contains(listener)) {
listeners.add(listener);
}
}
@Override
public void removeGraphicsListener(ECLPSGraphicsListener listener) {
listeners.remove(listener);
}
public void fireGraphicsEvent(int id) {
ECLPSGraphicsEvent event = new ECLPSGraphicsEvent(ps, id);
for (ECLPSGraphicsListener l : listeners) {
try {
l.graphicsEvent(event);
} catch (Exception ignored) {}
}
}
}
@@ -0,0 +1,33 @@
package haus.nightmare.lib3270j.ecl;
/**
* Standard implementation of ECLPSHindiServices conforming to IBM Host On-Demand ECL.
*/
public class DefaultPSHindiServices implements ECLPSHindiServices {
private final ECLPS ps;
public DefaultPSHindiServices(ECLPS ps) {
this.ps = ps;
}
@Override
public int GetHindiCursorCol(int row, int col) {
return col;
}
@Override
public byte GetHindiCursorLevel(int row, int col) {
return 0;
}
@Override
public int GetNormalCursorCol(int row, int col) {
return col;
}
@Override
public void switchToHindiLayer() {
// Layer switch stub
}
}
@@ -0,0 +1,39 @@
package haus.nightmare.lib3270j.ecl;
/**
* Standard implementation of ECLPSTHAIServices conforming to IBM Host On-Demand ECL.
*/
public class DefaultPSTHAIServices implements ECLPSTHAIServices {
private final ECLPS ps;
private int displayMode = 0;
public DefaultPSTHAIServices(ECLPS ps) {
this.ps = ps;
}
@Override
public void SetThaiDisplayMode(int mode) throws ECLErr {
this.displayMode = mode;
}
@Override
public int GetThaiDisplayMode() {
return displayMode;
}
@Override
public int GetThaiCursorCol(int row, int col) {
return col;
}
@Override
public byte GetThaiCursorLevel(int row, int col) {
return 0;
}
@Override
public int GetNormalCursorCol(int row, int col) {
return col;
}
}
@@ -5,6 +5,7 @@ import java.util.EventObject;
/**
* Event object dispatched on communication lifecycle and state transitions.
* Conforms 1:1 to IBM Host On-Demand ECLCommEvent specification.
*/
public class ECLCommEvent extends EventObject {
@@ -35,35 +36,60 @@ public class ECLCommEvent extends EventObject {
public ECLCommEvent(Object source, int eventType, ConnectionState oldState, ConnectionState newState,
String message, String deviceType, String deviceName) {
super(source);
super(source != null ? source : "ECLConnection");
this.eventType = eventType;
this.oldState = oldState;
this.newState = newState;
this.message = message;
this.deviceType = deviceType;
this.deviceName = deviceName;
this.message = message != null ? message : "";
this.deviceType = deviceType != null ? deviceType : "";
this.deviceName = deviceName != null ? deviceName : "";
}
public int getEventType() { return eventType; }
public int GetType() { return eventType; }
public int getType() { return eventType; }
public ConnectionState getOldState() { return oldState; }
public ConnectionState GetOldState() { return oldState; }
public ConnectionState getNewState() { return newState; }
public ConnectionState GetNewState() { return newState; }
public String getMessage() { return message; }
public String GetMessage() { return message; }
public String getErrorMessage() { return message; }
public String GetErrorMessage() { return message; }
public String getDeviceType() { return deviceType; }
public String GetDeviceType() { return deviceType; }
public String getDeviceName() { return deviceName; }
public String GetDeviceName() { return deviceName; }
public String getLUName() { return deviceName; }
public String GetLUName() { return deviceName; }
public boolean isConnected() {
return newState != null && newState.isConnected();
}
public boolean IsConnected() {
return isConnected();
}
public boolean isFullSession() {
return newState != null && newState.isFullSession();
}
public boolean IsFullSession() {
return isFullSession();
}
public ECLConnection getConnection() {
return (getSource() instanceof ECLConnection) ? (ECLConnection) getSource() : null;
}
public ECLConnection GetConnection() {
return getConnection();
}
@Override
public String toString() {
@@ -2,14 +2,39 @@ package haus.nightmare.lib3270j.ecl;
/**
* Listener interface for communication lifecycle events.
* Conforms 1:1 to IBM Host On-Demand ECLCommListener specification.
*/
public interface ECLCommListener {
/**
* Primary HoD notification callback invoked when connection state changes.
* @param event ECLCommEvent containing transition details
*/
default void CommNotifyEvent(ECLCommEvent event) {
commEvent(event);
}
/**
* Called when an error condition occurs on the connection.
* @param conn ECLConnection instance
* @param err ECLErr error descriptor
*/
default void CommNotifyError(ECLConnection conn, ECLErr err) {}
/**
* Called when communication event generation has stopped.
* @param conn ECLConnection instance
* @param reason Stop reason code
*/
default void CommNotifyStop(ECLConnection conn, int reason) {}
// ========== Backward-Compatibility Bridge Methods ==========
/**
* Called when the communication connection state or status changes.
* @param event ECLCommEvent containing transition details
*/
void commEvent(ECLCommEvent event);
default void commEvent(ECLCommEvent event) {}
/**
* Called specifically when the connection is established.
@@ -11,4 +11,26 @@ public interface ECLCommNotify {
* @param connected true if session is connected, false otherwise
*/
void CommNotify(boolean connected);
/**
* Optional event notification callback invoked on communication state change.
* @param event ECLCommEvent
*/
default void CommNotifyEvent(ECLCommEvent event) {
CommNotify(event != null && event.isConnected());
}
/**
* Optional error callback invoked on communication error.
* @param conn ECLConnection instance
* @param err ECLErr error descriptor
*/
default void CommNotifyError(ECLConnection conn, ECLErr err) {}
/**
* Optional stop callback invoked when communication event processing terminates.
* @param conn ECLConnection instance
* @param reason Stop reason code
*/
default void CommNotifyStop(ECLConnection conn, int reason) {}
}
@@ -7,6 +7,7 @@ import haus.nightmare.lib3270j.listener.ConnectionListener;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -19,6 +20,60 @@ public class ECLConnection {
private final List<ECLCommListener> commListeners = new CopyOnWriteArrayList<>();
private final List<ECLCommNotify> commNotifies = new CopyOnWriteArrayList<>();
private String host;
private int port = 23;
private String codePage;
private String deviceName;
private String luName;
private String workstationId = "";
private boolean ssl = false;
private boolean contentionResolution = false;
private boolean luluSession = false;
private boolean isNegCR = false;
private boolean isBIND7FArchitectureViolation = false;
private String keyRemap = "";
private String certificateName = "";
private String certificateSource = "";
private String certificateURL = "";
private String certificatePassword = "";
private boolean certificateProvided = false;
private String securityProtocol = "TLS";
private String tlsProtocolVersion = "TLSv1.2";
private boolean useJSSE = true;
private String jsseTrustStore = "";
private String jsseTrustStoreType = "JKS";
private String jsseTrustStorePassword = "";
private String proxyType = "";
private String proxyServerName = "";
private String proxyServerPort = "";
private String proxyUserId = "";
private String proxyUserPassword = "";
private String proxyAuthenMethod = "";
private String proxySecurityProtocol = "";
private Properties properties = new Properties();
public ECLConnection() {
this(null, null);
}
public ECLConnection(ECLSession session) {
this(session, session != null ? session.getClient() : null);
}
public ECLConnection(String host, int port) {
this(null, null);
this.host = host;
this.port = port;
}
public ECLConnection(Properties props) {
this(null, null);
if (props != null) {
this.properties.putAll(props);
convertData(this.properties);
}
}
public ECLConnection(ECLSession session, Telnet3270Client client) {
this.session = session;
this.client = client;
@@ -70,17 +125,20 @@ public class ECLConnection {
public Telnet3270Client getClient() { return client; }
public String GetHost() {
return (client != null && client.getConfig() != null) ? client.getConfig().getHost() : "";
if (client != null && client.getConfig() != null) return client.getConfig().getHost();
return host != null ? host : "";
}
public String getHost() { return GetHost(); }
public int GetPort() {
return (client != null && client.getConfig() != null) ? client.getConfig().getPort() : 23;
if (client != null && client.getConfig() != null) return client.getConfig().getPort();
return port;
}
public int getPort() { return GetPort(); }
public String GetCodePage() {
return (client != null) ? client.getCodePage() : "037";
if (client != null) return client.getCodePage();
return codePage != null ? codePage : "037";
}
public String getCodePage() { return GetCodePage(); }
@@ -93,7 +151,10 @@ public class ECLConnection {
if (client != null && client.getTelnetFSM() != null && client.getTelnetFSM().getConnectedLu() != null) {
return client.getTelnetFSM().getConnectedLu();
}
return (client != null && client.getConfig() != null) ? client.getConfig().getLuName() : null;
if (client != null && client.getConfig() != null && client.getConfig().getLuName() != null) {
return client.getConfig().getLuName();
}
return luName;
}
public String getLUName() { return GetLUName(); }
@@ -149,7 +210,8 @@ public class ECLConnection {
public boolean isDisconnecting() { return IsDisconnecting(); }
public boolean IsSSL() {
return client != null && client.getConfig() != null && client.getConfig().isUseTls();
if (client != null && client.getConfig() != null) return client.getConfig().isUseTls();
return ssl;
}
public boolean isSSL() { return IsSSL(); }
@@ -176,6 +238,10 @@ public class ECLConnection {
public void StopCommunication() { Disconnect(); }
public void stopCommunication() { Disconnect(); }
public static final int STOP_UNREGISTER = 1;
public static final int STOP_DISCONNECT = 2;
public static final int STOP_ERROR = 3;
// ========== Event Listener Management ==========
public void RegisterCommEvent(ECLCommListener listener) {
@@ -186,7 +252,12 @@ public class ECLConnection {
public void registerCommEvent(ECLCommListener listener) { RegisterCommEvent(listener); }
public void UnregisterCommEvent(ECLCommListener listener) {
commListeners.remove(listener);
if (listener != null) {
commListeners.remove(listener);
try {
listener.CommNotifyStop(this, STOP_UNREGISTER);
} catch (Exception ignored) {}
}
}
public void unregisterCommEvent(ECLCommListener listener) { UnregisterCommEvent(listener); }
@@ -198,30 +269,292 @@ public class ECLConnection {
public void registerCommEvent(ECLCommNotify notify, boolean sync) { RegisterCommEvent(notify, sync); }
public void UnregisterCommEvent(ECLCommNotify notify) {
commNotifies.remove(notify);
if (notify != null) {
commNotifies.remove(notify);
try {
notify.CommNotifyStop(this, STOP_UNREGISTER);
} catch (Exception ignored) {}
}
}
public void unregisterCommEvent(ECLCommNotify notify) { UnregisterCommEvent(notify); }
public void notifyCommError(ECLErr err) {
for (ECLCommListener l : commListeners) {
try {
l.CommNotifyError(this, err);
} catch (Exception ignored) {}
}
for (ECLCommNotify n : commNotifies) {
try {
n.CommNotifyError(this, err);
} catch (Exception ignored) {}
}
}
public void notifyCommStop(int reason) {
for (ECLCommListener l : commListeners) {
try {
l.CommNotifyStop(this, reason);
} catch (Exception ignored) {}
}
for (ECLCommNotify n : commNotifies) {
try {
n.CommNotifyStop(this, reason);
} catch (Exception ignored) {}
}
}
private void notifyCommEvent(ECLCommEvent event) {
for (ECLCommListener l : commListeners) {
try {
l.commEvent(event);
l.CommNotifyEvent(event);
if (event.getEventType() == ECLCommEvent.COMM_CONNECTED) {
l.commConnected(event);
} else if (event.getEventType() == ECLCommEvent.COMM_DISCONNECTED) {
l.commDisconnected(event);
} else if (event.getEventType() == ECLCommEvent.COMM_ERROR) {
l.commError(event);
l.CommNotifyError(this, new ECLErr("ECLConnection", "COMM0001", event.getMessage()));
}
} catch (Exception ignored) {}
}
for (ECLCommNotify n : commNotifies) {
try {
n.CommNotify(event.isConnected());
if (event.getEventType() == ECLCommEvent.COMM_ERROR) {
n.CommNotifyError(this, new ECLErr("ECLConnection", "COMM0001", event.getMessage()));
}
} catch (Exception ignored) {}
}
}
public void convertData(Properties properties) {
if (properties == null) return;
for (String key : properties.stringPropertyNames()) {
String val = properties.getProperty(key);
if (val != null) {
if ("true".equalsIgnoreCase(val)) {
properties.put(key, "1");
} else if ("false".equalsIgnoreCase(val)) {
properties.put(key, "0");
}
}
}
}
public void SetHost(String host) {
this.host = host;
if (client != null && client.getConfig() != null) {
client.getConfig().setHost(host);
}
}
public void setHost(String host) { SetHost(host); }
public void SetPort(int port) {
this.port = port;
if (client != null && client.getConfig() != null) {
client.getConfig().setPort(port);
}
}
public void setPort(int port) { SetPort(port); }
public void SetCodePage(String codePage) {
this.codePage = codePage;
if (client != null) {
client.setCodePage(codePage);
}
}
public void setCodePage(String codePage) { SetCodePage(codePage); }
public void SetDeviceName(String name) {
this.deviceName = name;
this.properties.put("deviceName", name != null ? name : "");
if (client != null && client.getConfig() != null) {
client.getConfig().setTerminalName(name);
}
}
public void setDeviceName(String name) { SetDeviceName(name); }
public String GetDeviceName() { return deviceName != null ? deviceName : GetLUName(); }
public String getDeviceName() { return GetDeviceName(); }
public void SetLUName(String lu) {
this.luName = lu;
if (client != null && client.getConfig() != null) {
client.getConfig().setLuName(lu);
}
}
public void setLUName(String lu) { SetLUName(lu); }
public void SetWorkstationID(String wid) { this.workstationId = wid; }
public void setWorkstationID(String wid) { SetWorkstationID(wid); }
public String GetWorkstationID() { return workstationId; }
public String getWorkstationID() { return workstationId; }
public void SetSSL(boolean ssl) {
this.ssl = ssl;
if (client != null && client.getConfig() != null) {
client.getConfig().setUseTls(ssl);
}
}
public void setSSL(boolean ssl) { SetSSL(ssl); }
public void setContentionResolution(boolean bl) { this.contentionResolution = bl; }
public void SetContentionResolution(boolean bl) { setContentionResolution(bl); }
public boolean getContentionResolution() { return contentionResolution; }
public boolean isContentionResolution() { return contentionResolution; }
public void set_LULU_Session(boolean bl) { this.luluSession = bl; }
public boolean is_LULU_Session() { return luluSession; }
public boolean get_LULU_Session() { return luluSession; }
public boolean isNegotiateCResolution() { return isNegCR; }
public void setNegotiatedCResolution(boolean bl) { this.isNegCR = bl; }
public boolean isBIND7FArchitectureViolation() { return isBIND7FArchitectureViolation; }
public void setBIND7FArchitectureViolation(boolean bl) { this.isBIND7FArchitectureViolation = bl; }
public void setKeyRemap(String remap) { this.keyRemap = remap; }
public void SetKeyRemap(String remap) { setKeyRemap(remap); }
public String getKeyRemap() { return keyRemap; }
public String GetKeyRemap() { return keyRemap; }
public void setCertificateName(String name) {
this.certificateName = name;
if (client != null && client.getConfig() != null) client.getConfig().setKeyStoreAlias(name);
}
public void SetCertificateName(String name) { setCertificateName(name); }
public String getCertificateName() { return certificateName; }
public String GetCertificateName() { return certificateName; }
public void setCertificateSource(String src) { this.certificateSource = src; }
public void SetCertificateSource(String src) { setCertificateSource(src); }
public String getCertificateSource() { return certificateSource; }
public String GetCertificateSource() { return certificateSource; }
public void setCertificateURL(String url) {
this.certificateURL = url;
if (client != null && client.getConfig() != null) client.getConfig().setKeyStorePath(url);
}
public void SetCertificateURL(String url) { setCertificateURL(url); }
public String getCertificateURL() { return certificateURL; }
public String GetCertificateURL() { return certificateURL; }
public void setCertificatePassword(String pwd) {
this.certificatePassword = pwd;
if (client != null && client.getConfig() != null) client.getConfig().setKeyStorePassword(pwd);
}
public void SetCertificatePassword(String pwd) { setCertificatePassword(pwd); }
public String getCertificatePassword() { return certificatePassword; }
public String GetCertificatePassword() { return certificatePassword; }
public void setCertificateProvided(boolean prov) { this.certificateProvided = prov; }
public void SetCertificateProvided(boolean prov) { setCertificateProvided(prov); }
public boolean isCertificateProvided() { return certificateProvided; }
public void setSecurityProtocol(String prot) {
this.securityProtocol = prot;
if (client != null && client.getConfig() != null) client.getConfig().setSslProtocol(prot);
}
public void SetSecurityProtocol(String prot) { setSecurityProtocol(prot); }
public String getSecurityProtocol() { return securityProtocol; }
public String GetSecurityProtocol() { return securityProtocol; }
public void setTLSProtocolVersion(String ver) {
this.tlsProtocolVersion = ver;
if (client != null && client.getConfig() != null && ver != null) {
client.getConfig().setSslProtocol(ver);
client.getConfig().setEnabledProtocols(ver);
}
}
public void SetTLSProtocolVersion(String ver) { setTLSProtocolVersion(ver); }
public String getTLSProtocolVersion() { return tlsProtocolVersion; }
public String GetTLSProtocolVersion() { return tlsProtocolVersion; }
public void setUseJSSE(boolean jsse) { this.useJSSE = jsse; }
public void SetUseJSSE(boolean jsse) { setUseJSSE(jsse); }
public boolean isUseJSSE() { return useJSSE; }
public void setJSSETrustStore(String ts) {
this.jsseTrustStore = ts;
if (client != null && client.getConfig() != null) client.getConfig().setTrustStorePath(ts);
}
public void SetJSSETrustStore(String ts) { setJSSETrustStore(ts); }
public String getJSSETrustStore() { return jsseTrustStore; }
public String GetJSSETrustStore() { return jsseTrustStore; }
public void setJSSETrustStoreType(String type) {
this.jsseTrustStoreType = type;
if (client != null && client.getConfig() != null) client.getConfig().setTrustStoreType(type);
}
public void SetJSSETrustStoreType(String type) { setJSSETrustStoreType(type); }
public String getJSSETrustStoreType() { return jsseTrustStoreType; }
public String GetJSSETrustStoreType() { return jsseTrustStoreType; }
public void setJSSETrustStorePassword(String pwd) {
this.jsseTrustStorePassword = pwd;
if (client != null && client.getConfig() != null) client.getConfig().setTrustStorePassword(pwd);
}
public void SetJSSETrustStorePassword(String pwd) { setJSSETrustStorePassword(pwd); }
public String getJSSETrustStorePassword() { return jsseTrustStorePassword; }
public String GetJSSETrustStorePassword() { return jsseTrustStorePassword; }
public haus.nightmare.lib3270j.security.ssl.HODSSLECLSessionImpl getSSLSessionImpl() {
return (session != null) ? session.getSSLSessionImpl() : new haus.nightmare.lib3270j.security.ssl.HODSSLECLSessionImpl(this);
}
public haus.nightmare.lib3270j.security.ssl.HODSSLECLSessionImpl GetSSLSessionImpl() {
return getSSLSessionImpl();
}
public void setProxy(String proxy) { this.proxyServerName = proxy; }
public void SetProxy(String proxy) { setProxy(proxy); }
public String getProxy() { return proxyServerName; }
public String GetProxy() { return proxyServerName; }
public void setProxyType(String type) { this.proxyType = type; }
public void SetProxyType(String type) { setProxyType(type); }
public String getProxyType() { return proxyType; }
public String GetProxyType() { return proxyType; }
public void setProxyServerName(String name) { this.proxyServerName = name; }
public void SetProxyServerName(String name) { setProxyServerName(name); }
public String getProxyServerName() { return proxyServerName; }
public String GetProxyServerName() { return proxyServerName; }
public void setProxyServerPort(String port) { this.proxyServerPort = port; }
public void SetProxyServerPort(String port) { setProxyServerPort(port); }
public String getProxyServerPort() { return proxyServerPort; }
public String GetProxyServerPort() { return proxyServerPort; }
public void setProxyUserID(String uid) { this.proxyUserId = uid; }
public void SetProxyUserID(String uid) { setProxyUserID(uid); }
public String getProxyUserID() { return proxyUserId; }
public String GetProxyUserID() { return proxyUserId; }
public void setProxyUserPassword(String pwd) { this.proxyUserPassword = pwd; }
public void SetProxyUserPassword(String pwd) { setProxyUserPassword(pwd); }
public String getProxyUserPassword() { return proxyUserPassword; }
public String GetProxyUserPassword() { return proxyUserPassword; }
public void setProxyAuthenMethod(String method) { this.proxyAuthenMethod = method; }
public void SetProxyAuthenMethod(String method) { setProxyAuthenMethod(method); }
public String getProxyAuthenMethod() { return proxyAuthenMethod; }
public String GetProxyAuthenMethod() { return proxyAuthenMethod; }
public void setProxySecurityProtocol(String prot) { this.proxySecurityProtocol = prot; }
public void SetProxySecurityProtocol(String prot) { setProxySecurityProtocol(prot); }
public String getProxySecurityProtocol() { return proxySecurityProtocol; }
public String GetProxySecurityProtocol() { return proxySecurityProtocol; }
public void setProperties(Properties props) {
if (props != null) {
this.properties.putAll(props);
convertData(this.properties);
}
}
public void SetProperties(Properties props) { setProperties(props); }
public Properties getProperties() { return properties; }
public Properties GetProperties() { return properties; }
@Override
public String toString() {
return String.format("ECLConnection[host=%s, port=%d, state=%s, lu=%s, ssl=%b]",
@@ -0,0 +1,70 @@
package haus.nightmare.lib3270j.ecl;
/**
* Conforms to IBM Host On-Demand ECLErr checked exception.
*/
public class ECLErr extends Exception {
private static final long serialVersionUID = 1L;
private String tag = "";
private String id = "";
private String text = "";
public ECLErr() {
super();
}
public ECLErr(String text) {
super(text);
this.text = text;
}
public ECLErr(String tag, String id, String text) {
super(formatMsg(tag, id, text));
this.tag = tag;
this.id = id;
this.text = text;
}
public ECLErr(String tag, String id, String text, String extra) {
super(formatMsg(tag, id, text + " " + extra));
this.tag = tag;
this.id = id;
this.text = text + " " + extra;
}
public ECLErr(Throwable cause) {
super(cause);
}
public ECLErr(String message, Throwable cause) {
super(message, cause);
this.text = message;
}
private static String formatMsg(String tag, String id, String text) {
StringBuilder sb = new StringBuilder();
if (tag != null && !tag.isEmpty()) sb.append(tag).append(" ");
if (id != null && !id.isEmpty()) sb.append(id).append(": ");
if (text != null) sb.append(text);
return sb.toString();
}
public String getTag() { return tag; }
public String GetTag() { return tag; }
public String getID() { return id; }
public String GetID() { return id; }
public String getText() { return text; }
public String GetText() { return text; }
public String getErrorText() { return getMessage(); }
public String GetErrorText() { return getMessage(); }
@Override
public String toString() {
return "ECLErr[tag=" + tag + ", id=" + id + ", text=" + text + "]";
}
}
@@ -106,6 +106,36 @@ public class ECLField {
}
public boolean IsDisplay() { return isDisplay(); }
public boolean isPenDetectable() {
return !isProtected() && (getLiveAttribute() & 0x0C) != 0;
}
public boolean IsPenDetectable() { return isPenDetectable(); }
public void setFieldAttribute(char attr) {
if (ps != null && ps.getScreenBuffer() != null) {
ExtendedAttribute cell = ps.getScreenBuffer().getCell(startPos);
if (cell != null) {
cell.fa = (byte) (attr & 0xFF);
ps.getScreenBuffer().markAllChanged();
ps.getScreenBuffer().updateDisplaySnapshot();
}
}
}
public void SetFieldAttribute(char attr) { setFieldAttribute(attr); }
public int getStartFieldPos() {
return startPos;
}
public int GetStartFieldPos() { return getStartFieldPos(); }
public char[] copyPlanes(int plane) {
if (length <= 0 || ps == null) return new char[0];
char[] buf = new char[length];
ps.getPlane(plane, buf, dataStart, length);
return buf;
}
public char[] CopyPlanes(int plane) { return copyPlanes(plane); }
public boolean isPenSelectable() {
return faIsSelectable(getLiveAttribute() & 0xFF);
}
@@ -225,4 +225,72 @@ public class ECLFieldList {
return null;
}
public ECLField FindField(String text, int startPos) { return findField(text, startPos); }
public boolean matchAttributes(ECLField f, int mask) {
if (f == null) return false;
if (mask == 0) return true;
boolean ok = true;
if ((mask & 0x01) == 1) {
ok &= f.IsModified();
} else if ((mask & 0x100) == 0x100) {
ok &= !f.IsModified();
}
if ((mask & 0x02) == 2) {
ok &= !f.IsNumeric();
} else if ((mask & 0x200) == 0x200) {
ok &= f.IsNumeric();
}
if ((mask & 0x10) == 0x10) {
ok &= f.IsHighIntensity();
} else if ((mask & 0x1000) == 0x1000) {
ok &= !f.IsHighIntensity();
}
if ((mask & 0x20) == 0x20) {
ok &= f.IsProtected();
} else if ((mask & 0x2000) == 0x2000) {
ok &= !f.IsProtected();
}
if ((mask & 0x40) == 0x40) {
ok &= f.IsDisplay();
} else if ((mask & 0x4000) == 0x4000) {
ok &= !f.IsDisplay();
}
if ((mask & 0x80) == 0x80) {
ok &= f.IsPenDetectable();
} else if ((mask & 0x8000) == 0x8000) {
ok &= !f.IsPenDetectable();
}
return ok;
}
public boolean MatchAttributes(ECLField f, int mask) { return matchAttributes(f, mask); }
public synchronized ECLField locateField(int attrMask, ECLField prev) {
if (fields.isEmpty()) return null;
int startIndex = 0;
if (prev != null) {
int idx = fields.indexOf(prev);
if (idx >= 0 && idx + 1 < fields.size()) {
startIndex = idx + 1;
} else {
return null;
}
}
for (int i = startIndex; i < fields.size(); i++) {
ECLField f = fields.get(i);
if (matchAttributes(f, attrMask)) {
return f;
}
}
return null;
}
public ECLField LocateField(int attrMask, ECLField prev) { return locateField(attrMask, prev); }
public synchronized void copyPlanes(int plane) {
if (ps != null && screen != null) {
int size = screen.getRows() * screen.getCols();
char[] buf = new char[size];
ps.getPlane(plane, buf, 0, size);
}
}
public void CopyPlanes(int plane) { copyPlanes(plane); }
}
@@ -15,14 +15,79 @@ import static haus.nightmare.lib3270j.protocol.DS3270Constants.*;
*/
public class ECLOIA implements ECLConstants {
public static final int INHIBIT_NOTINHIBITED = 0;
public static final int INHIBIT_SYSTEMWAIT = 1;
public static final int INHIBIT_COMMCHECK = 2;
public static final int INHIBIT_PROGCHECK = 3;
public static final int INHIBIT_MACHCHECK = 4;
public static final int INHIBIT_OTHERINHIBIT = 5;
public static final int STATE_NO_CHANGE = 0;
public static final int STATE_CONTROLLER_READY = 1;
public static final int STATE_ONLINE = 2;
public static final int STATE_A_ONLINE = 2;
public static final int STATE_MY_JOB = 4;
public static final int STATE_OP_SYS = 8;
public static final int STATE_UNOWNED = 16;
public static final int STATE_TIME = 32;
public static final int STATE_SYS_LOCK = 64;
public static final int STATE_COMM_CHECK = 128;
public static final int STATE_PROG_CHECK = 256;
public static final int STATE_ELSEWHERE = 512;
public static final int STATE_FN_MINUS = 1024;
public static final int STATE_WHAT_KEY = 2048;
public static final int STATE_MORE_THAN = 4096;
public static final int STATE_SYM_MINUS = 8192;
public static final int STATE_INPUT_ERROR = 16384;
public static final int STATE_OIA_SUPPRESS = 32768;
public static final int STATE_HOST_CONTROL = 65536;
public static final int STATE_HOST_WRITE = 131072;
public static final int STATE_HOD_CONTROL = 262144;
public static final int STATE_DO_NOT_ENTER = 32736;
public static final int STATE_CLEAR_DO_NOT_ENTER = -32737;
public static final int STATE_INSERT = 32768;
public static final int STATE_UPSHIFT = 65536;
public static final int STATE_APL = 131072;
public static final int STATE_GR_CURSOR = 262144;
public static final int STATE_CAPSLOCK = 524288;
public static final int STATE_NUMLOCK = 0x100000;
public static final int STATE_COMM_ERR_REM = 0x200000;
public static final int STATE_MSG_WAITING = 0x400000;
public static final int STATE_SCREEN_REVERSE = 0x800000;
public static final int STATE_LANGUAGE_LAYER = 0x1000000;
public static final int STATE_CURSOR_DIRECTION = 0x2000000;
public static final int STATE_AUTOREVERSE = 0x4000000;
public static final int STATE_NUMFIELD = 0x8000000;
public static final int STATE_AUTOPUSH = 0x10000000;
public static final int STATE_AUTOSHAPE = 0x20000000;
public static final int STATE_PUSH = 0x40000000;
public static final int STATE_TEXT_MODE = 0x40000000;
public static final int STATE_COLUMNHEAD = 0x2000000;
public static final int STATE_B_ONLINE = 0x40000000;
public static final int STATE_ENCRYPT = Integer.MIN_VALUE;
public static final long STATE_DOC_MODE = 0x100000000L;
public static final long STATE_WORDWRAP = 0x200000000L;
public static final int STOP_UNREGISTER = 1;
public static final int STOP_DISCONNECT = 2;
public static final int STOP_ERROR = 3;
private final ScreenBuffer screen;
private final InputProcessor inputProcessor;
private final TelnetFSM fsm;
private final List<ECLOIANotify> listeners = new ArrayList<>();
private final List<haus.nightmare.lib3270j.ecl.ECLOIANotify> listeners = new java.util.concurrent.CopyOnWriteArrayList<>();
private final List<ECLOIAListener> oiaListeners = new java.util.concurrent.CopyOnWriteArrayList<>();
public interface ECLOIANotify {
void onOIAChanged(ECLOIA oia);
protected long state = STATE_ONLINE | STATE_CONTROLLER_READY;
protected long previousState = 0L;
protected String stateData = null;
private ECLOIABIDI oiaBidi;
private ECLOIATHAI oiaThai;
private ECLOIAHindi oiaHindi;
private String oiaText = "";
private boolean oiaInvisible = false;
public interface ECLOIANotify extends haus.nightmare.lib3270j.ecl.ECLOIANotify {
}
public ECLOIA(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
@@ -35,14 +100,33 @@ public class ECLOIA implements ECLConstants {
}
}
public synchronized void registerOIAEvent(ECLOIANotify listener) {
public ECLOIA(ECLSession session) {
this(session != null && session.getClient() != null ? session.getClient().getScreenBuffer() : null,
session != null && session.getClient() != null ? session.getClient().getInputProcessor() : null,
session != null && session.getClient() != null ? session.getClient().getTelnetFSM() : null);
}
public void RegisterOIAEvent(haus.nightmare.lib3270j.ecl.ECLOIANotify listener) {
if (listener != null && !listeners.contains(listener)) {
listeners.add(listener);
}
}
public synchronized void unregisterOIAEvent(ECLOIANotify listener) {
listeners.remove(listener);
public void registerOIAEvent(haus.nightmare.lib3270j.ecl.ECLOIANotify listener) {
RegisterOIAEvent(listener);
}
public void UnregisterOIAEvent(haus.nightmare.lib3270j.ecl.ECLOIANotify listener) {
if (listener != null) {
listeners.remove(listener);
try {
listener.OIANotifyStop(this, STOP_UNREGISTER);
} catch (Exception ignored) {}
}
}
public void unregisterOIAEvent(haus.nightmare.lib3270j.ecl.ECLOIANotify listener) {
UnregisterOIAEvent(listener);
}
public void RegisterOIAEvent(ECLOIAListener listener) {
@@ -52,7 +136,12 @@ public class ECLOIA implements ECLConstants {
}
public void UnregisterOIAEvent(ECLOIAListener listener) {
oiaListeners.remove(listener);
if (listener != null) {
oiaListeners.remove(listener);
try {
listener.OIANotifyStop(this, STOP_UNREGISTER);
} catch (Exception ignored) {}
}
}
public void registerOIAListener(ECLOIAListener listener) {
@@ -63,17 +152,43 @@ public class ECLOIA implements ECLConstants {
UnregisterOIAEvent(listener);
}
private synchronized void notifyOIAChanged() {
for (ECLOIANotify l : listeners) {
public void notifyOIAError(ECLErr err) {
for (haus.nightmare.lib3270j.ecl.ECLOIANotify l : listeners) {
try {
l.onOIAChanged(this);
l.OIANotifyError(this, err);
} catch (Exception ignored) {}
}
ECLOIAEvent event = new ECLOIAEvent(this, ECLOIAEvent.OIA_UPDATE, getInputInhibited(),
getAlphanumericType(), isInsertMode(), getStatusString());
for (ECLOIAListener l : oiaListeners) {
try {
l.oiaChanged(event);
l.OIANotifyError(this, err);
} catch (Exception ignored) {}
}
}
public void notifyOIAStop(int reason) {
for (haus.nightmare.lib3270j.ecl.ECLOIANotify l : listeners) {
try {
l.OIANotifyStop(this, reason);
} catch (Exception ignored) {}
}
for (ECLOIAListener l : oiaListeners) {
try {
l.OIANotifyStop(this, reason);
} catch (Exception ignored) {}
}
}
private synchronized void notifyOIAChanged() {
ECLOIAEvent event = new ECLOIAEvent(this, ECLOIAEvent.OIA_UPDATE, getInputInhibited(),
getAlphanumericType(), isInsertMode(), getStatusString());
for (haus.nightmare.lib3270j.ecl.ECLOIANotify l : listeners) {
try {
l.OIANotifyEvent(event);
} catch (Exception ignored) {}
}
for (ECLOIAListener l : oiaListeners) {
try {
l.OIANotifyEvent(event);
if (inputProcessor != null) {
l.oiaLockStateChanged(event);
}
@@ -362,4 +477,140 @@ public class ECLOIA implements ECLConstants {
public boolean WaitForTransition(long timeoutMs) {
return waitForTransition(timeoutMs);
}
public synchronized long GetStatusFlagsEx() {
long s = this.state;
if (isInsertMode()) s |= STATE_INSERT;
if (isNumeric()) s |= STATE_NUMFIELD;
if (screen != null && screen.isEntryAssistDOCmode()) s |= STATE_DOC_MODE;
if (screen != null && screen.isEntryAssistWordWrap()) s |= STATE_WORDWRAP;
if (isXSystem()) s |= STATE_SYS_LOCK;
if (isXComm()) s |= STATE_COMM_CHECK;
return s;
}
public int GetStatusFlags() {
return (int) GetStatusFlagsEx();
}
public int getStatusFlags() { return GetStatusFlags(); }
public long getStatusFlagsEx() { return GetStatusFlagsEx(); }
public synchronized void setBitmaskState(long flag, boolean on) {
this.previousState = this.state;
if (on) {
this.state |= flag;
} else {
this.state &= ~flag;
}
notifyOIAChanged();
}
public synchronized void setDoNotEnter(int n, int n2) {
long l = 0L;
switch (n) {
case 7: l = 32L; break; // STATE_TIME
case 8: l = 64L; break; // STATE_SYS_LOCK
case 9: l = 0x200080L; break; // STATE_COMM_CHECK | STATE_COMM_ERR_REM
case 10: l = 256L; break; // STATE_PROG_CHECK
case 13: l = 512L; break; // STATE_ELSEWHERE
case 12: l = 1024L; break; // STATE_FN_MINUS
case 11: l = 2048L; break; // STATE_WHAT_KEY
case 14: l = 4096L; break; // STATE_MORE_THAN
case 15: l = 8192L; break; // STATE_SYM_MINUS
case 55: l = 16384L; break; // STATE_INPUT_ERROR
default: l = 64L; break;
}
this.previousState = this.state;
this.state &= 0xFFFFFFFFFFFF801FL;
this.state |= l;
this.stateData = String.valueOf(n2);
notifyOIAChanged();
}
public synchronized void clearDoNotEnter() {
this.previousState = this.state;
long l = this.state & 0x7FE0L;
this.state &= ~l;
this.stateData = null;
this.state &= ~0x200000L;
notifyOIAChanged();
}
public synchronized void setReadyConnect(int n, String string) {
long l = 0L;
boolean clear = false;
switch (n) {
case 1: l = 1L; break; // STATE_CONTROLLER_READY
case 2: l = 2L; break; // STATE_ONLINE
case 3: l = 0x40000000L; break; // STATE_B_ONLINE
case 4: l = 4L; break; // STATE_MY_JOB
case 5: l = 8L; break; // STATE_OP_SYS
case 6: l = 16L; break; // STATE_UNOWNED
case 69:
l = 0x80000000L; // STATE_ENCRYPT
if (" ".equals(string) && (this.state & 0x80000000L) != 0L) {
clear = true;
}
break;
default: break;
}
if (l != 0L) {
this.previousState = this.state;
this.state &= 0xFFFFFFFFFFFFFFE3L;
if (clear) {
this.state &= ~l;
} else {
this.state |= l;
}
this.stateData = string;
notifyOIAChanged();
}
}
public synchronized void setMsgWaiting(boolean bl) {
setBitmaskState(STATE_MSG_WAITING, bl);
}
public synchronized void setOiaInvisible() {
this.oiaInvisible = true;
setBitmaskState(STATE_OIA_SUPPRESS, true);
}
public synchronized void setOiaHostControl() {
setBitmaskState(STATE_HOST_CONTROL, true);
setBitmaskState(STATE_HOD_CONTROL, false);
}
public synchronized void setOiaHODControl() {
setBitmaskState(STATE_HOD_CONTROL, true);
setBitmaskState(STATE_HOST_CONTROL, false);
}
public synchronized void writeToOIA(String text) {
this.oiaText = text != null ? text : "";
notifyOIAChanged();
}
public synchronized ECLOIABIDI GetECLOIABIDI() {
if (oiaBidi == null) {
oiaBidi = new ECLOIABIDI(screen, inputProcessor, fsm);
}
return oiaBidi;
}
public ECLOIABIDI getECLOIABIDI() { return GetECLOIABIDI(); }
public synchronized ECLOIATHAI GetECLOIATHAI() {
if (oiaThai == null) {
oiaThai = new ECLOIATHAI(screen, inputProcessor, fsm);
}
return oiaThai;
}
public ECLOIATHAI getECLOIATHAI() { return GetECLOIATHAI(); }
public synchronized ECLOIAHindi GetECLOIAHindi() {
if (oiaHindi == null) {
oiaHindi = new ECLOIAHindi(screen, inputProcessor, fsm);
}
return oiaHindi;
}
public ECLOIAHindi getECLOIAHindi() { return GetECLOIAHindi(); }
}
@@ -0,0 +1,42 @@
package haus.nightmare.lib3270j.ecl;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
import haus.nightmare.lib3270j.telnet.TelnetFSM;
/**
* Conforms to IBM Host On-Demand ECLOIABIDI.
*/
public class ECLOIABIDI extends ECLOIA {
private int shapeValue;
public ECLOIABIDI(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
super(screen, inputProcessor, fsm);
}
public synchronized void setBIDIMode(int mode, boolean on) {
switch (mode) {
case 78: setStateBIDI(0x40000000, on); break;
case 70: setStateBIDI(0x800000, on); break;
case 71: setStateBIDI(0x1000000, on); break;
case 79:
case 72: setStateBIDI(0x2000000, on); break;
case 73: setStateBIDI(0x4000000, on); break;
case 74: setStateBIDI(0x8000000, on); break;
case 75: setStateBIDI(0x10000000, on); break;
case 77: setStateBIDI(0x40000000, on); break;
case 76: setStateBIDI(0x20000000, on); break;
default: break;
}
}
public synchronized void setBIDIShapeMode(int shape) {
this.shapeValue = shape;
setStateBIDI(0x20000000, shape == 0);
}
private void setStateBIDI(int flag, boolean on) {
setBitmaskState(flag, on);
}
}
@@ -4,6 +4,7 @@ import java.util.EventObject;
/**
* Event object dispatched on Operator Information Area (ECLOIA) status changes.
* Conforms 1:1 to IBM Host On-Demand ECLOIAEvent specification.
*/
public class ECLOIAEvent extends EventObject {
@@ -27,29 +28,48 @@ public class ECLOIAEvent extends EventObject {
public ECLOIAEvent(Object source, int eventType, int inputInhibited, int alphanumericType,
boolean insertMode, String statusString) {
super(source);
super(source != null ? source : "ECLOIA");
this.eventType = eventType;
this.inputInhibited = inputInhibited;
this.alphanumericType = alphanumericType;
this.insertMode = insertMode;
this.statusString = statusString;
this.statusString = statusString != null ? statusString : "";
}
public int getEventType() { return eventType; }
public int GetType() { return eventType; }
public int getType() { return eventType; }
public int getInputInhibited() { return inputInhibited; }
public int GetInputInhibited() { return inputInhibited; }
public int getInhibitedReason() { return inputInhibited; }
public int GetInhibitedReason() { return inputInhibited; }
public int getAlphanumericType() { return alphanumericType; }
public int GetAlphanumericType() { return alphanumericType; }
public boolean isInsertMode() { return insertMode; }
public boolean IsInsertMode() { return insertMode; }
public String getStatusString() { return statusString; }
public String GetStatusString() { return statusString; }
public boolean isInputInhibited() {
return inputInhibited != ECLConstants.INHIBIT_NOT_INHIBITED;
}
public boolean IsInputInhibited() {
return isInputInhibited();
}
public ECLOIA getOIA() {
return (getSource() instanceof ECLOIA) ? (ECLOIA) getSource() : null;
}
public ECLOIA GetOIA() {
return getOIA();
}
@Override
public String toString() {
return String.format("ECLOIAEvent[type=%d, status='%s', inhibited=%d, insert=%b]",
@@ -0,0 +1,21 @@
package haus.nightmare.lib3270j.ecl;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
import haus.nightmare.lib3270j.telnet.TelnetFSM;
/**
* Conforms to IBM Host On-Demand ECLOIAHindi.
*/
public class ECLOIAHindi extends ECLOIA {
public ECLOIAHindi(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
super(screen, inputProcessor, fsm);
}
public synchronized void setHindiMode(int mode, boolean on) {
if (mode == 71) {
setBitmaskState(0x1000000, on);
}
}
}
@@ -2,14 +2,39 @@ package haus.nightmare.lib3270j.ecl;
/**
* Listener interface for Operator Information Area (ECLOIA) status change events.
* Conforms 1:1 to IBM Host On-Demand ECLOIAListener specification.
*/
public interface ECLOIAListener {
/**
* Primary HoD notification callback invoked when OIA status changes.
* @param event ECLOIAEvent containing OIA status
*/
default void OIANotifyEvent(ECLOIAEvent event) {
oiaChanged(event);
}
/**
* Called when an error condition occurs during OIA event generation.
* @param oia ECLOIA instance
* @param err ECLErr error descriptor
*/
default void OIANotifyError(ECLOIA oia, ECLErr err) {}
/**
* Called when OIA event generation has stopped.
* @param oia ECLOIA instance
* @param reason Stop reason code
*/
default void OIANotifyStop(ECLOIA oia, int reason) {}
// ========== Backward-Compatibility Bridge Methods ==========
/**
* Called when the OIA status, input inhibited flag, or keyboard lock state changes.
* @param event ECLOIAEvent containing OIA status information
*/
void oiaChanged(ECLOIAEvent event);
default void oiaChanged(ECLOIAEvent event) {}
/**
* Called when the input inhibited condition changes specifically.
@@ -0,0 +1,29 @@
package haus.nightmare.lib3270j.ecl;
/**
* Interface for receiving Operator Information Area (ECLOIA) notifications.
* Conforms 1:1 to IBM Host On-Demand ECLOIANotify specification.
*/
@FunctionalInterface
public interface ECLOIANotify {
/**
* Primary HoD notification callback invoked when OIA status changes.
* @param event ECLOIAEvent containing OIA status
*/
void OIANotifyEvent(ECLOIAEvent event);
/**
* Called when an error condition occurs during OIA event generation.
* @param oia ECLOIA instance
* @param err ECLErr error descriptor
*/
default void OIANotifyError(ECLOIA oia, ECLErr err) {}
/**
* Called when OIA event generation has stopped.
* @param oia ECLOIA instance
* @param reason Stop reason code
*/
default void OIANotifyStop(ECLOIA oia, int reason) {}
}
@@ -0,0 +1,21 @@
package haus.nightmare.lib3270j.ecl;
import haus.nightmare.lib3270j.input.InputProcessor;
import haus.nightmare.lib3270j.screen.ScreenBuffer;
import haus.nightmare.lib3270j.telnet.TelnetFSM;
/**
* Conforms to IBM Host On-Demand ECLOIATHAI.
*/
public class ECLOIATHAI extends ECLOIA {
public ECLOIATHAI(ScreenBuffer screen, InputProcessor inputProcessor, TelnetFSM fsm) {
super(screen, inputProcessor, fsm);
}
public synchronized void setTHAIMode(int mode, boolean on) {
if (mode == 71) {
setBitmaskState(0x1000000, on);
}
}
}
@@ -18,11 +18,41 @@ public class ECLPS implements ECLConstants {
private final EbcdicTranslator translator;
private final ECLFieldList fieldList;
private ECLSession session;
private Object screenHistory;
private final ECLPSGraphicsServices graphicsServices;
private final ECLPSBIDIServices bidiServices;
private final ECLPSHindiServices hindiServices;
private final ECLPSTHAIServices thaiServices;
public static final int USER_EVENTS = 1;
public static final int HOST_EVENTS = 2;
public static final int ALL_EVENTS = 3;
public static final int STOP_UNREGISTER = 1;
public static final int STOP_DISCONNECT = 2;
public static final int STOP_ERROR = 3;
private boolean cursorVisible = true;
private final java.util.concurrent.atomic.AtomicInteger ringCounter = new java.util.concurrent.atomic.AtomicInteger(0);
private final java.util.Map<ECLPSListener, ECLScreenDesc> descriptorListeners = new java.util.concurrent.ConcurrentHashMap<>();
private final java.util.Map<ECLPSListener, Integer> listenerEventTypes = new java.util.concurrent.ConcurrentHashMap<>();
public ECLPS(ScreenBuffer screen, InputProcessor inputProcessor, EbcdicTranslator translator) {
this.screen = screen;
this.inputProcessor = inputProcessor;
this.translator = translator;
this.fieldList = new ECLFieldList(this, screen);
this.graphicsServices = new DefaultPSGraphicsServices(this);
this.bidiServices = new DefaultPSBIDIServices(this);
this.hindiServices = new DefaultPSHindiServices(this);
this.thaiServices = new DefaultPSTHAIServices(this);
}
public ECLPS(ECLSession session) {
this(session != null && session.getClient() != null ? session.getClient().getScreenBuffer() : null,
session != null && session.getClient() != null ? session.getClient().getInputProcessor() : null,
session != null && session.getClient() != null ? session.getClient().getTranslator() : null);
this.session = session;
}
public ScreenBuffer getScreenBuffer() { return screen; }
@@ -46,6 +76,35 @@ public class ECLPS implements ECLConstants {
this.nvtMode = nvt;
}
public ECLSession GetParent() { return session; }
public ECLSession getParent() { return session; }
public void setSession(ECLSession session) { this.session = session; }
public ECLSession getSession() { return session; }
public haus.nightmare.lib3270j.tn3270.DS3270 GetDS() {
return session != null ? session.GetDS() : null;
}
public haus.nightmare.lib3270j.tn3270.DS3270 getDS() { return GetDS(); }
public void setScreenHistory(Object hist) { this.screenHistory = hist; }
public Object getScreenHistory() { return screenHistory; }
public ECLPSGraphicsServices GetPSGraphicsServices() { return graphicsServices; }
public ECLPSGraphicsServices GetECLPSGraphicsServices() { return graphicsServices; }
public ECLPSGraphicsServices getGraphicsServices() { return graphicsServices; }
public ECLPSBIDIServices GetPSBIDIServices() { return bidiServices; }
public ECLPSBIDIServices GetECLPSBIDIServices() { return bidiServices; }
public ECLPSBIDIServices getBIDIServices() { return bidiServices; }
public ECLPSHindiServices GetPSHindiServices() { return hindiServices; }
public ECLPSHindiServices GetECLPSHindiServices() { return hindiServices; }
public ECLPSHindiServices getHindiServices() { return hindiServices; }
public ECLPSTHAIServices GetPSTHAIServices() { return thaiServices; }
public ECLPSTHAIServices GetECLPSTHAIServices() { return thaiServices; }
public ECLPSTHAIServices getTHAIServices() { return thaiServices; }
public int getSize() { return screen.getRows() * screen.getCols(); }
public int getRows() { return screen.getRows(); }
public int getCols() { return screen.getCols(); }
@@ -108,6 +167,40 @@ public class ECLPS implements ECLConstants {
return copyLen;
}
public synchronized int GetScreenRect(char[] cArray, int len, int sRow, int sCol, int eRow, int eCol, int plane) {
if (cArray == null || len <= 0 || screen == null) return 0;
int minR = Math.max(1, Math.min(sRow, eRow));
int maxR = Math.min(getRows(), Math.max(sRow, eRow));
int minC = Math.max(1, Math.min(sCol, eCol));
int maxC = Math.min(getCols(), Math.max(sCol, eCol));
int width = maxC - minC + 1;
int count = 0;
for (int r = minR; r <= maxR; r++) {
char[] rowBuf = new char[width];
int sAddr = (r - 1) * getCols() + (minC - 1);
getPlane(plane, rowBuf, sAddr, width);
int copyLen = Math.min(width, len - count);
if (copyLen <= 0) break;
System.arraycopy(rowBuf, 0, cArray, count, copyLen);
count += copyLen;
}
return count;
}
public int getScreenRect(char[] cArray, int len, int sRow, int sCol, int eRow, int eCol, int plane) {
return GetScreenRect(cArray, len, sRow, sCol, eRow, eCol, plane);
}
public String GetScreenRect(int startRow, int startCol, int endRow, int endCol) {
return copyString(startRow - 1, startCol - 1, endRow - 1, endCol - 1);
}
public String getScreenRect(int startRow, int startCol, int endRow, int endCol) {
return GetScreenRect(startRow, startCol, endRow, endCol);
}
/**
* Get a string of characters from the presentation space starting at address pos.
*/
@@ -126,6 +219,14 @@ public class ECLPS implements ECLConstants {
return getString(pos, length);
}
public String getScreen(int pos, int length) {
return getString(pos, length);
}
public String GetScreen(int pos, int length) {
return getString(pos, length);
}
/**
* Insert text directly into unprotected fields in the presentation space starting at pos.
*/
@@ -151,6 +252,23 @@ public class ECLPS implements ECLConstants {
setText(text, pos);
}
/**
* Insert text at 1-based (row, col) position.
*/
public void SetText(String text, int row, int col) {
int r = (row > 0) ? row - 1 : 0;
int c = (col > 0) ? col - 1 : 0;
setText(text, r, c);
}
/**
* Insert text at 1-based linear buffer position.
*/
public void SetText(String text, int pos) {
int p = (pos > 0) ? pos - 1 : 0;
setText(text, p);
}
/**
* Search for a string in the presentation space (0-based indexing).
* Returns 0-based position, or -1 if not found.
@@ -460,6 +578,88 @@ public class ECLPS implements ECLConstants {
return pasteLineWrap(text, startPos, endCol, wordWrap);
}
public synchronized int pasteInDocMode(String text, int row, int col) {
if (text == null || text.isEmpty()) return 0;
int r = (row > 0) ? row - 1 : 0;
int c = (col > 0) ? col - 1 : 0;
if (!isEntryAssistDOCmode()) {
return pasteString(text, r, c);
}
int pos = (screen != null) ? screen.rowColToAddress(r, c) : 0;
return pasteLineWrap(text, pos, getEntryAssistEndColumn(), isEntryAssistWordWrap());
}
public int PasteInDocMode(String text, int row, int col) { return pasteInDocMode(text, row, col); }
public boolean enableTrimOnPaste() {
String prop = System.getProperty("trimPastedChar");
if (prop == null && session != null && session.getProperties() != null) {
prop = session.getProperties().getProperty("trimPastedChar");
}
return "true".equalsIgnoreCase(prop);
}
public boolean EnableTrimOnPaste() { return enableTrimOnPaste(); }
public String handleTabs(String string, String string2) {
if (string == null || string2 == null) {
return string;
}
if (string2.equals("2")) {
int n = 4;
if (session != null && session.getProperties() != null) {
String sp = session.getProperties().getProperty("pasteTabSpaces");
if (sp != null) {
try { n = Integer.parseInt(sp); } catch (NumberFormatException ignored) {}
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < string.length(); ++i) {
char c = string.charAt(i);
if (c == '\t') {
for (int j = 0; j < n; ++j) {
sb.append(' ');
}
} else {
sb.append(c);
}
}
return sb.toString();
} else if (string2.equals("1")) {
int n = 8;
if (session != null && session.getProperties() != null) {
String colStr = session.getProperties().getProperty("pasteTabColumns");
if (colStr != null) {
try { n = Integer.parseInt(colStr); } catch (NumberFormatException ignored) {}
}
}
StringBuilder sb = new StringBuilder();
int n4 = 0;
for (int i = 0; i < string.length(); ++i) {
char c = string.charAt(i);
++n4;
if (c == '\t') {
while (n4 < n + 1) {
sb.append(' ');
++n4;
}
n4 = 0;
continue;
}
if (c == '\n') {
sb.append(c);
n4 = 0;
continue;
}
sb.append(c);
if (n4 == n && i + 1 < string.length() && string.charAt(i + 1) != '\t') {
n4 = 0;
}
}
return sb.toString();
}
return string;
}
public String HandleTabs(String string, String string2) { return handleTabs(string, string2); }
// ========== Entry Assist & DOC Mode Operations ==========
public boolean isEntryAssistDOCmode() { return screen != null && screen.isEntryAssistDOCmode(); }
@@ -562,28 +762,105 @@ public class ECLPS implements ECLConstants {
private final java.util.List<ECLPSListener> psListeners = new java.util.concurrent.CopyOnWriteArrayList<>();
public boolean isCursorVisible() { return cursorVisible; }
public boolean GetCursorVisible() { return cursorVisible; }
public void setCursorVisible(boolean visible) { this.cursorVisible = visible; }
public void SetCursorVisible(boolean visible) { setCursorVisible(visible); }
public int getRingCounter() { return ringCounter.get(); }
public int GetRingCounter() { return getRingCounter(); }
public void RegisterPSEvent(ECLPSListener listener) {
if (listener != null && !psListeners.contains(listener)) {
psListeners.add(listener);
}
RegisterPSEvent(listener, ALL_EVENTS);
}
public void registerPSEvent(ECLPSListener listener) {
RegisterPSEvent(listener);
}
public void RegisterPSEvent(ECLPSListener listener, int eventType) {
if (listener != null) {
listenerEventTypes.put(listener, eventType);
if (!psListeners.contains(listener)) {
psListeners.add(listener);
}
}
}
public void registerPSEvent(ECLPSListener listener, int eventType) {
RegisterPSEvent(listener, eventType);
}
public void RegisterPSEvent(ECLPSListener listener, ECLScreenDesc desc) {
RegisterPSEvent(listener, desc, ALL_EVENTS);
}
public void registerPSEvent(ECLPSListener listener, ECLScreenDesc desc) {
RegisterPSEvent(listener, desc);
}
public void RegisterPSEvent(ECLPSListener listener, ECLScreenDesc desc, int eventType) {
if (listener != null) {
if (desc != null) {
descriptorListeners.put(listener, desc);
} else {
descriptorListeners.remove(listener);
}
listenerEventTypes.put(listener, eventType);
if (!psListeners.contains(listener)) {
psListeners.add(listener);
}
}
}
public void registerPSEvent(ECLPSListener listener, ECLScreenDesc desc, int eventType) {
RegisterPSEvent(listener, desc, eventType);
}
public void UnregisterPSEvent(ECLPSListener listener) {
psListeners.remove(listener);
if (listener != null) {
psListeners.remove(listener);
descriptorListeners.remove(listener);
listenerEventTypes.remove(listener);
try {
listener.PSNotifyStop(this, STOP_UNREGISTER);
} catch (Exception ignored) {}
}
}
public void unregisterPSEvent(ECLPSListener listener) {
UnregisterPSEvent(listener);
}
public void UnregisterPSEvent(ECLPSListener listener, ECLScreenDesc desc) {
UnregisterPSEvent(listener);
}
public void unregisterPSEvent(ECLPSListener listener, ECLScreenDesc desc) {
UnregisterPSEvent(listener);
}
public void UnregisterPSEvent(ECLPSListener listener, int eventType) {
UnregisterPSEvent(listener);
}
public void unregisterPSEvent(ECLPSListener listener, int eventType) {
UnregisterPSEvent(listener);
}
public void notifyPSEvent(ECLPSEvent event) {
for (ECLPSListener l : psListeners) {
ECLScreenDesc desc = descriptorListeners.get(l);
if (desc != null && !desc.Matches(this, session != null ? session.GetOIA() : null)) {
continue;
}
int filter = listenerEventTypes.getOrDefault(l, ALL_EVENTS);
int evtCategory = event.GetType();
if (filter != ALL_EVENTS && (filter & evtCategory) == 0) {
continue;
}
try {
l.psChanged(event);
l.PSNotifyEvent(event);
if (event.getEventType() == ECLPSEvent.PS_CURSOR) {
l.psCursorMoved(event);
} else if (event.getEventType() == ECLPSEvent.PS_ALARM) {
@@ -597,11 +874,34 @@ public class ECLPS implements ECLConstants {
}
}
public void notifyPSError(ECLErr err) {
for (ECLPSListener l : psListeners) {
try {
l.PSNotifyError(this, err);
} catch (Exception ignored) {}
}
}
public void notifyPSStop(int reason) {
for (ECLPSListener l : psListeners) {
try {
l.PSNotifyStop(this, reason);
} catch (Exception ignored) {}
}
}
public void notifyPSUpdate(int startRow, int startCol, int endRow, int endCol, boolean full) {
notifyPSUpdate(startRow, startCol, endRow, endCol, full, HOST_EVENTS, false);
}
public void notifyPSUpdate(int startRow, int startCol, int endRow, int endCol, boolean full, int type, boolean startPrinter) {
int r = (screen != null) ? screen.getRows() : 0;
int c = (screen != null) ? screen.getCols() : 0;
int cur = (screen != null) ? screen.getCursorAddress() : 0;
notifyPSEvent(new ECLPSEvent(this, ECLPSEvent.PS_UPDATE, startRow, startCol, endRow, endCol, cur, cur, r, c, full));
int ring = ringCounter.incrementAndGet();
ECLPSEvent evt = new ECLPSEvent(this, ECLPSEvent.PS_UPDATE, type, startRow, startCol, endRow, endCol,
cur, cur, r, c, full, cursorVisible, ring, startPrinter, null);
notifyPSEvent(evt);
}
public void notifyCursorMoved(int oldAddress, int newAddress) {
@@ -609,16 +909,22 @@ public class ECLPS implements ECLConstants {
int c = (screen != null) ? screen.getCols() : 0;
int row = (c > 0) ? newAddress / c : 0;
int col = (c > 0) ? newAddress % c : 0;
notifyPSEvent(new ECLPSEvent(this, ECLPSEvent.PS_CURSOR, row, col, row, col, oldAddress, newAddress, r, c, false));
int ring = ringCounter.incrementAndGet();
notifyPSEvent(new ECLPSEvent(this, ECLPSEvent.PS_CURSOR, USER_EVENTS, row, col, row, col,
oldAddress, newAddress, r, c, false, cursorVisible, ring, false, null));
}
public void notifyAlarm() {
notifyPSEvent(new ECLPSEvent(this, ECLPSEvent.PS_ALARM));
int ring = ringCounter.incrementAndGet();
notifyPSEvent(new ECLPSEvent(this, ECLPSEvent.PS_ALARM, HOST_EVENTS, 0, 0, 0, 0,
0, 0, 0, 0, false, cursorVisible, ring, false, null));
}
public void notifyScreenResized(int rows, int cols) {
int cur = (screen != null) ? screen.getCursorAddress() : 0;
notifyPSEvent(new ECLPSEvent(this, ECLPSEvent.PS_RESIZE, 0, 0, rows - 1, cols - 1, cur, cur, rows, cols, true));
int ring = ringCounter.incrementAndGet();
notifyPSEvent(new ECLPSEvent(this, ECLPSEvent.PS_RESIZE, HOST_EVENTS, 0, 0, rows - 1, cols - 1,
cur, cur, rows, cols, true, cursorVisible, ring, false, null));
}
/**
@@ -713,16 +1019,58 @@ public class ECLPS implements ECLConstants {
}
}
public synchronized int CheckBeforeSendKeys(String string) {
if (inputProcessor != null && inputProcessor.isKeyboardLocked()) {
return 1;
}
return 0;
}
public synchronized int CheckBeforeSendKeys(String string, int pos) {
return CheckBeforeSendKeys(string);
}
public synchronized int CheckBeforeSendKeys(String string, int row, int col) {
return CheckBeforeSendKeys(string);
}
public synchronized void BadgeReader(String string) throws ECLErr {
BadgeReader(string, getCursorPos() + 1);
}
public synchronized void BadgeReader(String string, int pos) throws ECLErr {
if (pos > getSize() || pos < 1) {
throw new ECLErr("ECLPS", "ECL0010", "\"pos\"", String.valueOf(pos));
}
setCursorPos(pos - 1);
SendKeys(string + "[enter]");
}
public synchronized void BadgeReader(String string, int row, int col) throws ECLErr {
BadgeReader(string, (row - 1) * getCols() + col);
}
public synchronized void asisBadgeReader(String string, String featureKey) throws ECLErr {
BadgeReader(string);
}
// ========== Synchronization & ECL Automation Waits ==========
/**
* Block until the specified screen descriptor conditions are met.
*/
public boolean waitForScreen(ECLScreenDesc desc) {
return waitForScreen(desc, -1L);
}
public boolean WaitForScreen(ECLScreenDesc desc) {
return waitForScreen(desc);
}
public boolean waitForScreen(ECLScreenDesc desc, long timeoutMs) {
if (desc == null) return true;
long limit = (timeoutMs <= 0) ? 120000L : timeoutMs;
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < timeoutMs) {
if (desc.Matches(this, null)) {
ECLOIA oia = (session != null) ? session.GetOIA() : null;
while (System.currentTimeMillis() - start < limit) {
if (desc.Matches(this, oia)) {
return true;
}
try {
@@ -732,13 +1080,43 @@ public class ECLPS implements ECLConstants {
return false;
}
}
return desc.Matches(this, null);
return desc.Matches(this, oia);
}
public boolean WaitForScreen(ECLScreenDesc desc, long timeoutMs) {
return waitForScreen(desc, timeoutMs);
}
public boolean waitWhileScreen(ECLScreenDesc desc) {
return waitWhileScreen(desc, -1L);
}
public boolean WaitWhileScreen(ECLScreenDesc desc) {
return waitWhileScreen(desc);
}
public boolean waitWhileScreen(ECLScreenDesc desc, long timeoutMs) {
if (desc == null) return true;
long limit = (timeoutMs <= 0) ? 120000L : timeoutMs;
long start = System.currentTimeMillis();
ECLOIA oia = (session != null) ? session.GetOIA() : null;
while (System.currentTimeMillis() - start < limit) {
if (!desc.Matches(this, oia)) {
return true;
}
try {
Thread.sleep(25);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
return !desc.Matches(this, oia);
}
public boolean WaitWhileScreen(ECLScreenDesc desc, long timeoutMs) {
return waitWhileScreen(desc, timeoutMs);
}
/**
* Block until the specified text appears anywhere on the presentation space.
*/
@@ -0,0 +1,51 @@
package haus.nightmare.lib3270j.ecl;
/**
* Presentation Space BIDI services interface conforming to IBM Host On-Demand ECL.
*/
public interface ECLPSBIDIServices {
String NOMINAL = "NOMINAL";
String NATIONAL = "NATIONAL";
String CONTEXTUAL = "CONTEXTUAL";
String VISUAL = "VISUAL";
String LOGICAL = "LOGICAL";
String LEFT_TO_RIGHT = "LEFTTORIGHT";
String RIGHT_TO_LEFT = "RIGHTTOLEFT";
String LAMALEF_ON = "LAMALEFON";
String LAMALEF_OFF = "LAMALEFOFF";
String RTLUNICODE_ON = "RTLUNICODEON";
String RTLUNICODE_OFF = "RTLUNICODEOFF";
String ROUNDTRIP_ON = "ON";
String ROUNDTRIP_OFF = "OFF";
void SetNumeralShape(String shape) throws ECLErr;
String GetNumeralShape();
void SetTextType(String type) throws ECLErr;
String GetTextType();
void SetTextOrientation(String orientation) throws ECLErr;
String GetTextOrientation();
void setMacroBidiEnabled(boolean enabled);
boolean isMacroBidiEnabled();
void SetRoundTrip(String rt) throws ECLErr;
String GetRoundTrip();
void SetBIDICursorPos(int pos, boolean visual) throws ECLErr;
void SetBIDICursorPos(int pos) throws ECLErr;
void SetBIDICursorPos(int row, int col) throws ECLErr;
void SetLamAlef(String mode) throws ECLErr;
String GetLamAlef();
void SetRTLUnicode(String mode) throws ECLErr;
String GetRTLUnicode();
void setNumericSwap(boolean swap);
boolean getNumericSwap();
void setSymmetricSwap(boolean swap);
boolean getSymmetricSwap();
}
@@ -4,11 +4,18 @@ import java.util.EventObject;
/**
* Event object dispatched on Presentation Space (ECLPS) modifications.
* Conforms 1:1 to IBM Host On-Demand ECLPSEvent specification.
*/
public class ECLPSEvent extends EventObject {
private static final long serialVersionUID = 1L;
// Standard IBM Host On-Demand event category masks
public static final int USER_EVENTS = 1;
public static final int HOST_EVENTS = 2;
public static final int ALL_EVENTS = 3;
// Granular presentation space event types
public static final int PS_UPDATE = 1;
public static final int PS_CURSOR = 2;
public static final int PS_ALARM = 3;
@@ -22,6 +29,7 @@ public class ECLPSEvent extends EventObject {
public static final int EVENT_CLOSE = PS_CLOSE;
private final int eventType;
private final int type;
private final int startRow;
private final int startCol;
private final int endRow;
@@ -31,11 +39,18 @@ public class ECLPSEvent extends EventObject {
private final int rows;
private final int cols;
private final boolean fullUpdate;
private final boolean cursorVisible;
private final int ringCounter;
private final boolean startPrinterBit;
private ECLPSUpdate psUpdate;
public ECLPSEvent(Object source, int eventType, int startRow, int startCol, int endRow, int endCol,
int oldCursorAddress, int newCursorAddress, int rows, int cols, boolean fullUpdate) {
super(source);
public ECLPSEvent(Object source, int eventType, int type, int startRow, int startCol,
int endRow, int endCol, int oldCursorAddress, int newCursorAddress,
int rows, int cols, boolean fullUpdate, boolean cursorVisible,
int ringCounter, boolean startPrinterBit, ECLPSUpdate psUpdate) {
super(source != null ? source : "ECLPS");
this.eventType = eventType;
this.type = (type != 0) ? type : HOST_EVENTS;
this.startRow = startRow;
this.startCol = startCol;
this.endRow = endRow;
@@ -45,30 +60,152 @@ public class ECLPSEvent extends EventObject {
this.rows = rows;
this.cols = cols;
this.fullUpdate = fullUpdate;
this.cursorVisible = cursorVisible;
this.ringCounter = ringCounter;
this.startPrinterBit = startPrinterBit;
this.psUpdate = psUpdate;
}
public ECLPSEvent(Object source, int eventType, int startRow, int startCol, int endRow, int endCol,
int oldCursorAddress, int newCursorAddress, int rows, int cols, boolean fullUpdate) {
this(source, eventType, HOST_EVENTS, startRow, startCol, endRow, endCol,
oldCursorAddress, newCursorAddress, rows, cols, fullUpdate, true, 0, false, null);
}
public ECLPSEvent(Object source, int eventType) {
this(source, eventType, 0, 0, 0, 0, 0, 0, 0, 0, true);
}
/**
* Returns the HoD event category (USER_EVENTS, HOST_EVENTS, or ALL_EVENTS).
*/
public int GetType() { return type; }
public int getType() { return type; }
/**
* Returns the granular event type (PS_UPDATE, PS_CURSOR, PS_ALARM, PS_RESIZE, PS_CLOSE).
*/
public int getEventType() { return eventType; }
/**
* Returns 0-based start row index.
*/
public int getStartRow() { return startRow; }
/**
* Returns 1-based start row index conforming to HoD specification.
*/
public int GetStartRow() { return startRow + 1; }
/**
* Returns 0-based start column index.
*/
public int getStartCol() { return startCol; }
/**
* Returns 1-based start column index conforming to HoD specification.
*/
public int GetStartCol() { return startCol + 1; }
/**
* Returns 0-based end row index.
*/
public int getEndRow() { return endRow; }
/**
* Returns 1-based end row index conforming to HoD specification.
*/
public int GetEndRow() { return endRow + 1; }
/**
* Returns 0-based end column index.
*/
public int getEndCol() { return endCol; }
/**
* Returns 1-based end column index conforming to HoD specification.
*/
public int GetEndCol() { return endCol + 1; }
/**
* Returns 0-based linear start position within presentation space.
*/
public int getStart() {
return (cols > 0) ? (startRow * cols + startCol) : 0;
}
/**
* Returns 1-based linear start position conforming to HoD specification.
*/
public int GetStart() {
return getStart() + 1;
}
/**
* Returns 0-based linear end position within presentation space.
*/
public int getEnd() {
return (cols > 0) ? (endRow * cols + endCol) : 0;
}
/**
* Returns 1-based linear end position conforming to HoD specification.
*/
public int GetEnd() {
return getEnd() + 1;
}
public int getOldCursorAddress() { return oldCursorAddress; }
public int getNewCursorAddress() { return newCursorAddress; }
public int getRows() { return rows; }
public int GetRows() { return rows; }
public int getCols() { return cols; }
public int GetCols() { return cols; }
public boolean isFullUpdate() { return fullUpdate; }
public boolean IsFullUpdate() { return fullUpdate; }
public boolean getCursorVisible() { return cursorVisible; }
public boolean GetCursorVisible() { return cursorVisible; }
public boolean isCursorVisible() { return cursorVisible; }
public int getRingCounter() { return ringCounter; }
public int GetRingCounter() { return ringCounter; }
public boolean isStartPrinterBit() { return startPrinterBit; }
public boolean IsStartPrinterBit() { return startPrinterBit; }
public synchronized ECLPSUpdate getECLPSUpdate() {
if (psUpdate == null) {
ECLPS p = getPS();
String snippet = "";
if (p != null && cols > 0 && rows > 0) {
try {
snippet = p.getString(getStart(), Math.max(1, getEnd() - getStart() + 1));
} catch (Exception ignored) {}
}
psUpdate = new ECLPSUpdate(p, startRow, startCol, endRow, endCol, getStart(), getEnd(), fullUpdate, snippet);
}
return psUpdate;
}
public ECLPSUpdate GetECLPSUpdate() {
return getECLPSUpdate();
}
public ECLPS getPS() {
return (getSource() instanceof ECLPS) ? (ECLPS) getSource() : null;
}
public ECLPS GetPS() {
return getPS();
}
@Override
public String toString() {
return String.format("ECLPSEvent[type=%d, start=(%d,%d), end=(%d,%d), full=%b]",
eventType, startRow, startCol, endRow, endCol, fullUpdate);
return String.format("ECLPSEvent[type=%d, eventType=%d, start=(%d,%d), end=(%d,%d), full=%b, ring=%d]",
type, eventType, startRow, startCol, endRow, endCol, fullUpdate, ringCounter);
}
}
@@ -0,0 +1,62 @@
package haus.nightmare.lib3270j.ecl;
import java.awt.Image;
import java.awt.Rectangle;
/**
* Conforms to IBM Host On-Demand ECLPSGraphicsEvent.
*/
public class ECLPSGraphicsEvent {
public static final int GRAPHICS_CURSOR_ON = 1;
public static final int GRAPHICS_CURSOR_OFF = 2;
public static final int GRAPHICS_ACTIVATED = 3;
public static final int GRAPHICS_DEACTIVATED = 4;
public static final int GRAPHICS_UPDATED = 5;
private int id;
private Image image;
private Rectangle rect;
private ECLPS source;
public ECLPSGraphicsEvent(ECLPS source, int id) {
this.source = source;
this.id = id;
}
public ECLPSGraphicsEvent(ECLPS source, int id, Image image) {
this.source = source;
this.id = id;
this.image = image;
}
public ECLPSGraphicsEvent(ECLPS source, int id, Image image, Rectangle rectangle) {
this.source = source;
this.id = id;
this.image = image;
this.rect = rectangle;
}
public void setSource(ECLPS source) { this.source = source; }
public ECLPS getSource() { return this.source; }
public ECLPS GetSource() { return this.source; }
public ECLPS getPS() { return this.source; }
public ECLPS GetPS() { return this.source; }
public void setID(int id) { this.id = id; }
public int getID() { return this.id; }
public int GetID() { return this.id; }
public void setImage(Image image) { this.image = image; }
public Image getImage() { return this.image; }
public Image GetImage() { return this.image; }
public void setRectangle(Rectangle rect) { this.rect = rect; }
public Rectangle getRectangle() { return this.rect; }
public Rectangle GetRectangle() { return this.rect; }
@Override
public String toString() {
return String.format("ECLPSGraphicsEvent[id=%d, rect=%s, hasImage=%b]",
id, rect, image != null);
}
}

Some files were not shown because too many files have changed in this diff Show More