All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.tn5250j.framework.tn5250.Screen5250 Maven / Gradle / Ivy

There is a newer version: 0.7.6.4
Show newest version
/**
 * Title: Screen5250.java
 * Copyright:   Copyright (c) 2001 - 2004
 * Company:
 * @author  Kenneth J. Pouncey
 * @version 0.5
 *
 * Description:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this software; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307 USA
 *
 */
package org.tn5250j.framework.tn5250;

import static org.tn5250j.TN5250jConstants.*;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Vector;

import org.tn5250j.TN5250jConstants;
import org.tn5250j.event.ScreenListener;
import org.tn5250j.keyboard.KeyMnemonic;
import org.tn5250j.keyboard.KeyMnemonicResolver;
import org.tn5250j.tools.logging.TN5250jLogFactory;
import org.tn5250j.tools.logging.TN5250jLogger;

public class Screen5250 {

	// error codes to be sent to the host on an error
	private final static int ERR_CURSOR_PROTECTED = 0x05;
	private final static int ERR_INVALID_SIGN = 0x11;
	private final static int ERR_NO_ROOM_INSERT = 0x12;
	private final static int ERR_NUMERIC_ONLY = 0x09;
	private final static int ERR_DUP_KEY_NOT_ALLOWED = 0x19;
	private final static int ERR_NUMERIC_09 = 0x10;
	private final static int ERR_FIELD_MINUS = 0x16;
	private final static int ERR_FIELD_EXIT_INVALID = 0x18;
	private final static int ERR_ENTER_NO_ALLOWED = 0x20;
	private final static int ERR_MANDITORY_ENTER = 0x21;

	final static byte STATUS_SYSTEM = 1;
	final static byte STATUS_ERROR_CODE = 2;
	final static byte STATUS_VALUE_ON = 1;
	final static byte STATUS_VALUE_OFF = 2;

	final static int initAttr = 32;
	final static char initChar = 0;

	private final KeyMnemonicResolver keyMnemonicResolver = new KeyMnemonicResolver();
	private final TN5250jLogger log = TN5250jLogFactory.getLogger(this.getClass());

	private ScreenFields screenFields;
	private int lastAttr;
	private int lastPos;
	private int lenScreen;
	private KeyStrokenizer strokenizer;
	private tnvt sessionVT;
	private int numRows = 0;
	private int numCols = 0;

	public boolean cursorActive = false;
	public boolean cursorShown = false;
	private boolean keyProcessed = false;
	private Rect dirtyScreen = new Rect();

	public int homePos = 0;
	private int saveHomePos = 0;
	private String bufferedKeys;
	private boolean pendingInsert = false;

	private StringBuffer hsMore = new StringBuffer("More...");
	private StringBuffer hsBottom = new StringBuffer("Bottom");

	private boolean guiInterface = false;
	private boolean resetRequired = true;
	private boolean backspaceError = true;
	private boolean feError;

	// vector of listeners for changes to the screen.
	private Vector screenListeners = null;

	// Operator Information Area
	private ScreenOIA oia;

	// screen planes
	protected ScreenPlanes planes;

	//Added by Barry
	private StringBuffer keybuf;

	public Screen5250() {

		//Added by Barry
		this.keybuf = new StringBuffer();

		try {
			jbInit();
		} catch (Exception ex) {
			log.warn("In constructor: ", ex);
		}
	}

	void jbInit() throws Exception {

		lastAttr = 32;

		// default number of rows and columns
		numRows = 24;
		numCols = 80;

		setCursor(1, 1); // set initial cursor position

		oia = new ScreenOIA(this);
		oia.setKeyBoardLocked(true);

		lenScreen = numRows * numCols;

		planes = new ScreenPlanes(this,numRows);

		screenFields = new ScreenFields(this);
		strokenizer = new KeyStrokenizer();
	}

	protected ScreenPlanes getPlanes() {
		return planes;
	}

	public final ScreenOIA getOIA() {
		return oia;
	}

	protected final void setRowsCols(int rows, int cols) {

		int oldRows = numRows;
		int oldCols = numCols;

		// default number of rows and columns
		numRows = rows;
		numCols = cols;

		lenScreen = numRows * numCols;

		planes.setSize(rows);

		//  If they are not the same then we need to inform the listeners that
		//  the size changed.
		if (oldRows != numRows || oldCols != numCols)
			fireScreenSizeChanged();

	}


	public boolean isCursorActive() {
		return cursorActive;

	}

	public boolean isCursorShown() {
		return cursorShown;
	}

	public void setUseGUIInterface(boolean gui) {
		guiInterface = gui;
	}

	public void toggleGUIInterface() {
		guiInterface = !guiInterface;
	}

	public void setResetRequired(boolean reset) {
		resetRequired = reset;
	}

	public void setBackspaceError(boolean onError) {
		backspaceError = onError;
	}

	/**
	 * Copy and Paste support
	 * @param area a rectangle area
	 * @return a string, holding the text
	 */
	public final String copyText(Rect area) {
		StringBuilder sb = new StringBuilder();
		Rect workR = new Rect();
		workR.setBounds(area);
		log.debug("Copying " + workR);

		// loop through all the screen characters to send them to the clip board
		int m = workR.x;
		int i = 0;
		int t = 0;

		while (workR.height-- > 0) {
			t = workR.width;
			i = workR.y;
			while (t-- > 0) {
				// only copy printable characters (in this case >= ' ')
				char c = planes.getChar(getPos(m - 1, i - 1));
				if (c >= ' ' && (planes.screenExtended[getPos(m - 1, i - 1)] & EXTENDED_5250_NON_DSP)
						== 0)
					sb.append(c);
				else
					sb.append(' ');

				i++;
			}
			sb.append('\n');
			m++;
		}
		return sb.toString();
	}

	/**
	 * Copy and Paste support
	 *
	 * @param content the content
	 * @param special a flag
	 */
	public final void pasteText(String content, boolean special) {
		if (log.isDebugEnabled()) {
			log.debug("Pasting, special:"+special);
		}
		setCursorActive(false);

		StringBuilder sb = new StringBuilder(content);
		StringBuilder pd = new StringBuilder();

		// character counters within the string to be pasted.
		int nextChar = 0;
		int nChars = sb.length();

		int lr = getRow(lastPos);
		int lc = getCol(lastPos);
		resetDirty(lastPos);

		int cpos = lastPos;
		int length = getScreenLength();

		char c = 0;
		boolean setIt;

		// save our current place within the FFT.
		screenFields.saveCurrentField();

		for (int x = nextChar; x < nChars; x++) {

			c = sb.charAt(x);

			if ((c == '\n') || (c == '\r')) {

				log.info("pasted cr-lf>" + pd + "<");
				pd.setLength(0);
				// if we read in a cr lf in the data stream we need to go
				// to the starting column of the next row and start from there
				cpos = getPos(getRow(cpos)+1,lc);

				// If we go paste the end of the screen then let's start over from
				//   the beginning of the screen space.
				if (cpos > length)
					cpos = 0;
			}
			else {

				// we will default to set the character always.
				setIt = true;

				// If we are in a special paste scenario then we check for valid
				//   characters to paste.
				if (special && (!Character.isLetter(c) && !Character.isDigit(c)))
					setIt = false;

				// we will only push a character to the screen space if we are in
				//  a field
				if (isInField(cpos) && setIt) {
					planes.setChar(cpos, c);
					setDirty(cpos);
					screenFields.setCurrentFieldMDT();
				}
				//  If we placed a character then we go to the next position.
				if (setIt)
					cpos++;
				// we will append the information to our debug buffer.
				pd.append(c);
			}
		}

		// if we have anything else not logged then log it out.
		if (pd.length() > 0)
			log.info("pasted >" + pd + "<");

		// restore out position within the FFT.
		screenFields.restoreCurrentField();
		updateDirty();

		// restore our cursor position.
		setCursor(lr + 1, lc + 1);

		setCursorActive(true);

	}

	/**
	 * Copy and Paste support
	 *
	 * @param position start number
	 * @return a copied text
	 */
	public final String copyTextField(int position) {
		screenFields.saveCurrentField();
		isInField(position);
		String result = screenFields.getCurrentFieldText();
		screenFields.restoreCurrentField();
		return result;
	}

	/**
	 * @param formatOption formatting option to use
	 * @param area a rect angle
	 * @return vector string of numberic values
	 */
	public final Vector sumThem(boolean formatOption, Rect area) {

		StringBuilder sb = new StringBuilder();
		Rect workR = new Rect();
		workR.setBounds(area);

		log.debug("Summing");

		// obtain the decimal format for parsing
		DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();

		DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();

		if (formatOption) {
			dfs.setDecimalSeparator('.');
			dfs.setGroupingSeparator(',');
		} else {
			dfs.setDecimalSeparator(',');
			dfs.setGroupingSeparator('.');
		}

		df.setDecimalFormatSymbols(dfs);

		Vector sumVector = new Vector();

		// loop through all the screen characters to send them to the clip board
		int m = workR.x;
		int i = 0;
		int t = 0;

		double sum = 0.0;

		while (workR.height-- > 0) {
			t = workR.width;
			i = workR.y;
			while (t-- > 0) {

				// only copy printable numeric characters (in this case >= ' ')
				//				char c = screen[getPos(m - 1, i - 1)].getChar();
				char c = planes.getChar(getPos(m - 1, i - 1));
				//				if (((c >= '0' && c <= '9') || c == '.' || c == ',' || c == '-')
				//						&& !screen[getPos(m - 1, i - 1)].nonDisplay) {

				// TODO: update me here to implement the nonDisplay check as well
				if (((c >= '0' && c <= '9') || c == '.' || c == ',' || c == '-')) {
					sb.append(c);
				}
				i++;
			}

			if (sb.length() > 0) {
				if (sb.charAt(sb.length() - 1) == '-') {
					sb.insert(0, '-');
					sb.deleteCharAt(sb.length() - 1);
				}
				try {
					Number n = df.parse(sb.toString());
					sumVector.add(n.doubleValue());
					sum += n.doubleValue();
				} catch (ParseException pe) {
					log.warn(pe.getMessage() + " at "
							+ pe.getErrorOffset());
				}
			}
			sb.setLength(0);
			m++;
		}
		log.debug("" + sum);
		return sumVector;
	}

