Mercurial > 510Connectbot
diff app/src/main/java/org/tn5250j/framework/tn5250/ScreenPlanes.java @ 438:d29cce60f393
migrate from Eclipse to Android Studio
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 03 Dec 2015 11:23:55 -0800 |
parents | src/org/tn5250j/framework/tn5250/ScreenPlanes.java@446dbcf606eb |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/src/main/java/org/tn5250j/framework/tn5250/ScreenPlanes.java Thu Dec 03 11:23:55 2015 -0800 @@ -0,0 +1,803 @@ +/** + * 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; + } + +} \ No newline at end of file