Mercurial > 510Connectbot
view app/src/main/java/org/tn5250j/framework/tn5250/ScreenPlanes.java @ 524:609b142218bc
Added tag stable-1.9.4-7 for changeset 775a81a78a2b
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 31 May 2024 21:14:55 -0600 |
parents | d29cce60f393 |
children |
line wrap: on
line source
/** * Title: ScreenPlanes.java * Copyright: Copyright (c) 2001 * 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.*; public class ScreenPlanes { private final Screen5250 scr; private int screenSize; private int numRows; private int numCols; private int errorLineNum; private static final int initAttr = 32; private static final char initChar = 0; protected char[] screen; // text plane private char[] screenAttr; // attribute plane private char[] screenGUI; // gui plane private char[] screenIsAttr; private char[] fieldExtended; private char[] screenField; private char[] screenColor; // color plane protected char[] screenExtended; // extended plane private char[] screenIsChanged; private char[] initArray; private char[] errorLine; private char[] errorLineAttr; private char[] errorLineIsAttr; private char[] errorLineGui; public ScreenPlanes(Screen5250 s5250, int size) { scr = s5250; setSize(size); } protected void setSize(int newSize) { screenSize = newSize; numCols = 80; switch (newSize) { case 24: numRows = 24; break; case 27: numRows = 27; numCols = 132; break; } // this is used here when size changes setErrorLine(numRows); screenSize = numRows * numCols; screen = new char[screenSize]; screenAttr = new char[screenSize]; screenIsAttr = new char[screenSize]; screenGUI = new char[screenSize]; screenColor = new char[screenSize]; screenExtended = new char[screenSize]; fieldExtended = new char[screenSize]; screenIsChanged = new char[screenSize]; screenField = new char[screenSize]; initArray = new char[screenSize]; initalizePlanes(); } protected void setErrorLine(int line) { // * NOTE * for developers I have changed the send qry to pass different // parameters to the host so check setsize for setting error line as well. // if (line == 0 || line > numRows) errorLineNum = numRows; else errorLineNum = line; } /** * Returns the current error line number * * @return current error line number */ protected int getErrorLine() { return errorLineNum; } protected void saveErrorLine() { // if there is already an error line saved then do not save it again // This signifies that there was a previous error and the original error // line was not restored yet. if (errorLine == null) { errorLine = new char[numCols]; errorLineAttr = new char[numCols]; errorLineIsAttr = new char[numCols]; errorLineGui = new char[numCols]; int r = scr.getPos(errorLineNum - 1, 0); for (int x = 0; x < numCols; x++) { errorLine[x] = screen[r + x]; errorLineAttr[x] = screenAttr[r + x]; errorLineIsAttr[x] = screenIsAttr[r + x]; errorLineGui[x] = screenGUI[r + x]; } } } /** * Restores the error line characters from the save buffer. * * @see #saveErrorLine() */ protected void restoreErrorLine() { if (errorLine != null) { int r = scr.getPos(errorLineNum - 1, 0); for (int x = 0; x < numCols - 1; x++) { setScreenCharAndAttr(r + x, errorLine[x], errorLineAttr[x], (errorLineIsAttr[x] == '1' ? true : false)); screenGUI[x] = errorLineGui[x]; } errorLine = null; errorLineAttr = null; errorLineIsAttr = null; errorLineGui = null; } } protected boolean isErrorLineSaved() { return errorLine == null ? false : true; } protected void setScreenCharAndAttr(int pos, char c, int attr, boolean isAttr) { screen[pos] = c; screenAttr[pos] = (char)attr; disperseAttribute(pos, attr); screenIsAttr[pos] = (isAttr ? (char)1 : (char)0); screenGUI[pos] = NO_GUI; } protected void setScreenAttr(int pos, int attr, boolean isAttr) { screenAttr[pos] = (char)attr; screenIsAttr[pos] = isAttr ? (char)1 : (char)0; disperseAttribute(pos, attr); screenGUI[pos] = initChar; } protected void setScreenAttr(int pos, int attr) { screenAttr[pos] = (char)attr; //screenGUI[pos] = initChar; disperseAttribute(pos, attr); } protected void setScreenFieldAttr(int pos, int attr) { screenField[pos] = (char)attr; } protected final void setChar(int pos, char c) { screenIsChanged[pos] = screen[pos] == c ? '0' : '1'; screen[pos] = c; if (screenIsAttr[pos] == 1) setScreenCharAndAttr(pos, c, 32, false); } protected final char getChar(int pos) { return screen[pos]; } protected final char getCharColor(int pos) { return screenColor[pos]; } protected final int getCharAttr(int pos) { return screenAttr[pos]; } protected final char getCharExtended(int pos) { return screenExtended[pos]; } protected final boolean isAttributePlace(int pos) { return screenIsAttr[pos] == 1 ? true : false; } public final void setUseGUI(int pos, int which) { screenIsChanged[pos] = screenGUI[pos] == which ? '0' : '1'; screenGUI[pos] = (char)which; } private void disperseAttribute(int pos, int attr) { char c = 0; char cs = 0; char ul = 0; char nd = 0; if (attr == 0) return; switch (attr) { case 32: // green normal c = ATTR_32; break; case 33: // green/revers c = ATTR_33; break; case 34: // white normal c = ATTR_34; break; case 35: // white/reverse c = ATTR_35; break; case 36: // green/underline c = ATTR_36; ul = EXTENDED_5250_UNDERLINE; break; case 37: // green/reverse/underline c = ATTR_37; ul = EXTENDED_5250_UNDERLINE; break; case 38: // white/underline c = ATTR_38; ul = EXTENDED_5250_UNDERLINE; break; case 39: nd = EXTENDED_5250_NON_DSP; break; case 40: case 42: // red/normal c = ATTR_40; break; case 41: case 43: // red/reverse c = ATTR_41; break; case 44: case 46: // red/underline c = ATTR_44; ul = EXTENDED_5250_UNDERLINE; break; case 45: // red/reverse/underline c = ATTR_45; ul = EXTENDED_5250_UNDERLINE; break; case 47: nd = EXTENDED_5250_NON_DSP; break; case 48: c = ATTR_48; cs = EXTENDED_5250_COL_SEP; break; case 49: c = ATTR_49; cs = EXTENDED_5250_COL_SEP; break; case 50: c = ATTR_50; cs = EXTENDED_5250_COL_SEP; break; case 51: c = ATTR_51; cs = EXTENDED_5250_COL_SEP; break; case 52: c = ATTR_52; // colSep = true; ul = EXTENDED_5250_UNDERLINE; break; case 53: c = ATTR_53; // colSep = true; ul = EXTENDED_5250_UNDERLINE; break; case 54: c = ATTR_54; // colSep = true; ul = EXTENDED_5250_UNDERLINE; break; case 55: nd = EXTENDED_5250_NON_DSP; break; case 56: // pink c = ATTR_56; break; case 57: // pink/reverse c = ATTR_57; break; case 58: // blue/reverse c = ATTR_58; break; case 59: // blue c = ATTR_59; break; case 60: // pink/underline c = ATTR_60; ul = EXTENDED_5250_UNDERLINE; break; case 61: // pink/reverse/underline c = ATTR_61; ul = EXTENDED_5250_UNDERLINE; break; case 62: // blue/underline c = ATTR_62; ul = EXTENDED_5250_UNDERLINE; break; case 63: // nondisplay nd = EXTENDED_5250_NON_DSP; cs = EXTENDED_5250_COL_SEP; break; default: c = (COLOR_BG_BLACK << 8 & 0xff00) | (COLOR_FG_YELLOW & 0xff); break; } screenColor[pos] = c; screenExtended[pos] = (char)(ul | cs | nd); } protected void initalizePlanes() { char c = (COLOR_BG_BLACK << 8 & 0xff00) | (COLOR_FG_GREEN & 0xff); for (int y = 0; y < screenSize; y++) { screenAttr[y] = initAttr; screenColor[y] = c; } // here we will just copy the initialized plane onto the other planes // using arraycopy which will be faster. I hope. System.arraycopy(initArray, 0, screen, 0, screenSize); System.arraycopy(initArray, 0, screenGUI, 0, screenSize); System.arraycopy(initArray, 0, screenIsAttr, 0, screenSize); System.arraycopy(initArray, 0, screenExtended, 0, screenSize); System.arraycopy(initArray, 0, fieldExtended, 0, screenSize); System.arraycopy(initArray, 0, screenField, 0, screenSize); } protected void initalizeFieldPlanes() { System.arraycopy(initArray, 0, fieldExtended, 0, screenSize); System.arraycopy(initArray, 0, screenField, 0, screenSize); } protected final int getWhichGUI(int pos) { return screenGUI[pos]; } protected final boolean isChanged(int pos) { return screenIsChanged[pos] == 0 ? false : true; } protected final boolean isUseGui(int pos) { return screenGUI[pos] == NO_GUI ? false : true; } /** * Return the data associated with the plane that is passed. * * @param from Position from which to start * @param to Position to end * @param plane From which plane to obtain the data * @return Character array containing the data requested */ protected synchronized char[] getPlaneData(int from, int to, int plane) { int len = (to - from); char[] planeChars = new char[len + 1]; switch (plane) { case PLANE_TEXT: System.arraycopy(screen, from, planeChars, 0, len); break; case PLANE_ATTR: System.arraycopy(screenAttr, from, planeChars, 0, len); break; case PLANE_COLOR: System.arraycopy(screenColor, from, planeChars, 0, len); break; case PLANE_EXTENDED: System.arraycopy(screenExtended, from, planeChars, 0, len); break; case PLANE_EXTENDED_GRAPHIC: System.arraycopy(screenGUI, from, planeChars, 0, len); break; case PLANE_FIELD: System.arraycopy(screenField, from, planeChars, 0, len); break; case PLANE_IS_ATTR_PLACE: System.arraycopy(screenIsAttr, from, planeChars, 0, len); break; default: System.arraycopy(screen, from, planeChars, 0, len); } return planeChars; } /** * Converts a linear presentation space position to its corresponding row. * * @param pos The position to be converted * @return The row which corresponds to the position given * @throws OhioException */ private int convertPosToRow(int pos) { return (pos / numCols) + 1; } /** * Converts a linear presentation space position to its corresponding column. * * @param pos The position to be converted * @return The column which corresponds to the position given * @throws OhioException */ private int convertPosToColumn(int pos) { return (pos % numCols) + 1; } /** * * Converts a row and column coordinate to its corresponding linear position. * * @param row - The row of the coordinate * @param col - The column of the coordinate * @return The linear position which corresponds to the coordinate given. * @throws OhioException */ private int convertRowColToPos(int row, int col) { return (row - 1) * numCols + col - 1; } /** * <p> * 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. * </p> * <p> * 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. * <p> * * @param buffer * @param bufferLength * @param plane * @return The number of characters copied to the buffer * @throws OhioException */ public synchronized int GetScreen(char buffer[], int bufferLength, int plane) { return GetScreen(buffer, bufferLength, 0, screenSize, plane); } /** * <p> * 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. * </p> * <p> * 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. * </p> * * @param buffer * @param bufferLength * @param from * @param length * @param plane * @return The number of characters copied to the buffer * @throws OhioException */ public synchronized int GetScreen(char buffer[], int bufferLength, int from, int length, int plane) { // if(buffer == null) // throw new OhioException(sessionVT.getSessionConfiguration(), // OhioScreen.class.getName(), "osohio.screen.ohio00300", 1); if (buffer == null) return 0; int min = Math.min(Math.min(buffer.length, bufferLength), screenSize); if ((from + min) > screenSize) { min = screenSize - from; } char[] pd = getPlaneData(from, from + min, plane); if (pd != null) { System.arraycopy(pd, 0, buffer, 0, min); return pd.length; } return 0; } /** * <p> * 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. * </p> * <p> * 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. * </p> * * @param buffer * @param bufferLength * @param row * @param col * @param length * @param plane * @return The number of characters copied to the buffer. * @throws OhioException */ public synchronized int GetScreen(char buffer[], int bufferLength, int row, int col, int length, int plane) // throws OhioException { { // Call GetScreen function after converting row and column to // a position. return GetScreen(buffer, bufferLength, convertRowColToPos(row, col), length, plane); } /** * <p> * 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. * </p> * * <p> * 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. * </p> * <p> * 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. * </p> * * @param buffer * @param bufferLength * @param startPos * @param endPos * @param plane * @return The number of characters copied to the buffer * @throws OhioException */ protected int GetScreenRect(char buffer[], int bufferLength, int startPos, int endPos, int plane) // throws OhioException { { // We will use the row,col routine here because it is easier to use // row colum than it is for position since I wrote the other first and // am to lazy to implement it here // Maybe it would be faster to do it the other way? int startRow = convertPosToRow(startPos); int startCol = convertPosToColumn(startPos); int endRow = convertPosToRow(endPos); int endCol = convertPosToColumn(endPos); return GetScreenRect(buffer, bufferLength, startRow, startCol, endRow, endCol, plane); } /** * <p> * 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. * </p> * <p> * 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. * </p> * <p> * 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. * </p> * * @param buffer * @param bufferLength * @param startRow * @param startCol * @param endRow * @param endCol * @param plane * @return The number characters copied to the buffer * @throws OhioException */ protected int GetScreenRect(char buffer[], int bufferLength, int startRow, int startCol, int endRow, int endCol, int plane) // throws OhioException { { // number of bytes obtained int numBytes = 0; // lets check the row range. If they are reversed then we need to // place them in the correct order. if (startRow > endRow) { int r = startRow; startRow = endRow; endRow = r; } // lets check the column range. If they are reversed then we need to // place them in the correct order. if (startCol > endCol) { int c = startCol; startCol = endCol; endCol = c; } int numCols = (endCol - startCol) + 1; int numRows = (endRow - startRow) + 1; // lets make sure it is within the bounds of the character array passed // if not the return as zero bytes where read as per documentation. if (numCols * numRows <= bufferLength) { // make sure it is one larger. I guess for other languanges to // reference like in C which is terminated by a zero byte at the end // of strings. char cb[] = new char[numCols + 1]; int charOffset = 0; int bytes = 0; // now let's loop through and get the screen information for // each row; for (int row = startRow; row <= endRow;) { if ((bytes = GetScreen(cb, cb.length, row, startCol, numCols, plane)) != 0) { System.arraycopy(cb, 0, buffer, charOffset, numCols); } row++; charOffset += numCols; // make sure we count the number of bytes returned numBytes += bytes; } } return numBytes; } private int isOption(char[] screen, int x, int lenScreen, int numPref, int numSuff, char suff) { boolean hs = true; int sp = x; int os = 0; // check to the left for option while (--sp >= 0 && screen[sp] <= ' ') { if (x - sp > numPref || screen[sp] == suff || screen[sp] == '.' || screen[sp] == '*') { hs = false; break; } } // now lets check for how long the option is it has to be numPref or less os = sp; while (hs && --os > 0 && screen[os] > ' ') { if (sp - os >= numPref || screen[os] == suff || screen[os] == '.' || screen[os] == '*') { hs = false; break; } } if (sp - os > 1 && !Character.isDigit(screen[os + 1])) { hs = false; } sp = x; if (Character.isDigit(screen[sp + 1])) hs = false; // now lets make sure there are no more than numSuff spaces after option while (hs && (++sp < lenScreen && screen[sp] <= ' ' || screen[sp] == suff)) { if (sp - x >= numSuff || screen[sp] == suff || screen[sp] == '.' || screen[sp] == '*') { hs = false; break; } } if (hs && !Character.isLetterOrDigit(screen[sp])) hs = false; if (hs) { return os; } return -1; } }