	/**
	 * This will move the screen cursor based on the mouse event.
	 *
	 * I do not think the checks here for the gui characters should be here but
	 * will leave them here for now until we work out the interaction.  This
	 * should be up to the gui frontend in my opinion.
	 *
	 * @param pos a position to move to
	 * @return flag
	 */
	public boolean moveCursor(int pos) {

		if (!oia.isKeyBoardLocked()) {

			if (pos < 0)
				return false;
			// because getRowColFromPoint returns offset of 1,1 we need to
			//    translate to offset 0,0
			//         pos -= (numCols + 1);

			int g = planes.getWhichGUI(pos);

			// lets check for hot spots
			if (g >= BUTTON_LEFT && g <= BUTTON_LAST) {
				StringBuffer aid = new StringBuffer();
				boolean aidFlag = true;
				switch (g) {
				case BUTTON_RIGHT:
				case BUTTON_MIDDLE:
					while (planes.getWhichGUI(--pos) != BUTTON_LEFT) {
					}
				case BUTTON_LEFT:
					if (planes.getChar(pos) == 'F') {
						pos++;
					} else
						aidFlag = false;

					if (planes.getChar(pos + 1) != '='
						&& planes.getChar(pos + 1) != '.'
							&& planes.getChar(pos + 1) != '/') {
						aid.append(planes.getChar(pos));
						aid.append(planes.getChar(pos + 1));
					} else {
						log.debug(" Hotspot clicked!!! we will send character "
								+ planes.getChar(pos));
						aid.append(planes.getChar(pos));
					}
					break;

				}
				if (aidFlag) {
					switch (g) {

					case BUTTON_LEFT_UP:
					case BUTTON_MIDDLE_UP:
					case BUTTON_RIGHT_UP:
					case BUTTON_ONE_UP:
					case BUTTON_SB_UP:
					case BUTTON_SB_GUIDE:
						sessionVT.sendAidKey(AID_ROLL_UP);
						break;

					case BUTTON_LEFT_DN:
					case BUTTON_MIDDLE_DN:
					case BUTTON_RIGHT_DN:
					case BUTTON_ONE_DN:
					case BUTTON_SB_DN:
					case BUTTON_SB_THUMB:

						sessionVT.sendAidKey(AID_ROLL_DOWN);
						break;
					case BUTTON_LEFT_EB:
					case BUTTON_MIDDLE_EB:
					case BUTTON_RIGHT_EB:
						StringBuffer eb = new StringBuffer();
						while (planes.getWhichGUI(pos--) != BUTTON_LEFT_EB)
							;
						while (planes.getWhichGUI(pos++) != BUTTON_RIGHT_EB) {
							eb.append(planes.getChar(pos));
						}
						org.tn5250j.tools.system.OperatingSystem.displayURL(eb
								.toString());
						// take out the log statement when we are sure it is
						// working
						log.info("Send to external Browser: " + eb.toString());
						break;

					default:
						int aidKey = Integer.parseInt(aid.toString());
						if (aidKey >= 1 && aidKey <= 12)
							sessionVT.sendAidKey(0x30 + aidKey);
						if (aidKey >= 13 && aidKey <= 24)
							sessionVT.sendAidKey(0xB0 + (aidKey - 12));
					}
				} else {
					if (screenFields.getCurrentField() != null) {
						int xPos = screenFields.getCurrentField().startPos();
						for (int x = 0; x < aid.length(); x++) {
							//                  System.out.println(sr + "," + (sc + x) + " " +
							// aid.charAt(x));
							planes.setChar(xPos + x , aid.charAt(x));
						}
						//                  System.out.println(aid);
						screenFields.setCurrentFieldMDT();
						sessionVT.sendAidKey(AID_ENTER);
					}

				}
				// return back to the calling routine that the cursor was not moved
				// but something else here was done like aid keys or the such
				return false;
			}
			// this is a note to not execute this code here when we
			// implement
			//   the remain after edit function option.
			//				if (gui.rubberband.isAreaSelected()) {
			//					gui.rubberband.reset();
			//					gui.repaint();
			//				} else {
			goto_XY(pos);
			isInField(lastPos);

			// return back to the calling object that the cursor was indeed
			//  moved with in the screen object
			return true;
			//				}
		}
		return false;
	}

	public void setVT(tnvt v) {

		sessionVT = v;
	}

	protected void setPrehelpState(boolean setErrorCode, boolean lockKeyboard,
			boolean unlockIfLocked) {
		if (oia.isKeyBoardLocked() && unlockIfLocked)
			oia.setKeyBoardLocked(false);
		else
			oia.setKeyBoardLocked(lockKeyboard);
		bufferedKeys = null;
		oia.setKeysBuffered(false);


	}

	/**
	 * Activate the cursor on screen
	 *
	 * @param activate a flag
	 */
	public void setCursorActive(boolean activate) {
		if (cursorActive && !activate) {
			setCursorOff();
			cursorActive = activate;
		} else {
			if (!cursorActive && activate) {
				cursorActive = activate;
				setCursorOn();
			}
		}
	}

	public void setCursorOn() {
		cursorShown = true;
		updateCursorLoc();
	}

	public void setCursorOff() {
		cursorShown = false;
		updateCursorLoc();
	}

	/**
	 *
	 */
	private void updateCursorLoc() {
		if (cursorActive) {
			fireCursorChanged(3);
		}
	}

	//Added by Barry
	public String getKeys() {
		String result = this.keybuf.toString();
		this.keybuf = new StringBuffer();
		return result;
	}

	public synchronized void sendKeys(KeyMnemonic keyMnemonic) {
		sendKeys(keyMnemonic.mnemonic);
	}

	/**
	 * The sendKeys method sends a string of keys to the virtual screen. This
	 * method acts as if keystrokes were being typed from the keyboard. The
	 * keystrokes will be sent to the location given. The string being passed
	 * can also contain mnemonic values such as [enter] enter key,[tab] tab key,
	 * [pf1] pf1 etc...
	 *
	 * These will be processed as if you had pressed these keys from the
	 * keyboard. All the valid special key values are contained in the MNEMONIC
	 * enumeration. See also {@link KeyMnemonic}
	 *
	 * @param text The string of characters to be sent
	 * @see #sendAid
	 */
	public synchronized void sendKeys(String text) {

		this.keybuf.append(text);

		if (isStatusErrorCode() && !resetRequired) {
			setCursorActive(false);
			simulateMnemonic(KeyMnemonic.RESET.value);
			setCursorActive(true);
		}

		if (oia.isKeyBoardLocked()) {
			if (KeyMnemonic.RESET.mnemonic.equals(text)
					|| KeyMnemonic.SYSREQ.mnemonic.equals(text)
					|| KeyMnemonic.ATTN.mnemonic.equals(text)) {
				setCursorActive(false);
				simulateMnemonic(keyMnemonicResolver.findMnemonicValue(text));
				setCursorActive(true);

			} else {
				if (isStatusErrorCode()) {
					sessionVT.signalBell();
					return;
				}

				oia.setKeysBuffered(true);

				if (bufferedKeys == null) {
					bufferedKeys = text;
					return;
				}
				bufferedKeys += text;
				return;
			}

		} else {

			if (oia.isKeysBuffered()) {
				if (bufferedKeys != null) {
					text = bufferedKeys + text;
				}
				//            if (text.length() == 0) {
				oia.setKeysBuffered(false);
				//            }
				bufferedKeys = null;

			}
			// check to see if position is in a field and if it is then change
			//   current field to that field
			isInField(lastPos, true);
			if (text.length() == 1 && !text.equals("[") && !text.equals("]")) {
				setCursorActive(false);
				simulateKeyStroke(text.charAt(0));
				setCursorActive(true);
			} else {

				strokenizer.setKeyStrokes(text);
				String s;
				boolean done = false;

				setCursorActive(false);
				while (!done) {
					if (strokenizer.hasMoreKeyStrokes()) {

						// check to see if position is in a field and if it is
						// then change
						//   current field to that field
						isInField(lastPos, true);
						s = strokenizer.nextKeyStroke();
						if (s.length() == 1) {
							simulateKeyStroke(s.charAt(0));
						} else {
							simulateMnemonic(keyMnemonicResolver.findMnemonicValue(s));
						}

						if (oia.isKeyBoardLocked()) {

							bufferedKeys = strokenizer
							.getUnprocessedKeyStroked();
							if (bufferedKeys != null) {
								oia.setKeysBuffered(true);

							}
							done = true;
						}

					}	else {
						done = true;
					}
				}
				setCursorActive(true);
			}
		}
	}

	/**
	 * The sendAid method sends an "aid" keystroke to the virtual screen. These
	 * aid keys can be thought of as special keystrokes, like the Enter key,
	 * PF1-24 keys or the Page Up key. All the valid special key values are
	 * contained in the AID_ enumeration:
	 *
	 * @param aidKey
	 *            The aid key to be sent to the host
	 *
	 */
	public void sendAid(int aidKey) {

		sessionVT.sendAidKey(aidKey);
	}

	/**
	 * Restores the error line and sets the error mode off.
	 *
	 */
	protected void resetError() {

		restoreErrorLine();
		setStatus(STATUS_ERROR_CODE, STATUS_VALUE_OFF, "");

	}

	protected boolean simulateMnemonic(int mnem) {

		boolean simulated = false;

		switch (mnem) {

		case AID_CLEAR:
		case AID_ENTER:
		case AID_PF1:
		case AID_PF2:
		case AID_PF3:
		case AID_PF4:
		case AID_PF5:
		case AID_PF6:
		case AID_PF7:
		case AID_PF8:
		case AID_PF9:
		case AID_PF10:
		case AID_PF11:
		case AID_PF12:
		case AID_PF13:
		case AID_PF14:
		case AID_PF15:
		case AID_PF16:
		case AID_PF17:
		case AID_PF18:
		case AID_PF19:
		case AID_PF20:
		case AID_PF21:
		case AID_PF22:
		case AID_PF23:
		case AID_PF24:
		case AID_ROLL_DOWN:
		case AID_ROLL_UP:
		case AID_ROLL_LEFT:
		case AID_ROLL_RIGHT:

			if (!screenFields.isCanSendAid()) {
				displayError(ERR_ENTER_NO_ALLOWED);
			} else
				sendAid(mnem);
			simulated = true;

			break;
		case AID_HELP:
			sessionVT.sendHelpRequest();
			simulated = true;
			break;

		case AID_PRINT:
			sessionVT.hostPrint(1);
			simulated = true;
			break;

		case BACK_SPACE:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				if (screenFields.getCurrentField().startPos() == lastPos) {
					if (backspaceError)
						displayError(ERR_CURSOR_PROTECTED);
					else {
						gotoFieldPrev();
						goto_XY(screenFields.getCurrentField().endPos());
						updateDirty();
					}
				}
				else {
					screenFields.getCurrentField().getKeyPos(lastPos);
					screenFields.getCurrentField().changePos(-1);
					resetDirty(screenFields.getCurrentField().getCurrentPos());
					shiftLeft(screenFields.getCurrentField().getCurrentPos());
					updateDirty();
					screenFields.setCurrentFieldMDT();

					simulated = true;
				}
			} else {
				displayError(ERR_CURSOR_PROTECTED);

			}
			break;
		case BACK_TAB:

			if (screenFields.getCurrentField() != null
					&& screenFields.isCurrentFieldHighlightedEntry()) {
				resetDirty(screenFields.getCurrentField().startPos);
				gotoFieldPrev();
				updateDirty();
			} else
				gotoFieldPrev();

			if (screenFields.isCurrentFieldContinued()) {
				do {
					gotoFieldPrev();
				} while (screenFields.isCurrentFieldContinuedMiddle()
						|| screenFields.isCurrentFieldContinuedLast());
			}
			isInField(lastPos);
			simulated = true;
			break;
		case UP:
		case MARK_UP:
			process_XY(lastPos - numCols);
			simulated = true;
			break;
		case DOWN:
		case MARK_DOWN:
			process_XY(lastPos + numCols);
			simulated = true;
			break;
		case LEFT:
		case MARK_LEFT:
			process_XY(lastPos - 1);
			simulated = true;
			break;
		case RIGHT:
		case MARK_RIGHT:
			process_XY(lastPos + 1);
			simulated = true;
			break;
		case NEXTWORD:
			gotoNextWord();
			simulated = true;
			break;
		case PREVWORD:
			gotoPrevWord();
			simulated = true;
			break;
		case DELETE:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				resetDirty(lastPos);
				screenFields.getCurrentField().getKeyPos(lastPos);
				shiftLeft(screenFields.getCurrentFieldPos());
				screenFields.setCurrentFieldMDT();
				updateDirty();
				simulated = true;
			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case TAB:

			if (screenFields.getCurrentField() != null
					&& !screenFields.isCurrentFieldContinued()) {
				if (screenFields.isCurrentFieldHighlightedEntry()) {
					resetDirty(screenFields.getCurrentField().startPos);
					gotoFieldNext();
					updateDirty();
				} else
					gotoFieldNext();
			} else {
				do {
					gotoFieldNext();
				} while (screenFields.getCurrentField() != null
						&& (screenFields.isCurrentFieldContinuedMiddle() || screenFields
								.isCurrentFieldContinuedLast()));
			}

			isInField(lastPos);
			simulated = true;

			break;
		case EOF:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {
				int where = endOfField(screenFields.getCurrentField()
						.startPos(), true);
				if (where > 0) {
					setCursor((where / numCols) + 1, (where % numCols) + 1);
				}
				simulated = true;
			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}
			resetDirty(lastPos);

			break;
		case ERASE_EOF:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				int where = lastPos;
				resetDirty(lastPos);
				if (fieldExit()) {
					screenFields.setCurrentFieldMDT();
					if (!screenFields.isCurrentFieldContinued()) {
						gotoFieldNext();
					} else {
						do {
							gotoFieldNext();
							if (screenFields.isCurrentFieldContinued())
								fieldExit();
						} while (screenFields.isCurrentFieldContinuedMiddle()
								|| screenFields.isCurrentFieldContinuedLast());
					}
				}
				updateDirty();
				goto_XY(where);
				simulated = true;

			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case ERASE_FIELD:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				int where = lastPos;
				lastPos = screenFields.getCurrentField().startPos();
				resetDirty(lastPos);
				if (fieldExit()) {
					screenFields.setCurrentFieldMDT();
					if (!screenFields.isCurrentFieldContinued()) {
						gotoFieldNext();
					} else {
						do {
							gotoFieldNext();
							if (screenFields.isCurrentFieldContinued())
								fieldExit();
						} while (screenFields.isCurrentFieldContinuedMiddle()
								|| screenFields.isCurrentFieldContinuedLast());
					}
				}
				updateDirty();
				goto_XY(where);
				simulated = true;

			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case INSERT:
			// we toggle it
			oia.setInsertMode(oia.isInsertMode() ? false : true);
			break;
		case HOME:
			// position to the home position set
			if (lastPos + numCols + 1 != homePos) {
				goto_XY(homePos - numCols - 1);
				// now check if we are in a field
				isInField(lastPos);
			} else
				gotoField(1);
			break;
		case KEYPAD_0:
			simulated = simulateKeyStroke('0');
			break;
		case KEYPAD_1:
			simulated = simulateKeyStroke('1');
			break;
		case KEYPAD_2:
			simulated = simulateKeyStroke('2');
			break;
		case KEYPAD_3:
			simulated = simulateKeyStroke('3');
			break;
		case KEYPAD_4:
			simulated = simulateKeyStroke('4');
			break;
		case KEYPAD_5:
			simulated = simulateKeyStroke('5');
			break;
		case KEYPAD_6:
			simulated = simulateKeyStroke('6');
			break;
		case KEYPAD_7:
			simulated = simulateKeyStroke('7');
			break;
		case KEYPAD_8:
			simulated = simulateKeyStroke('8');
			break;
		case KEYPAD_9:
			simulated = simulateKeyStroke('9');
			break;
		case KEYPAD_PERIOD:
			simulated = simulateKeyStroke('.');
			break;
		case KEYPAD_COMMA:
			simulated = simulateKeyStroke(',');
			break;
		case KEYPAD_MINUS:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				int s = screenFields.getCurrentField().getFieldShift();
				if (s == 3 || s == 5 || s == 7) {
					planes.setChar(lastPos,'-');

					resetDirty(lastPos);
					advancePos();
					if (fieldExit()) {
						screenFields.setCurrentFieldMDT();
						if (!screenFields.isCurrentFieldContinued()) {
							gotoFieldNext();
						} else {
							do {
								gotoFieldNext();
							} while (screenFields
									.isCurrentFieldContinuedMiddle()
									|| screenFields
									.isCurrentFieldContinuedLast());
						}
						simulated = true;
						updateDirty();
						if (screenFields.isCurrentFieldAutoEnter())
							sendAid(AID_ENTER);

					}
				} else {
					displayError(ERR_FIELD_MINUS);

				}
			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case FIELD_EXIT:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				resetDirty(lastPos);

				boolean autoFE = screenFields.isCurrentFieldAutoEnter();

				if (fieldExit()) {
					screenFields.setCurrentFieldMDT();
					if (!screenFields.isCurrentFieldContinued() &&
							!screenFields.isCurrentFieldAutoEnter()) {
						gotoFieldNext();
					} else {
						do {
							gotoFieldNext();
							if (screenFields.isCurrentFieldContinued())
								fieldExit();
						} while (screenFields.isCurrentFieldContinuedMiddle()
								|| screenFields.isCurrentFieldContinuedLast());
					}
				}

				updateDirty();
				simulated = true;
				if (autoFE)
					sendAid(AID_ENTER);

			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case FIELD_PLUS:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				resetDirty(lastPos);

				boolean autoFE = screenFields.isCurrentFieldAutoEnter();
				if (fieldExit()) {
					screenFields.setCurrentFieldMDT();
					if (!screenFields.isCurrentFieldContinued() &&
							!screenFields.isCurrentFieldAutoEnter()) {
						gotoFieldNext();
					} else {
						do {
							gotoFieldNext();
						} while (screenFields.isCurrentFieldContinuedMiddle()
								|| screenFields.isCurrentFieldContinuedLast());
					}
				}
				updateDirty();
				simulated = true;

				if (autoFE)
					sendAid(AID_ENTER);

			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case FIELD_MINUS:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				int s = screenFields.getCurrentField().getFieldShift();
				if (s == 3 || s == 5 || s == 7) {
					planes.setChar(lastPos, '-');

					resetDirty(lastPos);
					advancePos();

					boolean autoFE = screenFields.isCurrentFieldAutoEnter();

					if (fieldExit()) {
						screenFields.setCurrentFieldMDT();
						if (!screenFields.isCurrentFieldContinued()
								&& !screenFields.isCurrentFieldAutoEnter()) {
							gotoFieldNext();
						}
						else {
							do {
								gotoFieldNext();
							}
							while (screenFields.isCurrentFieldContinuedMiddle()
									|| screenFields.isCurrentFieldContinuedLast());
						}
					}
					updateDirty();
					simulated = true;
					if (autoFE)
						sendAid(AID_ENTER);

				}
				else {
					displayError(ERR_FIELD_MINUS);

				}
			}
			else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case BOF:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {
				int where = screenFields.getCurrentField().startPos();
				if (where > 0) {
					goto_XY(where);
				}
				simulated = true;
			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}
			resetDirty(lastPos);

			break;
		case SYSREQ:
			sessionVT.systemRequest();
			simulated = true;
			break;
		case RESET:
			if (isStatusErrorCode()) {
				resetError();
				isInField(lastPos);
				updateDirty();
			} else {
				setPrehelpState(false, oia.isKeyBoardLocked(), false);
			}
			simulated = true;
			break;
		case ATTN:
			sessionVT.sendAttentionKey();
			simulated = true;
			break;
		case DUP_FIELD:
			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				if (screenFields.isCurrentFieldDupEnabled()) {
					resetDirty(lastPos);
					screenFields.getCurrentField().setFieldChar(lastPos,
							(char) 0x1C);
					screenFields.setCurrentFieldMDT();
					gotoFieldNext();
					updateDirty();
					simulated = true;
				} else {
					displayError(ERR_DUP_KEY_NOT_ALLOWED);
				}
			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

			break;
		case NEW_LINE:
			if (screenFields.getSize() > 0) {
				int startRow = getRow(lastPos) + 1;
				int startPos = lastPos;

				if (startRow == getRows())
					startRow = 0;

				setCursor(++startRow, 1);

				if (!isInField() && screenFields.getCurrentField() != null
						&& !screenFields.isCurrentFieldBypassField()) {
					while (!isInField()
							&& screenFields.getCurrentField() != null
							&& !screenFields.isCurrentFieldBypassField()) {

						// lets keep going
						advancePos();

						// Have we looped the screen?
						if (lastPos == startPos) {
							// if so then go back to starting point
							goto_XY(startPos);
							break;
						}
					}
				}
			}
			simulated = true;
			break;
		case FAST_CURSOR_DOWN:
			int rowNow = (getCurrentRow()-1) + 3;
			if (rowNow > getRows()-1)
				rowNow = rowNow - getRows();
			this.goto_XY(getPos(rowNow,getCurrentCol()-1));
			simulated = true;
			break;
		case FAST_CURSOR_UP:
			rowNow = (getCurrentRow()-1) - 3;
			if (rowNow < 0)
				rowNow = (getRows()) + rowNow;
			this.goto_XY(getPos(rowNow,getCurrentCol()-1));
			simulated = true;
			break;
		case FAST_CURSOR_LEFT:
			int colNow = (getCurrentCol()-1) - 3;
			rowNow = getCurrentRow()-1;
			if (colNow <= 0) {
				colNow = getColumns() + colNow;
				rowNow--;
			}
			if (rowNow < 0)
				rowNow = getRows() - 1;

			process_XY(getPos(rowNow,colNow));
			simulated = true;
			break;
		case FAST_CURSOR_RIGHT:
			colNow = (getCurrentCol()-1) + 3;
			rowNow = getCurrentRow()-1;
			if (colNow >= getColumns()) {
				colNow = colNow - getColumns();
				rowNow++;
			}
			if (rowNow > getRows() - 1)
				rowNow = getRows() - rowNow;

			process_XY(getPos(rowNow,colNow));
			simulated = true;
			break;
		default:
			log.info(" Mnemonic not supported " + mnem);
			break;

		}

		return simulated;
	}

	protected boolean simulateKeyStroke(char c) {

		if (isStatusErrorCode() && !Character.isISOControl(c) && !keyProcessed) {
			if (resetRequired) return false;
			resetError();
		}

		boolean updateField = false;
		boolean numericError = false;
		boolean updatePos = false;
		boolean autoEnter = false;

		if (!Character.isISOControl(c)) {

			if (screenFields.getCurrentField() != null
					&& screenFields.withinCurrentField(lastPos)
					&& !screenFields.isCurrentFieldBypassField()) {

				if (screenFields.isCurrentFieldFER()
						&& !screenFields.withinCurrentField(screenFields
								.getCurrentFieldPos())
								&& lastPos == screenFields.getCurrentField().endPos()
								&& screenFields.getCurrentFieldPos() > screenFields
								.getCurrentField().endPos()) {

					displayError(ERR_FIELD_EXIT_INVALID);
					feError = true;
					return false;
				}

				switch (screenFields.getCurrentFieldShift()) {
				case 0: // Alpha shift
				case 2: // Numeric Shift
				case 4: // Kakana Shift
					updateField = true;
					break;
				case 1: // Alpha Only
					if (Character.isLetter(c) || c == ',' || c == '-'
						|| c == '.' || c == ' ')
						updateField = true;
					break;
				case 3: // Numeric only
					if (Character.isDigit(c) || c == '+' || c == ','
						|| c == '-' || c == '.' || c == ' ')
						updateField = true;
					else
						numericError = true;
					break;
				case 5: // Digits only
					if (Character.isDigit(c))
						updateField = true;
					else
						displayError(ERR_NUMERIC_09);
					break;
				case 7: // Signed numeric
					if (Character.isDigit(c) || c == '+' || c == '-')
						if (lastPos == screenFields.getCurrentField().endPos()
								&& (c != '+' && c != '-'))
							displayError(ERR_INVALID_SIGN);
						else
							updateField = true;
					else
						displayError(ERR_NUMERIC_09);
					break;
				}

				if (updateField) {
					if (screenFields.isCurrentFieldToUpper())
						c = Character.toUpperCase(c);

					updatePos = true;
					resetDirty(lastPos);

					if (oia.isInsertMode()) {
						if (endOfField(false) != screenFields.getCurrentField()
								.endPos())
							shiftRight(lastPos);
						else {

							displayError(ERR_NO_ROOM_INSERT);
							updatePos = false;
						}

					}

					if (updatePos) {
						screenFields.getCurrentField().getKeyPos(
								getRow(lastPos), getCol(lastPos));
						screenFields.getCurrentField().changePos(1);

						planes.setChar(lastPos,c);

						screenFields.setCurrentFieldMDT();

						// if we have gone passed the end of the field then goto
						// the next field
						if (!screenFields.withinCurrentField(screenFields
								.getCurrentFieldPos())) {
							if (screenFields.isCurrentFieldAutoEnter()) {
								autoEnter = true;
							} else if (!screenFields.isCurrentFieldFER())
								gotoFieldNext();
							else {
								//                        screenFields.getCurrentField().changePos(1);
								//
								//                        if (screenFields.
								//                        cursorPos == endPos)
								//                           System.out.println("end of field");
								//
								//                        feError != feError;
								//                        if (feError)
								//                           displayError(ERR_FIELD_EXIT_INVALID);
							}

						} else
							setCursor(screenFields.getCurrentField()
									.getCursorRow() + 1, screenFields
									.getCurrentField().getCursorCol() + 1);

					}

					fireScreenChanged(1);

					if (autoEnter)
						sendAid(AID_ENTER);
				} else {
					if (numericError) {
						displayError(ERR_NUMERIC_ONLY);
					}
				}
			} else {
				displayError(ERR_CURSOR_PROTECTED);
			}

		}
		return updatePos;
	}

	/**
	 * Method: endOfField
	 * 

* * convenience method that call endOfField with lastRow lastCol and passes * the posSpace to that method * * @param posSpace * value of type boolean - specifying to return the position of * the the last space or not * @return a value of type int - the screen postion (row * columns) + col * */ private int endOfField(boolean posSpace) { return endOfField(lastPos, posSpace); } /** * Method: endOfField *

* * gets the position of the last character of the current field posSpace * parameter tells the routine whether to return the position of the last * space ( <= ' ') or the last non space posSpace == true last occurrence of * char <= ' ' posSpace == false last occurrence of char > ' ' * * @param pos * value of type int - position to start from * @param posSpace * value of type boolean - specifying to return the position of * the the last space or not * @return a value of type int - the screen postion (row * columns) + col * */ private int endOfField(int pos, boolean posSpace) { int endPos = screenFields.getCurrentField().endPos(); int fePos = endPos; // get the number of characters to the right int count = endPos - pos; // first lets get the real ending point without spaces and the such while (planes.getChar(endPos) <= ' ' && count-- > 0) { endPos--; } if (endPos == fePos) { return endPos; } screenFields.getCurrentField().getKeyPos(endPos); if (posSpace) screenFields.getCurrentField().changePos(+1); return screenFields.getCurrentFieldPos(); } private boolean fieldExit() { int pos = lastPos; boolean mdt = false; int end = endOfField(false); // get the ending position of the first // non blank character in field ScreenField sf = screenFields.getCurrentField(); if (sf.isMandatoryEnter() && end == sf.startPos()) { displayError(ERR_MANDITORY_ENTER); return false; } // save off the current pos of the field for checking field exit required // positioning. the getKeyPos resets this information so it is useless // for comparing if we are positioned passed the end of field. // Maybe this should be changed to not update the current cursor position // of the field. int currentPos = sf.getCurrentPos(); // get the number of characters to the right int count = (end - sf.startPos()) - sf.getKeyPos(pos); if (count == 0 && sf.isFER()) { if (currentPos > sf.endPos()) { mdt = true; return mdt; } } for (; count >= 0; count--) { planes.setChar(pos, initChar); setDirty(pos); pos++; mdt = true; } // This checks for a field minus because a field minus places // a negative sign and then advances a position. If it is the // end of the field where the minus is placed then this offset will // place the count as -1. if (count == -1) { int s = sf.getFieldShift(); if (s == 3 || s == 5 || s == 7) { mdt = true; } } int adj = sf.getAdjustment(); if (adj != 0) { switch (adj) { case 5: rightAdjustField('0'); sf.setRightAdjusted(); break; case 6: rightAdjustField(' '); sf.setRightAdjusted(); break; case 7: sf.setManditoryEntered(); break; } } else { // we need to right adjust signed numeric fields as well. if (sf.isSignedNumeric()) { rightAdjustField(' '); } } return mdt; } private void rightAdjustField(char fill) { int end = endOfField(false); // get the ending position of the first // non blank character in field // get the number of characters to the right int count = screenFields.getCurrentField().endPos() - end; // subtract 1 from count for signed numeric - note for later if (screenFields.getCurrentField().isSignedNumeric()) { if (planes.getChar(end -1) != '-') count--; } int pos = screenFields.getCurrentField().startPos(); while (count-- >= 0) { shiftRight(pos); planes.setChar(pos,fill); setDirty(pos); } } private void shiftLeft(int sPos) { int endPos = 0; int pos = sPos; int pPos = sPos; ScreenField sf = screenFields.getCurrentField(); int end; int count; do { end = endOfField(pPos, false); // get the ending position of the // first // non blank character in field count = (end - screenFields.getCurrentField().startPos()) - screenFields.getCurrentField().getKeyPos(pPos); // now we loop through and shift the remaining characters to the // left while (count-- > 0) { pos++; planes.setChar(pPos,planes.getChar(pos)); setDirty(pPos); pPos = pos; } if (screenFields.isCurrentFieldContinued()) { gotoFieldNext(); if (screenFields.getCurrentField().isContinuedFirst()) break; pos = screenFields.getCurrentField().startPos(); planes.setChar(pPos,planes.getChar(pos)); setDirty(pPos); pPos = pos; } } while (screenFields.isCurrentFieldContinued() && !screenFields.getCurrentField().isContinuedFirst()); if (end >= 0 && count >= -1) { endPos = end; } else { endPos = sPos; } screenFields.setCurrentField(sf); planes.setChar(endPos,initChar); setDirty(endPos); goto_XY(screenFields.getCurrentFieldPos()); sf = null; } private void shiftRight(int sPos) { int end = endOfField(true); // get the ending position of the first // non blank character in field int pos = end; int pPos = end; int count = end - sPos; // now we loop through and shift the remaining characters to the right while (count-- > 0) { pos--; planes.setChar(pPos, planes.getChar(pos)); setDirty(pPos); pPos = pos; } } public int getRow(int pos) { // if (pos == 0) // return 1; int row = pos / numCols; if (row < 0) { row = lastPos / numCols; } if (row > (lenScreen / numCols) - 1) row = (lenScreen / numCols) - 1; return row; } public int getCol(int pos) { int col = pos % (getColumns()); if (col > 0) return col; return 0; } /** * This routine is 0 based offset. So to get row 20,1 then pass row 19,0 * * @param row number of the row * @param col number of the column * @return number of the position */ public int getPos(int row, int col) { return (row * numCols) + col; } /** * Current position is based on offsets of 1,1 not 0,0 of the current * position of the screen * * @return int the current position */ public int getCurrentPos() { // return lastPos + numCols + 1; return lastPos + 1; } /** * I got this information from a tcp trace of each error. I could not find * any documenation for this. Maybe there is but I could not find it. If * anybody finds this documention could you please send me a copy. Please * note that I did not look that hard either. *

* 0000: 00 50 73 1D 89 81 00 50 DA 44 C8 45 08 00 45 00 .Ps....P.D.E..E. *

*

* 0010: 00 36 E9 1C 40 00 80 06 9B F9 C1 A8 33 58 C0 A8 [email protected].. *

*

* 0020: C0 02 06 0E 00 17 00 52 6E 88 73 40 DE CB 50 18 [email protected]. *

*

* 0030: 20 12 3C 53 00 00 00 0C 12 A0 00 00 04 01 00 00 . *

* 0040: 00 05 FF EF .... ----------|| The 00 XX is the code to be sent. I * found the following

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
ERR_CURSOR_PROTECTED0x05
ERR_INVALID_SIGN0x11
ERR_NO_ROOM_INSERT0x12
ERR_NUMERIC_ONLY0x09
ERR_NUMERIC_090x10
ERR_FIELD_MINUS0x16
ERR_ENTER_NOT_ALLOWED0x20
ERR_MANDITORY_ENTER0x21
ERR_ENTER_NOT_ALLOWED0x20
I am tired of typing and they should be self explanitory. Finding * them in the first place was the pain. *

* * @param ec error code */ private void displayError(int ec) { saveHomePos = homePos; homePos = lastPos + numCols + 1; pendingInsert = true; sessionVT.sendNegResponse2(ec); } private void process_XY(int pos) { if (pos < 0) pos = lenScreen + pos; if (pos > lenScreen - 1) pos = pos - lenScreen; // if there was a field exit error then we need to treat the movement // of the cursor in a special way that equals that of Client Access. // If the cursor is moved from the field then we need to reset the // position within the field so that the last character can be typed // over again instead of sending the field exit error again. // We also need to reset the field exit error flag. // // How we know we have a field exit error is when the field position is // set beyond the end of the field and a character is then typed we can // not position that character. To reset this we need to set the next // position of the field to not be beyond the end of field but to the // last character. // // Now to make it work like Client Access if the cursor is a back space // then do not move the cursor but place it on the last field. All // other keys will reset the field position so that entering over the // last character will not cause an error but replace that character or // just plain move the cursor if the key was to do that. ScreenField sf = screenFields.getCurrentField(); if (feError) { feError = false; sf.changePos(-1); } else { if (sf != null&& sf.isFER()){ if ((sf.getCurrentPos() > sf.endPos())) { if (sf.withinField(pos)) { sf.getKeyPos(pos); return; } sf.getKeyPos(sf.endPos()); } } goto_XY(pos); } } public boolean isUsingGuiInterface() { return guiInterface; } /** * Convinience class to return if the cursor is in a field or not. * * @return true or false */ protected boolean isInField() { return isInField(lastPos, true); } /** * * Convinience class to return if the position that is passed is in a field * or not. If it is then the chgToField parameter will change the current * field to this field where the position indicates * * @param pos number * @param chgToField flag * @return true or false */ public boolean isInField(int pos, boolean chgToField) { return screenFields.isInField(pos, chgToField); } /** * * Convinience class to return if the position that is passed is in a field * or not. If it is then the field at this position becomes the current * working field * * @param pos number of position * @return true or false */ public boolean isInField(int pos) { return screenFields.isInField(pos, true); } /** * Convinience class to return if the position at row and column that is * passed is in a field or not. If it is then the field at this position * becomes the current working field. * * @param row number of the row * @param col number of the column * @return true or false */ public boolean isInField(int row, int col) { return isInField(row, col, true); } /** * * Convinience class to return if the position at row and column that is * passed is in a field or not. If it is then the chgToField parameter will * change the current field to this field where the row and column * indicates. * * @param row number of the row * @param col number of the column * @param chgToField flag * @return true or false */ public boolean isInField(int row, int col, boolean chgToField) { return screenFields.isInField((row * numCols) + col, chgToField); } /** * Gets the length of the screen - number of rows times number of columns * * @return int value of screen length */ public int getScreenLength() { return lenScreen; } /** * Get the number or rows available. * * @return number of rows */ public int getRows() { return numRows; } /** * Get the number of columns available. * * @return number of columns */ public int getColumns() { return numCols; } /** * Get the current row where the cursor is * * @return the cursor current row position 1,1 based */ public int getCurrentRow() { return (lastPos / numCols) + 1; } /** * Get the current column where the cursor is * * @return the cursor current column position 1,1 based */ public int getCurrentCol() { return (lastPos % numCols) + 1; } /** * The last position of the cursor on the screen - Note - position is based * 0,0 * * @return last position */ protected int getLastPos() { return lastPos; } /** * Hotspot More... string * * @return string literal of More... */ public StringBuffer getHSMore() { return hsMore; } /** * Hotspot Bottom string * * @return string literal of Bottom */ public StringBuffer getHSBottom() { return hsBottom; } /** * Return the whole screen represented as a character array * * @return character array containing the text * * Added by Luc - LDC * * Note to KJP - Have to ask what the difference is between this method and * the other */ public char[] getScreenAsAllChars() { char[] sac = new char[lenScreen]; char c; for (int x = 0; x < lenScreen; x++) { c = planes.getChar(x); // only draw printable characters (in this case >= ' ') if ((c >= ' ') && (!planes.isAttributePlace(x))) { sac[x] = c; // TODO: implement the underline check here // if (screen[x].underLine && c <= ' ') // sac[x] = '_'; } else sac[x] = ' '; } return sac; } /** * * Return the screen represented as a character array * * @return character array containing the text */ public char[] getScreenAsChars() { char[] sac = new char[lenScreen]; char c; for (int x = 0; x < lenScreen; x++) { c = planes.getChar(x); // only draw printable characters (in this case >= ' ') if ((c >= ' ') && (!planes.isAttributePlace(x))) { sac[x] = c; // TODO: implement the underline check here // if (screen[x].underLine && c <= ' ') // sac[x] = '_'; } else sac[x] = ' '; } return sac; } public char[] getData(int startRow, int startCol, int endRow, int endCol, int plane) { try { int from = getPos(startRow,startCol); int to = getPos(endRow,endCol); if (from > to) { int f = from; to = f; from = f; } return planes.getPlaneData(from,to,plane); } catch (Exception oe) { return null; } } /** *

* GetScreen retrieves the various planes associated with the presentation * space. The data is returned as a linear array of character values in the * array provided. The array is not terminated by a null character except * when data is retrieved from the text plane, in which case a single null * character is appended. *

*

* The application must supply a buffer for the returned data and the length * of the buffer. Data is returned starting from the beginning of the * presentation space and continuing until the buffer is full or the entire * plane has been copied. For text plane data, the buffer must include one * extra position for the terminating null character. *

* * @param buffer character buffer * @param bufferLength length * @param plane plane * @return The number of characters copied to the buffer */ public synchronized int GetScreen(char buffer[], int bufferLength, int plane) { return GetScreen(buffer,bufferLength,0,lenScreen,plane); } /** *

* GetScreen retrieves the various planes associated with the presentation * space. The data is returned as a linear array of character values in the * array provided. The array is not terminated by a null character except * when data is retrieved from the text plane, in which case a single null * character is appended. *

*

* The application must supply a buffer for the returned data and the length * of the buffer. Data is returned starting from the given position and * continuing until the specified number of characters have been copied, the * buffer is full or the entire plane has been copied. For text plane data, * the buffer must include one extra position for the terminating null character. *

* * @param buffer buffer * @param bufferLength length * @param from where to begin * @param length length * @param plane plane * @return The number of characters copied to the buffer */ public synchronized int GetScreen(char buffer[], int bufferLength, int from, int length, int plane) { return planes.GetScreen(buffer,bufferLength, from, length, plane); } /** *

* GetScreen retrieves the various planes associated with the presentation * space. The data is returned as a linear array of character values in the * array provided. The array is not terminated by a null character except * when data is retrieved from the text plane, in which case a single null * character is appended. *

*

* The application must supply a buffer for the returned data and the length * of the buffer. Data is returned starting from the given coordinates and * continuing until the specified number of characters have been copied, * the buffer is full, or the entire plane has been copied. For text plane * data, the buffer must include one extra position for the terminating null * character. *

* * @param buffer buffer * @param bufferLength length * @param row number of row * @param col number of column * @param length length * @param plane plane * @return The number of characters copied to the buffer. */ public synchronized int GetScreen(char buffer[], int bufferLength, int row, int col, int length, int plane) { // Call GetScreen function after converting row and column to // a position. return planes.GetScreen(buffer,bufferLength, row, col, length, plane); } /** *

* GetScreenRect retrieves data from the various planes associated with the * presentation space. The data is returned as a linear array of character * values in the buffer provided. *

* *

* The application supplies two positions that represent opposing corners of * a rectangle within the presentation space. The starting and ending * positions can have any spatial relationship to each other. The data * returned starts from the row containing the upper-most point to the row * containing the lower-most point, and from the left-most column to the * right-most column. *

*

* The specified buffer must be at least large enough to contain the number * of characters in the rectangle. If the buffer is too small, no data is * copied and zero is returned by the method. Otherwise, the method returns * the number of characters copied. *

* * @param buffer nuffer * @param bufferLength length * @param startPos where to start * @param endPos where to end * @param plane plane * @return The number of characters copied to the buffer */ public synchronized int GetScreenRect(char buffer[], int bufferLength, int startPos, int endPos, int plane) { return planes.GetScreenRect(buffer, bufferLength, startPos, endPos, plane); } /** *

* GetScreenRect retrieves data from the various planes associated with the * presentation space. The data is returned as a linear array of character * values in the buffer provided. The buffer is not terminated by a null * character. *

*

* The application supplies two coordinates that represent opposing corners * of a rectangle within the presentation space. The starting and ending * coordinates can have any spatial relationship to each other. The data * returned starts from the row containing the upper-most point to the row * containing the lower-most point, and from the left-most column to the * right-most column. *

*

* The specified buffer must be at least large enough to contain the number * of characters in the rectangle. If the buffer is too small, no data is * copied and zero is returned by the method. Otherwise, the method returns * the number of characters copied. *

* * @param buffer buffer * @param bufferLength length * @param startRow row to start * @param startCol column to start * @param endRow row to end * @param endCol column to end * @param plane plane * @return The number characters copied to the buffer */ public synchronized int GetScreenRect(char buffer[], int bufferLength, int startRow, int startCol, int endRow, int endCol, int plane) { return planes.GetScreenRect(buffer, bufferLength, startRow, startCol, endRow, endCol, plane); } public synchronized boolean[] getActiveAidKeys() { return sessionVT.getActiveAidKeys(); } protected synchronized void setScreenData(String text, int location) { if (location < 0 || location > lenScreen) { return; } int l = text.length(); boolean updated = false; boolean flag = false; int x =0; for (; x < l; x++) { if (isInField(location + x,true)) { if (!screenFields.getCurrentField().isBypassField()) { if (!flag) { screenFields.getCurrentField().setMDT(); updated = true; resetDirty(location + x); screenFields.setMasterMDT(); flag = true; } planes.screen[location + x] = text.charAt(x); setDirty(location + x); } } } lastPos = location + x; if (updated) { fireScreenChanged(1); } } /** * This routine is based on offset 1,1 not 0,0 it will translate to offset * 0,0 and call the goto_XY(int pos) it is mostly used from external classes * that use the 1,1 offset * * @param row number of row * @param col number of column */ public void setCursor(int row, int col) { goto_XY(((row - 1) * numCols) + (col - 1)); } // this routine is based on offset 0,0 not 1,1 protected void goto_XY(int pos) { // setCursorOff(); updateCursorLoc(); lastPos = pos; // setCursorOn(); updateCursorLoc(); } /** * Set the current working field to the field number specified. * * @param f - * numeric field number on the screen * @return true or false whether it was sucessful */ public boolean gotoField(int f) { int sizeFields = screenFields.getSize(); if (f > sizeFields || f <= 0) return false; screenFields.setCurrentField(screenFields.getField(f - 1)); while (screenFields.isCurrentFieldBypassField() && f < sizeFields) { screenFields.setCurrentField(screenFields.getField(f++)); } return gotoField(screenFields.getCurrentField()); } /** * Convenience method to set the field object passed as the currect working * screen field * * @param screenField a screen field object * @return true or false whether it was sucessful */ protected boolean gotoField(ScreenField screenField) { if (screenField != null) { goto_XY(screenField.startPos()); return true; } return false; } /** * Convenience class to position the cursor to the next word on the screen * */ private void gotoNextWord() { int pos = lastPos; if (planes.getChar(lastPos) > ' ') { advancePos(); // get the next space character while (planes.getChar(lastPos) > ' ' && pos != lastPos) { advancePos(); } } else advancePos(); // now that we are positioned on the next space character get the // next none space character while (planes.getChar(lastPos) <= ' ' && pos != lastPos) { advancePos(); } } /** * Convenience class to position the cursor to the previous word on the * screen * */ private void gotoPrevWord() { int pos = lastPos; changePos(-1); // position previous white space character while (planes.getChar(lastPos) <= ' ') { changePos(-1); if (pos == lastPos) break; } changePos(-1); // get the previous space character while (planes.getChar(lastPos) > ' ' && pos != lastPos) { changePos(-1); } // and position one position more should give us the beginning of word advancePos(); } /** * Convinience class to position to the next field on the screen. */ private void gotoFieldNext() { if (screenFields.isCurrentFieldHighlightedEntry()) unsetFieldHighlighted(screenFields.getCurrentField()); screenFields.gotoFieldNext(); if (screenFields.isCurrentFieldHighlightedEntry()) setFieldHighlighted(screenFields.getCurrentField()); } /** * Convinience class to position to the previous field on the screen. */ private void gotoFieldPrev() { if (screenFields.isCurrentFieldHighlightedEntry()) unsetFieldHighlighted(screenFields.getCurrentField()); screenFields.gotoFieldPrev(); if (screenFields.isCurrentFieldHighlightedEntry()) setFieldHighlighted(screenFields.getCurrentField()); } protected void createWindow(int depth, int width, int type, boolean gui, int monoAttr, int colorAttr, int ul, int upper, int ur, int left, int right, int ll, int bottom, int lr) { int c = getCol(lastPos); int w = 0; width++; w = width; // set leading attribute byte // screen[lastPos].setCharAndAttr(initChar, initAttr, true); planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true); setDirty(lastPos); advancePos(); // set upper left // screen[lastPos].setCharAndAttr((char) ul, colorAttr, false); planes.setScreenCharAndAttr(lastPos, (char) ul, colorAttr, false); if (gui) { // screen[lastPos].setUseGUI(UPPER_LEFT); planes.setUseGUI(lastPos, UPPER_LEFT); } setDirty(lastPos); advancePos(); // draw top row while (w-- >= 0) { // screen[lastPos].setCharAndAttr((char) upper, colorAttr, false); planes.setScreenCharAndAttr(lastPos, (char) upper, colorAttr, false); if (gui) { // screen[lastPos].setUseGUI(UPPER); planes.setUseGUI(lastPos,UPPER); } setDirty(lastPos); advancePos(); } // set upper right // screen[lastPos].setCharAndAttr((char) ur, colorAttr, false); planes.setScreenCharAndAttr(lastPos,(char) ur, colorAttr, false); if (gui) { // screen[lastPos].setUseGUI(UPPER_RIGHT); planes.setUseGUI(lastPos, UPPER_RIGHT); } setDirty(lastPos); advancePos(); // set ending attribute byte planes.setScreenCharAndAttr(lastPos,initChar, initAttr, true); setDirty(lastPos); lastPos = ((getRow(lastPos) + 1) * numCols) + c; // now handle body of window while (depth-- > 0) { // set leading attribute byte planes.setScreenCharAndAttr(lastPos,initChar, initAttr, true); setDirty(lastPos); advancePos(); // set left planes.setScreenCharAndAttr(lastPos, (char) left, colorAttr, false); if (gui) { planes.setUseGUI(lastPos,GUI_LEFT); } setDirty(lastPos); advancePos(); w = width; // fill it in while (w-- >= 0) { // screen[lastPos].setCharAndAttr(initChar, initAttr, true); planes.setScreenCharAndAttr(lastPos,initChar, initAttr, true); // screen[lastPos].setUseGUI(NO_GUI); planes.setUseGUI(lastPos,NO_GUI); setDirty(lastPos); advancePos(); } // set right // screen[lastPos].setCharAndAttr((char) right, colorAttr, false); planes.setScreenCharAndAttr(lastPos,(char) right, colorAttr, false); if (gui) { // screen[lastPos].setUseGUI(RIGHT); planes.setUseGUI(lastPos,GUI_RIGHT); } setDirty(lastPos); advancePos(); // set ending attribute byte // screen[lastPos].setCharAndAttr(initChar, initAttr, true); planes.setScreenCharAndAttr(lastPos,initChar, initAttr, true); setDirty(lastPos); lastPos = ((getRow(lastPos) + 1) * numCols) + c; } // set leading attribute byte // screen[lastPos].setCharAndAttr(initChar, initAttr, true); planes.setScreenCharAndAttr(lastPos,initChar, initAttr, true); setDirty(lastPos); advancePos(); // set lower left // screen[lastPos].setCharAndAttr((char) ll, colorAttr, false); planes.setScreenCharAndAttr(lastPos,(char) ll, colorAttr, false); if (gui) { // screen[lastPos].setUseGUI(LOWER_LEFT); planes.setUseGUI(lastPos,LOWER_LEFT); } setDirty(lastPos); advancePos(); w = width; // draw bottom row while (w-- >= 0) { planes.setScreenCharAndAttr(lastPos,(char) bottom, colorAttr, false); if (gui) { planes.setUseGUI(lastPos,BOTTOM); } setDirty(lastPos); advancePos(); } // set lower right planes.setScreenCharAndAttr(lastPos, (char) lr, colorAttr, false); if (gui) { planes.setUseGUI(lastPos,LOWER_RIGHT); } setDirty(lastPos); advancePos(); // set ending attribute byte planes.setScreenCharAndAttr(lastPos,initChar, initAttr, true); setDirty(lastPos); } /** * Creates a scroll bar on the screen using the parameters provided. * ** we only support vertical scroll bars at the time. * * @param flag - * type to draw - vertical or horizontal * @param totalRowScrollable number * @param totalColScrollable number * @param sliderRowPos number * @param sliderColPos number * @param sbSize number */ protected void createScrollBar(int flag, int totalRowScrollable, int totalColScrollable, int sliderRowPos, int sliderColPos, int sbSize) { // System.out.println("Scrollbar flag: " + flag + // " scrollable Rows: " + totalRowScrollable + // " scrollable Cols: " + totalColScrollable + // " thumb Row: " + sliderRowPos + // " thumb Col: " + sliderColPos + // " size: " + sbSize + // " row: " + getRow(lastPos) + // " col: " + getCol(lastPos)); int sp = lastPos; int size = sbSize - 2; int thumbPos = (int) (size * ((float) sliderColPos / (float) totalColScrollable)); // System.out.println(thumbPos); planes.setScreenCharAndAttr(sp,' ', 32, false); planes.setUseGUI(sp,BUTTON_SB_UP); int ctr = 0; while (ctr < size) { sp += numCols; planes.setScreenCharAndAttr(sp,' ', 32, false); if (ctr == thumbPos) planes.setUseGUI(sp,BUTTON_SB_THUMB); else planes.setUseGUI(sp, BUTTON_SB_GUIDE); ctr++; } sp += numCols; planes.setScreenCharAndAttr(sp, ' ', 32, false); planes.setUseGUI(sp, BUTTON_SB_DN); } protected void writeWindowTitle(int pos, int depth, int width, byte orientation, int monoAttr, int colorAttr, StringBuffer title) { int len = title.length(); // get bit 0 and 1 for interrogation switch (orientation & 0xc0) { case 0x40: // right pos += (4 + width - len); break; case 0x80: // left pos += 2; break; default: // center // this is to place the position to the first text position of the // window // the position passed in is the first attribute position, the next // is the border character and then there is another attribute after // that. pos += (3 + ((width / 2) - (len / 2))); break; } // if bit 2 is on then this is a footer if ((orientation & 0x20) == 0x20) pos += ((depth + 1) * numCols); // System.out.println(pos + "," + width + "," + len+ "," + getRow(pos) // + "," + getCol(pos) + "," + ((orientation >> 6) & 0xf0)); for (int x = 0; x < len; x++) { planes.setChar(pos, title.charAt(x)); planes.setUseGUI(pos++, NO_GUI); } } /** * Roll the screen up or down. * * Byte 1: Bit 0 0 = Roll up 1 = Roll down Bits 1-2 Reserved Bits 3-7 Number * of lines that the designated area is to be rolled Byte 2: Bits 0-7 Line * number defining the top line of the area that will participate in the * roll. Byte 3: Bits 0-7 Line number defining the bottom line of the area * that will participate in the roll. * * @param direction direction * @param topLine number of top line * @param bottomLine number of bottom line */ protected void rollScreen(int direction, int topLine, int bottomLine) { // get the number of lines which are the last 5 bits /* int lines = direction & 0x7F; */ // get the direction of the roll which is the first bit // 0 - up // 1 - down int updown = direction & 0x80; final int lines = direction & 0x7F; // calculate the reference points for the move. int start = this.getPos(topLine - 1, 0); int end = this.getPos(bottomLine - 1, numCols - 1); int len = end - start; // System.out.println(" starting roll"); // dumpScreen(); switch (updown) { case 0: // Now round em up and head em UP. for (int x = start; x < end + numCols; x++) { if (x + lines * numCols >= lenScreen) { //Clear at the end planes.setChar(x, ' '); } else { planes.setChar(x, planes.getChar(x + lines * numCols )); } } break; case 1: // Now round em up and head em DOWN. for (int x = end + numCols; x > 0; x--) { if ((x - lines * numCols ) < 0 ) { //Do nothing ... tooo small!!! } else { planes.setChar(x - lines * numCols, planes.getChar(x)); //and clear planes.setChar(x, ' '); } } break; default: log.warn(" Invalid roll parameter - please report this"); } // System.out.println(" end roll"); // dumpScreen(); } public void dumpScreen() { StringBuffer sb = new StringBuffer(); char[] s = getScreenAsChars(); int c = getColumns(); int l = getRows() * c; int col = 0; for (int x = 0; x < l; x++, col++) { sb.append(s[x]); if (col == c) { sb.append('\n'); col = 0; } } log.info(sb.toString()); } public String getDumpScreen() { StringBuffer sb = new StringBuffer(); char[] s = getScreenAsChars(); int c = getColumns(); int l = getRows() * c; int col = 0; for (int x = 0; x < l; x++, col++) { sb.append(s[x]); if (col == c) { sb.append('\n'); col = 0; } } return sb.toString(); } /** * Add a field to the field format table. * * @param attr - Field attribute * @param len - length of field * @param ffw1 - Field format word 1 * @param ffw2 - Field format word 2 * @param fcw1 - Field control word 1 * @param fcw2 - Field control word 2 */ protected void addField(int attr, int len, int ffw1, int ffw2, int fcw1, int fcw2) { lastAttr = attr; planes.setScreenCharAndAttr(lastPos, initChar, lastAttr, true); setDirty(lastPos); advancePos(); ScreenField sf = null; // from 14.6.12 for Start of Field Order 5940 function manual // examine the format table for an entry that begins at the current // starting address plus 1. if (screenFields.existsAtPos(lastPos)) { screenFields.setCurrentFieldFFWs(ffw1, ffw2); } else { sf = screenFields.setField(attr, getRow(lastPos), getCol(lastPos), len, ffw1, ffw2, fcw1, fcw2); lastPos = sf.startPos(); int x = len; boolean gui = guiInterface; if (sf.isBypassField()) gui = false; while (x-- > 0) { if (planes.getChar(lastPos) == 0) planes.setScreenCharAndAttr(lastPos, ' ', lastAttr, false); else planes.setScreenAttr(lastPos,lastAttr); if (gui) { planes.setUseGUI(lastPos,FIELD_MIDDLE); } // now we set the field plane attributes planes.setScreenFieldAttr(lastPos,ffw1); advancePos(); } if (gui) if (len > 1) { planes.setUseGUI(sf.startPos(), FIELD_LEFT); if (lastPos > 0) planes.setUseGUI(lastPos - 1, FIELD_RIGHT); else planes.setUseGUI(lastPos,FIELD_RIGHT); } else { planes.setUseGUI(lastPos - 1,FIELD_ONE); } // screen[lastPos].setCharAndAttr(initChar,initAttr,true); setEndingAttr(initAttr); lastPos = sf.startPos(); } } /** * Return the fields that are contained in the Field Format Table * * @return ScreenFields object */ public ScreenFields getScreenFields() { return screenFields; } /** * Redraw the fields on the screen. Used for gui enhancement to redraw the * fields when toggling * */ protected void drawFields() { ScreenField sf; int sizeFields = screenFields.getSize(); for (int x = 0; x < sizeFields; x++) { sf = screenFields.getField(x); if (!sf.isBypassField()) { int pos = sf.startPos(); int l = sf.length; boolean f = true; if (l >= lenScreen) l = lenScreen - 1; if (l > 1) { while (l-- > 0) { if (guiInterface && f) { planes.setUseGUI(pos,FIELD_LEFT); f = false; } else { planes.setUseGUI(pos,FIELD_MIDDLE); } if (guiInterface && l == 0) { planes.setUseGUI(pos,FIELD_RIGHT); } setDirty(pos++); } } else { planes.setUseGUI(pos,FIELD_ONE); } } } //updateDirty(); } /** * Draws the field on the screen. Used to redraw or change the attributes of * the field. * * @param screenField Field to be redrawn */ protected void drawField(ScreenField screenField) { int pos = screenField.startPos(); int x = screenField.length; while (x-- > 0) { setDirty(pos++); } updateDirty(); } /** * Set the field to be displayed as highlighted. * * @param sf - * Field to be highlighted */ protected void setFieldHighlighted(ScreenField sf) { int pos = sf.startPos(); int x = sf.length; int na = sf.getHighlightedAttr(); while (x-- > 0) { planes.setScreenAttr(pos,na); setDirty(pos++); } fireScreenChanged(1); } /** * Draw the field as un higlighted. This is used to reset the field * presentation on the screen after the field is exited. * * @param sf - * Field to be unhighlighted */ protected void unsetFieldHighlighted(ScreenField sf) { int pos = sf.startPos(); int x = sf.length; int na = sf.getAttr(); while (x-- > 0) { planes.setScreenAttr(pos,na); setDirty(pos++); } fireScreenChanged(1); } public boolean checkHotSpots() { return planes.checkHotSpots(); } protected void setChar(int cByte) { if (lastPos > 0) { lastAttr = planes.getCharAttr(lastPos - 1); } if (cByte > 0 && (char)cByte < ' ') { planes.setScreenCharAndAttr(lastPos, (char) 0x00, 33, false); setDirty(lastPos); advancePos(); } else { planes.setScreenCharAndAttr(lastPos, (char) cByte, lastAttr, false); setDirty(lastPos); if (guiInterface && !isInField(lastPos, false)) { planes.setUseGUI(lastPos, NO_GUI); } advancePos(); } } protected void setEndingAttr(int cByte) { int attr = lastAttr; setAttr(cByte); lastAttr = attr; } protected void setAttr(int cByte) { lastAttr = cByte; // int sattr = screen[lastPos].getCharAttr(); // System.out.println("changing from " + sattr + " to attr " + lastAttr // + // " at " + (this.getRow(lastPos) + 1) + "," + (this.getCol(lastPos) + // 1)); planes.setScreenCharAndAttr(lastPos, initChar, lastAttr, true); setDirty(lastPos); advancePos(); int pos = lastPos; while (planes.getCharAttr(lastPos) != lastAttr && !planes.isAttributePlace(lastPos)) { planes.setScreenAttr(lastPos, lastAttr); if (guiInterface && !isInField(lastPos, false)) { int g = planes.getWhichGUI(lastPos); if (g >= FIELD_LEFT && g <= FIELD_ONE) planes.setUseGUI(lastPos,NO_GUI); } setDirty(lastPos); advancePos(); } // sanity check for right now // if (times > 200) // System.out.println(" setAttr = " + times + " start = " + (sr + 1) + // "," + (sc + 1)); lastPos = pos; } protected void setScreenCharAndAttr(char right, int colorAttr, boolean isAttr) { planes.setScreenCharAndAttr(lastPos,right, colorAttr, isAttr); setDirty(lastPos); advancePos(); } protected void setScreenCharAndAttr(char right, int colorAttr, int whichGui, boolean isAttr) { planes.setScreenCharAndAttr(lastPos,right, colorAttr, isAttr); planes.setUseGUI(lastPos,whichGui); setDirty(lastPos); advancePos(); } /** * Draw or redraw the dirty parts of the screen and display them. * * Rectangle dirty holds the dirty area of the screen to be updated. * * If you want to change the screen in anyway you need to set the screen * attributes before calling this routine. */ protected void updateDirty() { fireScreenChanged(1); } protected void setDirty(int pos) { int minr = Math.min(getRow(pos),getRow(dirtyScreen.x)); int minc = Math.min(getCol(pos),getCol(dirtyScreen.x)); int maxr = Math.max(getRow(pos),getRow(dirtyScreen.y)); int maxc = Math.max(getCol(pos),getCol(dirtyScreen.y)); int x1 = getPos(minr,minc); int x2 = getPos(maxr,maxc); dirtyScreen.setBounds(x1,x2,0,0); } private void resetDirty(int pos) { dirtyScreen.setBounds(pos,pos,0,0); } /** * Change the screen position by one column */ protected void advancePos() { changePos(1); } /** * Change position of the screen by the increment of parameter passed. * * If the position change is under the minimum of the first screen position * then the position is moved to the last row and column of the screen. * * If the position change is over the last row and column of the screen then * cursor is moved to first position of the screen. * * @param i position */ protected void changePos(int i) { lastPos += i; if (lastPos < 0) lastPos = lenScreen + lastPos; if (lastPos > lenScreen - 1) lastPos = lastPos - lenScreen; } protected void goHome() { // now we try to move to first input field according to // 14.6 WRITE TO DISPLAY Command // ? If the WTD command is valid, after the command is processed, // the cursor moves to one of three locations: // - The location set by an insert cursor order (unless control // character byte 1, bit 1 is equal to B'1'.) // - The start of the first non-bypass input field defined in the // format table // - A default starting address of row 1 column 1. if (pendingInsert && homePos > 0) { setCursor(getRow(homePos), getCol(homePos)); isInField(); // we now check if we are in a field } else { if (!gotoField(1)) { homePos = getPos(1, 1); setCursor(1, 1); isInField(0, 0); // we now check if we are in a field } else { homePos = getPos(getCurrentRow(), getCurrentCol()); } } } protected void setPendingInsert(boolean flag, int icX, int icY) { pendingInsert = flag; if (pendingInsert) { homePos = getPos(icX, icY); } if (!isStatusErrorCode()) { setCursor(icX, icY); } } protected void setPendingInsert(boolean flag) { if (homePos != -1) pendingInsert = flag; } /** * Set the error line number to that of number passed. * * @param line number of the line */ protected void setErrorLine(int line) { planes.setErrorLine(line); } /** * Returns the current error line number * * @return current error line number */ protected int getErrorLine() { return planes.getErrorLine(); } /** * Saves off the current error line characters to be used later. * */ protected void saveErrorLine() { planes.saveErrorLine(); } /** * Restores the error line characters from the save buffer. * */ protected void restoreErrorLine() { if (planes.isErrorLineSaved()) { planes.restoreErrorLine(); fireScreenChanged(1,planes.getErrorLine()-1,0,planes.getErrorLine()-1,numCols - 1); } } protected void setStatus(byte attr, byte value, String s) { // set the status area switch (attr) { case STATUS_SYSTEM: if (value == STATUS_VALUE_ON) { oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT,ScreenOIA.OIA_LEVEL_INPUT_INHIBITED, s); } else { oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_NOTINHIBITED,ScreenOIA.OIA_LEVEL_NOT_INHIBITED,s); } break; case STATUS_ERROR_CODE: if (value == STATUS_VALUE_ON) { setPrehelpState(true, true, false); oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT, ScreenOIA.OIA_LEVEL_INPUT_ERROR,s); sessionVT.signalBell(); } else { oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_NOTINHIBITED, ScreenOIA.OIA_LEVEL_NOT_INHIBITED); setPrehelpState(false, true, true); homePos = saveHomePos; saveHomePos = 0; pendingInsert = false; } break; } } protected boolean isStatusErrorCode() { return oia.getLevel() == ScreenOIA.OIA_LEVEL_INPUT_ERROR; } /** * This routine clears the screen, resets row and column to 0, resets the * last attribute to 32, clears the fields, turns insert mode off, * clears/initializes the screen character array. */ protected void clearAll() { lastAttr = 32; lastPos = 0; clearTable(); clearScreen(); planes.setScreenAttr(0, initAttr); oia.setInsertMode(false); } /** * Clear the fields table */ protected void clearTable() { oia.setKeyBoardLocked(true); screenFields.clearFFT(); planes.initalizeFieldPlanes(); pendingInsert = false; homePos = -1; } /** * Clear the gui constructs * */ protected void clearGuiStuff() { for (int x = 0; x < lenScreen; x++) { planes.setUseGUI(x,NO_GUI); } dirtyScreen.setBounds(0,lenScreen - 1,0,0); } /** * Clear the screen by setting the initial character and initial attribute * to all the positions on the screen */ protected void clearScreen() { planes.initalizePlanes(); dirtyScreen.setBounds(0,lenScreen - 1,0,0); oia.clearScreen(); } protected void restoreScreen() { lastAttr = 32; dirtyScreen.setBounds(0,lenScreen - 1,0,0); updateDirty(); } /** * Notify all registered listeners of the onScreenChanged event. * */ private void fireScreenChanged(int which, int startRow, int startCol, int endRow, int endCol) { if (screenListeners != null) { // Patch below contributed by Mitch Blevins //int size = listeners.size(); Vector lc = new Vector(screenListeners); int size = lc.size(); for (int i = 0; i < size; i++) { //ScreenListener target = // (ScreenListener)listeners.elementAt(i); ScreenListener target = lc.elementAt(i); target.onScreenChanged(1,startRow,startCol,endRow,endCol); } } dirtyScreen.setBounds(lenScreen,0,0,0); } /** * Notify all registered listeners of the onScreenChanged event. * */ private synchronized void fireScreenChanged(int update) { if (dirtyScreen.x > dirtyScreen.y) { // log.info(" x < y " + dirtyScreen); return; } fireScreenChanged(update, getRow(dirtyScreen.x), getCol(dirtyScreen.x), getRow(dirtyScreen.y), getCol(dirtyScreen.y)); } /** * Notify all registered listeners of the onScreenChanged event. * */ private synchronized void fireCursorChanged(int update) { int startRow = getRow(lastPos); int startCol = getCol(lastPos); if (screenListeners != null) { Vector lc = new Vector(screenListeners); for (int i = 0, len = lc.size(); i < len; i++) { ScreenListener target = lc.elementAt(i); target.onScreenChanged(update,startRow,startCol,startRow,startCol); } } } /** * Notify all registered listeners of the onScreenSizeChanged event. * */ private void fireScreenSizeChanged() { if (screenListeners != null) { Vector lc = new Vector(screenListeners); for (int i = 0, size = lc.size(); i < size; i++) { ScreenListener target = lc.elementAt(i); target.onScreenSizeChanged(numRows,numCols); } } } /** * This method does a complete refresh of the screen. */ public final void updateScreen() { repaintScreen(); setCursorActive(false); setCursorActive(true); } /** * Add a ScreenListener to the listener list. * * @param listener The ScreenListener to be added */ public void addScreenListener(ScreenListener listener) { if (screenListeners == null) { screenListeners = new java.util.Vector(3); } screenListeners.addElement(listener); } /** * Remove a ScreenListener from the listener list. * * @param listener The ScreenListener to be removed */ public void removeScreenListener(ScreenListener listener) { if (screenListeners == null) { return; } screenListeners.removeElement(listener); } /** * Utility method to share the repaint behaviour between setBounds() and * updateScreen. */ public void repaintScreen() { setCursorOff(); dirtyScreen.setBounds(0,lenScreen - 1,0,0); updateDirty(); // restore statuses that were on the screen before resize if (oia.getLevel() == ScreenOIA.OIA_LEVEL_INPUT_ERROR) { oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT, ScreenOIA.OIA_LEVEL_INPUT_ERROR); } if (oia.getLevel() == ScreenOIA.OIA_LEVEL_INPUT_INHIBITED) { oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT, ScreenOIA.OIA_LEVEL_INPUT_INHIBITED); } if (oia.isMessageWait()) oia.setMessageLightOn(); setCursorOn(); } // ADDED BY BARRY - changed by Kenneth to use the character plane // This should be replaced with the getPlane methods when they are implemented public char[] getCharacters() { return planes.screen; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy