ScreenPlanes.java
上传用户:xiekaiwei
上传日期:2015-07-04
资源大小:620k
文件大小:35k
源码类别:

Telnet客户端

开发平台:

Java

  1. /**
  2.  * Title: ScreenPlanes.java
  3.  * Copyright:   Copyright (c) 2001
  4.  * Company:
  5.  * @author  Kenneth J. Pouncey
  6.  * @version 0.5
  7.  *
  8.  * Description:
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2, or (at your option)
  13.  * any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this software; see the file COPYING.  If not, write to
  22.  * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  23.  * Boston, MA 02111-1307 USA
  24.  *
  25.  */
  26. package org.tn5250j.framework.tn5250;
  27. import org.tn5250j.TN5250jConstants;
  28. public class ScreenPlanes implements TN5250jConstants {
  29.    Screen5250 scr;
  30.    int screenSize;
  31.    int numRows;
  32.    int numCols;
  33.    int errorLineNum;
  34.    private char char0 = 0;
  35.    private static final int initAttr = 32;
  36.    private static final char initChar = 0;
  37.    protected char[] screen;   // text plane
  38.    protected char[] screenAttr;   // attribute plane
  39.    protected char[] screenGUI;   // gui plane
  40.    protected char[] screenIsAttr;
  41.    protected char[] fieldExtended;
  42.    protected char[] screenField;
  43.    protected char[] screenColor;   // color plane
  44.    protected char[] screenExtended;   // extended plane
  45.    protected char[] screenIsChanged;
  46.    protected char[] initArray;
  47.    protected char[] errorLine;
  48.    protected char[] errorLineAttr;
  49.    protected char[] errorLineIsAttr;
  50.    protected char[] errorLineGui;
  51.    public ScreenPlanes(Screen5250 s5250, int size) {
  52.       scr = s5250;
  53.       setSize(size);
  54.    }
  55.    protected void setSize(int newSize) {
  56.       int oldRows = numRows;
  57.       screenSize = newSize;
  58.       numCols = 80;
  59.       switch (newSize) {
  60.          case 24:
  61.             numRows = 24;
  62.             break;
  63.          case 27:
  64.             numRows = 27;
  65.             numCols = 132;
  66.          break;
  67.       }
  68.       // this is used here when size changes
  69.       setErrorLine(numRows);
  70.       screenSize = numRows * numCols;
  71.       screen = new char[screenSize];
  72.       screenAttr = new char[screenSize];
  73.       screenIsAttr = new char[screenSize];
  74.       screenGUI = new char[screenSize];
  75.       screenColor = new char[screenSize];
  76.       screenExtended = new char[screenSize];
  77.       fieldExtended = new char[screenSize];
  78.       screenIsChanged = new char[screenSize];
  79.       screenField = new char[screenSize];
  80.       initArray = new char[screenSize];
  81.       initalizePlanes();
  82.    }
  83.    protected void setErrorLine (int line) {
  84.       // * NOTE * for developers I have changed the send qry to pass different
  85.       //    parameters to the host so check setsize for setting error line as well.
  86.       //
  87.       if (line == 0 || line > numRows)
  88.          errorLineNum = numRows;
  89.       else
  90.          errorLineNum = line;
  91.    }
  92. /**
  93.  * Returns the current error line number
  94.  *
  95.  * @return current error line number
  96.  */
  97. protected int getErrorLine() {
  98. return errorLineNum;
  99. }
  100.    protected void saveErrorLine() {
  101.       // if there is already an error line saved then do not save it again
  102.       //  This signifies that there was a previous error and the original error
  103.       //  line was not restored yet.
  104.       if (errorLine == null) {
  105.          errorLine = new char[numCols];
  106.          errorLineAttr = new char[numCols];
  107.          errorLineIsAttr = new char[numCols];
  108.          errorLineGui = new char[numCols];
  109.          int r = scr.getPos(errorLineNum-1,0);
  110.          for (int x = 0;x < numCols; x++) {
  111.             errorLine[x] = screen[r+x];
  112.             errorLineAttr[x] = screenAttr[r+x];
  113.             errorLineIsAttr[x] = screenIsAttr[r+x];
  114.             errorLineGui[x] = screenGUI[r+x];
  115.          }
  116.       }
  117.    }
  118. /**
  119.  * Restores the error line characters from the save buffer.
  120.  *
  121.  * @see #saveErrorLine()
  122.  */
  123. protected void restoreErrorLine() {
  124. if (errorLine != null) {
  125. int r = scr.getPos(errorLineNum - 1, 0);
  126. for (int x = 0; x < numCols - 1; x++) {
  127.             setScreenCharAndAttr(r+x,errorLine[x],errorLineAttr[x],
  128.                    (errorLineIsAttr[x] == '1' ? true : false));
  129.             screenGUI[x] = errorLineGui[x];
  130. }
  131. errorLine = null;
  132. errorLineAttr = null;
  133.          errorLineIsAttr = null;
  134.          errorLineGui = null;
  135. }
  136. }
  137.    protected boolean isErrorLineSaved() {
  138.       return errorLine == null ? false : true;
  139.    }
  140.    protected void setScreenCharAndAttr(int pos, char c, int attr, boolean isAttr) {
  141.       screen[pos] = c;
  142.       screenAttr[pos] = (char)attr;
  143.       disperseAttribute(pos,attr);
  144.       screenIsAttr[pos] = (isAttr ? (char)1 : (char)0);
  145.       screenGUI[pos] = NO_GUI;
  146.    }
  147.    protected void setScreenAttr(int pos, int attr, boolean isAttr) {
  148.       screenAttr[pos] = (char)attr;
  149.       screenIsAttr[pos] = isAttr ? (char)1 : (char)0;
  150.       disperseAttribute(pos,attr);
  151.       screenGUI[pos] = initChar;
  152.    }
  153.    protected void setScreenAttr(int pos, int attr) {
  154.       screenAttr[pos] = (char)attr;
  155.       //screenGUI[pos] = initChar;
  156.       disperseAttribute(pos,attr);
  157.    }
  158.    protected void setScreenFieldAttr(int pos, int attr) {
  159.       screenField[pos] = (char)attr;
  160.    }
  161.    protected final void setChar(int pos, char c) {
  162.       screenIsChanged[pos] = screen[pos] == c ? '0' : '1';
  163.       screen[pos] = c;
  164.       if (screenIsAttr[pos] == 1)
  165.          setScreenCharAndAttr(pos,c,32,false);
  166.    }
  167.    protected final char getChar(int pos) {
  168.       return screen[pos];
  169.    }
  170.    protected final int getCharAttr(int pos) {
  171.       return screenAttr[pos];
  172.    }
  173.    protected final boolean isAttributePlace(int pos) {
  174.       return screenIsAttr[pos] == 1 ? true : false;
  175.    }
  176.    public final void setUseGUI(int pos, int which) {
  177.       screenIsChanged[pos] = screenGUI[pos] == which ? '0' : '1';
  178.       screenGUI[pos] = (char)which;
  179.    }
  180.    private void disperseAttribute(int pos, int attr) {
  181.       char c = 0;
  182.       char cs = 0;
  183.       char ul = 0;
  184.       char nd = 0;
  185.       if(attr == 0)
  186.          return;
  187.       switch(attr) {
  188.          case 32: // green normal
  189.             c = ATTR_32;
  190.             break;
  191.          case 33: // green/revers
  192.             c = ATTR_33;
  193.             break;
  194.          case 34: // white normal
  195.             c = ATTR_34;
  196.             break;
  197.          case 35: // white/reverse
  198.             c = ATTR_35;
  199.             break;
  200.          case 36: // green/underline
  201.             c = ATTR_36;
  202.             ul = EXTENDED_5250_UNDERLINE;
  203.             break;
  204.          case 37: // green/reverse/underline
  205.             c = ATTR_37;
  206.             ul = EXTENDED_5250_UNDERLINE;
  207.             break;
  208.          case 38: // white/underline
  209.             c = ATTR_38;
  210.             ul = EXTENDED_5250_UNDERLINE;
  211.             break;
  212.          case 39:
  213.             nd = EXTENDED_5250_NON_DSP;
  214.             break;
  215.          case 40:
  216.          case 42: // red/normal
  217.             c = ATTR_40;
  218.             break;
  219.          case 41:
  220.          case 43: // red/reverse
  221.             c = ATTR_41;
  222.             break;
  223.          case 44:
  224.          case 46: // red/underline
  225.             c = ATTR_44;
  226.             ul = EXTENDED_5250_UNDERLINE;
  227.             break;
  228.          case 45: // red/reverse/underline
  229.             c = ATTR_45;
  230.             ul = EXTENDED_5250_UNDERLINE;
  231.             break;
  232.          case 47:
  233.             nd = EXTENDED_5250_NON_DSP;
  234.             break;
  235.          case 48:
  236.             c = ATTR_48;
  237.             cs = EXTENDED_5250_COL_SEP;
  238.             break;
  239.          case 49:
  240.             c = ATTR_49;
  241.             cs = EXTENDED_5250_COL_SEP;
  242.             break;
  243.          case 50:
  244.             c = ATTR_50;
  245.             cs = EXTENDED_5250_COL_SEP;
  246.             break;
  247.          case 51:
  248.             c = ATTR_51;
  249.             cs = EXTENDED_5250_COL_SEP;
  250.             break;
  251.          case 52:
  252.             c = ATTR_52;
  253. //            colSep = true;
  254.             ul = EXTENDED_5250_UNDERLINE;
  255.             break;
  256.          case 53:
  257.             c = ATTR_53;
  258. //            colSep = true;
  259.             ul = EXTENDED_5250_UNDERLINE;
  260.             break;
  261.          case 54:
  262.             c = ATTR_54;
  263. //            colSep = true;
  264.             ul = EXTENDED_5250_UNDERLINE;
  265.             break;
  266.          case 55:
  267.             nd = EXTENDED_5250_NON_DSP;
  268.             break;
  269.          case 56: // pink
  270.             c = ATTR_56;
  271.             break;
  272.          case 57: // pink/reverse
  273.             c = ATTR_57;
  274.             break;
  275.          case 58: // blue/reverse
  276.             c = ATTR_58;
  277.             break;
  278.          case 59: // blue
  279.             c = ATTR_59;
  280.             break;
  281.          case 60: // pink/underline
  282.             c = ATTR_60;
  283.             ul = EXTENDED_5250_UNDERLINE;
  284.             break;
  285.          case 61: // pink/reverse/underline
  286.             c = ATTR_61;
  287.             ul = EXTENDED_5250_UNDERLINE;
  288.             break;
  289.          case 62: // blue/underline
  290.             c = ATTR_62;
  291.             ul = EXTENDED_5250_UNDERLINE;
  292.             break;
  293.          case 63:  // nondisplay
  294.             nd = EXTENDED_5250_NON_DSP;
  295.             cs = EXTENDED_5250_COL_SEP;
  296.             break;
  297.          default:
  298.             c = ( COLOR_BG_BLACK << 8 & 0xff00) |
  299.             ( COLOR_FG_YELLOW & 0xff);
  300.             break;
  301.       }
  302.       screenColor[pos] = c;
  303.       screenExtended[pos] = (char)(ul | cs | nd);
  304.    }
  305.    protected void initalizePlanes () {
  306.       char c = (COLOR_BG_BLACK << 8 & 0xff00) |
  307.       (COLOR_FG_GREEN & 0xff);
  308.       for (int y = 0;y < screenSize; y++) {
  309.          screenAttr[y] = initAttr;
  310.          screenColor[y] = c;
  311.       }
  312.       // here we will just copy the initialized plane onto the other planes
  313.       // using arraycopy which will be faster.  I hope.
  314.       System.arraycopy(initArray,0,screen,0,screenSize);
  315.       System.arraycopy(initArray,0,screenGUI,0,screenSize);
  316.       System.arraycopy(initArray,0,screenIsAttr,0,screenSize);
  317.       System.arraycopy(initArray,0,screenExtended,0,screenSize);
  318.       System.arraycopy(initArray,0,fieldExtended,0,screenSize);
  319.       System.arraycopy(initArray,0,screenField,0,screenSize);
  320.    }
  321.    protected void initalizeFieldPlanes () {
  322.       System.arraycopy(initArray,0,fieldExtended,0,screenSize);
  323.       System.arraycopy(initArray,0,screenField,0,screenSize);
  324.    }
  325.    protected final int getWhichGUI(int pos) {
  326.       return screenGUI[pos];
  327.    }
  328.    protected final boolean isChanged(int pos) {
  329.       return screenIsChanged[pos] == 0 ? false : true;
  330.    }
  331.    protected final boolean isUseGui(int pos) {
  332.       return screenGUI[pos] == NO_GUI ? false : true;
  333.    }
  334.    /**
  335.     * Return the data associated with the plane that is passed.
  336.     *
  337.     * @param from Position from which to start
  338.     * @param to Position to end
  339.     * @param plane From which plane to obtain the data
  340.     * @return Character array containing the data requested
  341.     */
  342.    protected synchronized char[] getPlaneData(int from, int to, int plane) {
  343.       int len = to - from;
  344.       char[] planeChars = new char[len + 1];
  345.       switch (plane) {
  346.          case PLANE_TEXT:
  347.             System.arraycopy(screen, from, planeChars, 0, len);
  348.             break;
  349.          case PLANE_ATTR:
  350.             System.arraycopy(screenAttr, from, planeChars, 0, len);
  351.             break;
  352.          case PLANE_COLOR:
  353.             System.arraycopy(screenColor, from, planeChars, 0, len);
  354.             break;
  355.          case PLANE_EXTENDED:
  356.             System.arraycopy(screenExtended, from, planeChars, 0, len);
  357.             break;
  358.          case PLANE_EXTENDED_GRAPHIC:
  359.             System.arraycopy(screenGUI, from, planeChars, 0, len);
  360.             break;
  361.          case PLANE_FIELD:
  362.             System.arraycopy(screenField, from, planeChars, 0, len);
  363.             break;
  364.          case PLANE_IS_ATTR_PLACE:
  365.             System.arraycopy(screenIsAttr, from, planeChars, 0, len);
  366.             break;
  367.          default:
  368.             System.arraycopy(screen, from, planeChars, 0, len);
  369.       }
  370.       return planeChars;
  371.    }
  372.    /**
  373.     * Converts a linear presentation space position to its corresponding row.
  374.     *
  375.     * @param pos The position to be converted
  376.     * @return The row which corresponds to the position given
  377.     * @throws OhioException
  378.     */
  379.    private int convertPosToRow(int pos) {
  380.       return (pos / numCols) + 1;
  381.    }
  382.    /**
  383.     * Converts a linear presentation space position to its corresponding column.
  384.     *
  385.     * @param pos The position to be converted
  386.     * @return The column which corresponds to the position given
  387.     * @throws OhioException
  388.     */
  389.    private int convertPosToColumn(int pos) {
  390.       return (pos % numCols) + 1;
  391.    }
  392.    /**
  393.     *
  394.     * Converts a row and column coordinate to its corresponding linear position.
  395.     *
  396.     * @param row - The row of the coordinate
  397.     * @param col - The column of the coordinate
  398.     * @return The linear position which corresponds to the coordinate given.
  399.     * @throws OhioException
  400.     */
  401.    private int convertRowColToPos(int row, int col) {
  402.       return (row - 1) * numCols + col -1;
  403.    }
  404.    /**
  405.     * <p>
  406.     *  GetScreen retrieves the various planes associated with the presentation
  407.     *  space. The data is returned as a linear array of character values in the
  408.     *  array provided. The array is not terminated by a null character except
  409.     *  when data is retrieved from the text plane, in which case a single null
  410.     *  character is appended.
  411.     *  </p>
  412.     *  <p>
  413.     *  The application must supply a buffer for the returned data and the length
  414.     *  of the buffer. Data is returned starting from the beginning of the
  415.     *  presentation space and continuing until the buffer is full or the entire
  416.     *  plane has been copied. For text plane data, the buffer must include one
  417.     *  extra position for the terminating null character.
  418.     *  <p>
  419.     *
  420.     * @param buffer
  421.     * @param bufferLength
  422.     * @param plane
  423.     * @return The number of characters copied to the buffer
  424.     * @throws OhioException
  425.     */
  426.    public synchronized int GetScreen(char buffer[], int bufferLength, int plane) {
  427.       return GetScreen(buffer,bufferLength,0,screenSize,plane);
  428.    }
  429.    /**
  430.     * <p>
  431.     *  GetScreen retrieves the various planes associated with the presentation
  432.     *  space. The data is returned as a linear array of character values in the
  433.     *  array provided. The array is not terminated by a null character except
  434.     *  when data is retrieved from the text plane, in which case a single null
  435.     *  character is appended.
  436.     * </p>
  437.     * <p>
  438.     * The application must supply a buffer for the returned data and the length
  439.     * of the buffer. Data is returned starting from the given position and
  440.     * continuing until the specified number of characters have been copied, the
  441.     * buffer is full or the entire plane has been copied. For text plane data,
  442.     * the buffer must include one extra position for the terminating null character.
  443.     * </p>
  444.     *
  445.     * @param buffer
  446.     * @param bufferLength
  447.     * @param from
  448.     * @param length
  449.     * @param plane
  450.     * @return The number of characters copied to the buffer
  451.     * @throws OhioException
  452.     */
  453.    public synchronized int GetScreen(char buffer[], int bufferLength, int from,
  454.                                     int length, int plane)
  455.                                     {
  456. //      if(buffer == null)
  457. //         throw new OhioException(sessionVT.getSessionConfiguration(),
  458. //                     OhioScreen.class.getName(), "osohio.screen.ohio00300", 1);
  459.       if(buffer == null)
  460.          return 0;
  461.       int min = Math.min(Math.min(buffer.length, bufferLength), screenSize);
  462.       if ((from + min) > screenSize) {
  463.          min = screenSize - from;
  464.       }
  465.       char[] pd = getPlaneData(from,from + min,plane);
  466.       if(pd != null) {
  467.          System.arraycopy(pd, 0, buffer, 0, min);
  468.          return pd.length;
  469.       }
  470.       return 0;
  471.    }
  472.    /**
  473.     * <p>
  474.     *  GetScreen retrieves the various planes associated with the presentation
  475.     *  space. The data is returned as a linear array of character values in the
  476.     *  array provided. The array is not terminated by a null character except
  477.     *  when data is retrieved from the text plane, in which case a single null
  478.     *  character is appended.
  479.     *  </p>
  480.     *  <p>
  481.     *  The application must supply a buffer for the returned data and the length
  482.     *  of the buffer. Data is returned starting from the given coordinates and
  483.     *  continuing until the specified number of characters have been copied,
  484.     *  the buffer is full, or the entire plane has been copied. For text plane
  485.     *  data, the buffer must include one extra position for the terminating null
  486.     *  character.
  487.     *  </p>
  488.     *
  489.     * @param buffer
  490.     * @param bufferLength
  491.     * @param row
  492.     * @param col
  493.     * @param length
  494.     * @param plane
  495.     * @return The number of characters copied to the buffer.
  496.     * @throws OhioException
  497.     */
  498.    public synchronized int GetScreen(char buffer[], int bufferLength, int row,
  499.                                        int col, int length, int plane)
  500. //                                       throws OhioException {
  501.                                        {
  502.       // Call GetScreen function after converting row and column to
  503.       // a position.
  504.       return GetScreen(buffer,bufferLength, convertRowColToPos(row,col),
  505.                            length, plane);
  506.    }
  507.    /**
  508.     * <p>
  509.     *  GetScreenRect retrieves data from the various planes associated with the
  510.     *  presentation space. The data is returned as a linear array of character
  511.     *  values in the buffer provided.
  512.     *  </p>
  513.     *
  514.     * <p>
  515.     * The application supplies two positions that represent opposing corners of
  516.     * a rectangle within the presentation space. The starting and ending
  517.     * positions can have any spatial relationship to each other. The data
  518.     * returned starts from the row containing the upper-most point to the row
  519.     * containing the lower-most point, and from the left-most column to the
  520.     * right-most column.
  521.     * </p>
  522.     * <p>
  523.     * The specified buffer must be at least large enough to contain the number
  524.     * of characters in the rectangle. If the buffer is too small, no data is
  525.     * copied and zero is returned by the method. Otherwise, the method returns
  526.     * the number of characters copied.
  527.     * </p>
  528.     *
  529.     * @param buffer
  530.     * @param bufferLength
  531.     * @param startPos
  532.     * @param endPos
  533.     * @param plane
  534.     * @return The number of characters copied to the buffer
  535.     * @throws OhioException
  536.     */
  537.    protected int GetScreenRect(char buffer[], int bufferLength,
  538.                                              int startPos, int endPos, int plane)
  539. //                                             throws OhioException {
  540.                                              {
  541.       // We will use the row,col routine here because it is easier to use
  542.       // row colum than it is for position since I wrote the other first and
  543.       // am to lazy to implement it here
  544.       // Maybe it would be faster to do it the other way?
  545.       int startRow = convertPosToRow(startPos);
  546.       int startCol = convertPosToColumn(startPos);
  547.       int endRow = convertPosToRow(endPos);
  548.       int endCol = convertPosToColumn(endPos);
  549.       return GetScreenRect(buffer, bufferLength, startRow, startCol,
  550.                                  endRow, endCol, plane);
  551.    }
  552.    /**
  553.     * <p>
  554.     *  GetScreenRect retrieves data from the various planes associated with the
  555.     *  presentation space. The data is returned as a linear array of character
  556.     *  values in the buffer provided. The buffer is not terminated by a null
  557.     *  character.
  558.     * </p>
  559.     * <p>
  560.     * The application supplies two coordinates that represent opposing corners
  561.     * of a rectangle within the presentation space. The starting and ending
  562.     * coordinates can have any spatial relationship to each other. The data
  563.     * returned starts from the row containing the upper-most point to the row
  564.     * containing the lower-most point, and from the left-most column to the
  565.     * right-most column.
  566.     * </p>
  567.     * <p>
  568.     * The specified buffer must be at least large enough to contain the number
  569.     * of characters in the rectangle. If the buffer is too small, no data is
  570.     * copied and zero is returned by the method. Otherwise, the method returns
  571.     * the number of characters copied.
  572.     * </p>
  573.     *
  574.     * @param buffer
  575.     * @param bufferLength
  576.     * @param startRow
  577.     * @param startCol
  578.     * @param endRow
  579.     * @param endCol
  580.     * @param plane
  581.     * @return The number characters copied to the buffer
  582.     * @throws OhioException
  583.     */
  584.    protected int GetScreenRect(char buffer[], int bufferLength,
  585.                                              int startRow, int startCol,
  586.                                              int endRow, int endCol, int plane)
  587. //                                             throws OhioException {
  588.                                              {
  589.       // number of bytes obtained
  590.       int numBytes = 0;
  591.       // lets check the row range.  If they are reversed then we need to
  592.       // place them in the correct order.
  593.       if(startRow > endRow) {
  594.          int r = startRow;
  595.          startRow = endRow;
  596.          endRow = r;
  597.       }
  598.       // lets check the column range.  If they are reversed then we need to
  599.       // place them in the correct order.
  600.       if(startCol > endCol) {
  601.          int c = startCol;
  602.          startCol = endCol;
  603.          endCol = c;
  604.       }
  605.       int numCols = (endCol - startCol) + 1;
  606.       int numRows = (endRow - startRow) + 1;
  607.       // lets make sure it is within the bounds of the character array passed
  608.       //  if not the return as zero bytes where read as per documentation.
  609.       if(numCols * numRows <= bufferLength) {
  610.          // make sure it is one larger.  I guess for other languanges to
  611.          // reference like in C which is terminated by a zero byte at the end
  612.          // of strings.
  613.          char cb[] = new char[numCols + 1];
  614.          int charOffset = 0;
  615.          int bytes = 0;
  616.          // now let's loop through and get the screen information for
  617.          //  each row;
  618.          for(int row = startRow; row <= endRow;) {
  619.              if((bytes = GetScreen(cb, cb.length, row, startCol, numCols, plane)) != 0) {
  620.                  System.arraycopy(cb, 0, buffer, charOffset, numCols);
  621.              }
  622.              row++;
  623.              charOffset += numCols;
  624.              // make sure we count the number of bytes returned
  625.              numBytes += bytes;
  626.          }
  627.       }
  628.       return numBytes;
  629.    }
  630.    protected boolean checkHotSpots () {
  631.     Screen5250 s = scr;
  632.     int lenScreen = scr.getScreenLength();
  633.     boolean hs = false;
  634.    boolean retHS = false;
  635.    StringBuffer hsMore = s.getHSMore();
  636.    StringBuffer hsBottom = s.getHSBottom();
  637.       for (int x = 0; x < lenScreen; x++) {
  638.          hs =false;
  639.          if (s.isInField(x,false))
  640.             continue;
  641.          // First check for PF keys
  642.          if (x > 0 && screen[x] == 'F') {
  643.             if (screen[x + 1] >= '0' &&
  644.                      screen[x + 1] <= '9' &&
  645.                       screen[x - 1] <= ' ' &&
  646.                       (screenExtended[x] & EXTENDED_5250_NON_DSP) == 0) {
  647.                if (screen[x + 2] >= '0' &&
  648.                      screen[x + 2] <= '9' &&
  649.                       (screen[x + 3] == '=' ||
  650.                        screen[x + 3] == '-' ||
  651.                        screen[x + 3] == '/') )
  652.                   hs = true;
  653.                else
  654.                   if (   screen[x + 2] == '=' ||
  655.                          screen[x + 3] == '-' ||
  656.                          screen[x + 3] == '/')
  657.                      hs = true;
  658.                if (hs) {
  659.                   screenGUI[x] = BUTTON_LEFT;
  660.                   int ns = 0;
  661.                   int row = x / numCols;
  662.                   while (ns < 2 && ++x / numCols == row) {
  663.                      if (screen[x] <= ' ')
  664.                         ns++;
  665.                      else
  666.                         ns = 0;
  667.                      if (ns <2)
  668.                         screenGUI[x] = BUTTON_MIDDLE;
  669.                   }
  670.                   // now lets go back and take out gui's that do not belong
  671.                   while (screen[--x] <= ' ') {
  672.                      screenGUI[x] = NO_GUI;
  673.                   }
  674.                   screenGUI[x] = BUTTON_RIGHT;
  675.                }
  676.             }
  677.          }
  678.          // now lets check for menus
  679.          if (!hs && x > 0 && x < lenScreen - 2 &&
  680.                screen[x] == '.' &&
  681.                screenGUI[x] == NO_GUI &&
  682.                (screenExtended[x] & EXTENDED_5250_UNDERLINE) == 0 &&
  683.                (screenExtended[x] & EXTENDED_5250_NON_DSP) == 0
  684.             ) {
  685.             int os = 0;
  686.             if ((os = isOption(screen,x,lenScreen,2,3,'.') )> 0) {
  687.                hs = true;
  688.                int stop = x;
  689.                int ns = 0;
  690.                int row = stop / numCols;
  691.                while (++stop / numCols == row &&
  692.                             (screen[stop] >= ' ' ||
  693.                              screen[stop] == 0x0) ) {
  694.                   if (screen[stop] <= ' ') {
  695.                      ns++;
  696.                   }
  697.                   else
  698.                      ns = 0;
  699.                   if (screen[stop] == '.') {
  700.                      int io = 0;
  701.                      if ((io = isOption(screen,stop,lenScreen,2,3,'.')) > 0) {
  702.                         stop = io;
  703.                         break;
  704.                      }
  705.                   }
  706.                   if (ns > 3)
  707.                      break;
  708.                }
  709.                screenGUI[++os] = BUTTON_LEFT;
  710.                s.setDirty(os);
  711.                while (++os < stop) {
  712.                   screenGUI[os] = BUTTON_MIDDLE;
  713.                   s.setDirty(os);
  714.                }
  715.                // now lets go back and take out gui's that do not belong
  716.                while (screen[--stop] <= ' ') {
  717.                   screenGUI[stop] = NO_GUI;
  718.                   s.setDirty(stop);
  719.                }
  720.                screenGUI[stop] = BUTTON_RIGHT;
  721.                s.setDirty(stop);
  722.             }
  723.          }
  724.          // now lets check for options.
  725.          if (!hs && x > 0 && x < lenScreen - 2 &&
  726.                screen[x] == '=' &&
  727.                screenGUI[x] == NO_GUI &&
  728.                (screenExtended[x] & EXTENDED_5250_UNDERLINE) == 0 &&
  729.                (screenExtended[x] & EXTENDED_5250_NON_DSP) == 0
  730.             ) {
  731.             int os = 0;
  732.             if ((os = isOption(screen,x,lenScreen,2,2,'=') )> 0) {
  733.                hs = true;
  734.                int stop = x;
  735.                int ns = 0;
  736.                int row = stop / numCols;
  737.                while (++stop / numCols == row &&
  738.                             screen[stop] >= ' ') {
  739.                   if (screen[stop] == ' ') {
  740.                      ns++;
  741.                   }
  742.                   else
  743.                      ns = 0;
  744.                   if (screen[stop] == '=') {
  745.                      int io = 0;
  746.                      if ((io = isOption(screen,stop,lenScreen,2,2,'=')) > 0) {
  747.                         stop = io;
  748.                         break;
  749.                      }
  750.                   }
  751.                   if (ns > 2)
  752.                      break;
  753.                }
  754.                screenGUI[++os] = BUTTON_LEFT;
  755.                s.setDirty(os);
  756.                while (++os < stop) {
  757.                   screenGUI[os] = BUTTON_MIDDLE;
  758.                   s.setDirty(os);
  759.                }
  760.                // now lets go back and take out gui's that do not belong
  761.                while (screen[--stop] <= ' ') {
  762.                   screenGUI[stop] = NO_GUI;
  763.                   s.setDirty(stop);
  764.                }
  765.                screenGUI[stop] = BUTTON_RIGHT;
  766.                s.setDirty(stop);
  767.             }
  768.          }
  769.          // now lets check for More... .
  770.          if (!hs && x > 2 && x < lenScreen - hsMore.length() &&
  771.                screen[x] == hsMore.charAt(0) &&
  772.                screen[x - 1] <= ' ' &&
  773.                screen[x - 2] <= ' ' &&
  774.                screenGUI[x] == NO_GUI &&
  775.                (screenExtended[x] & EXTENDED_5250_NON_DSP) == 0
  776.             ) {
  777.             boolean mFlag = true;
  778.             int ms = hsMore.length();
  779.             int mc = 0;
  780.             while (++mc < ms) {
  781.                if (screen[x+mc] != hsMore.charAt(mc)) {
  782.                   mFlag = false;
  783.                   break;
  784.                }
  785.             }
  786.             if (mFlag) {
  787.                hs = true;
  788.                screenGUI[x] = BUTTON_LEFT_DN;
  789.                while (--ms > 0) {
  790.                   screenGUI[++x] = BUTTON_MIDDLE_DN;
  791.                }
  792.                screenGUI[x] = BUTTON_RIGHT_DN;
  793.             }
  794.          }
  795.          // now lets check for Bottom .
  796.          if (!hs && x > 2 && x < lenScreen - hsBottom.length() &&
  797.                screen[x] == hsBottom.charAt(0) &&
  798.                screen[x - 1]  <= ' ' &&
  799.                screen[x - 2] <= ' ' &&
  800.                screenGUI[x] == NO_GUI &&
  801.                (screenExtended[x] & EXTENDED_5250_NON_DSP) == 0
  802.             ) {
  803.             boolean mFlag = true;
  804.             int bs = hsBottom.length();
  805.             int bc = 0;
  806.             while (++bc < bs) {
  807.                if (screen[x+bc] != hsBottom.charAt(bc)) {
  808.                   mFlag = false;
  809.                   break;
  810.                }
  811.             }
  812.             if (mFlag) {
  813.                hs = true;
  814.                screenGUI[x] = BUTTON_LEFT_UP;
  815.                while (--bs > 0) {
  816.                   screenGUI[++x] = BUTTON_MIDDLE_UP;
  817.                }
  818.                screenGUI[x] = BUTTON_RIGHT_UP;
  819.             }
  820.          }
  821.             // Submitted by Richard Houston of RLH Consulting rhouston@rlhc.net
  822.             // now lets check for HTTP:// or HTTPS://.
  823.          if (!hs && x > 0 && x < lenScreen - 7 &&
  824.                Character.toLowerCase(screen[x]) == 'h' &&
  825.                screen[x - 1] <= ' ' &&
  826.                screenGUI[x] == NO_GUI &&
  827.                (screenExtended[x] & EXTENDED_5250_NON_DSP) == 0
  828.             ) {
  829.             if (Character.toLowerCase(screen[x+1]) == 't' &&
  830.                   Character.toLowerCase(screen[x+2]) == 't' &&
  831.                   Character.toLowerCase(screen[x+3]) == 'p' &&
  832.                   screen[x+4] == ':' &&
  833.                   screen[x+5] == '/' &&
  834.                   screen[x+6] == '/' ) {
  835.                hs = true;
  836.                screenGUI[x] = BUTTON_LEFT_EB;
  837.                while (screen[++x] > ' ') {
  838.                   screenGUI[x] = BUTTON_MIDDLE_EB;
  839.                }
  840.                screenGUI[--x] = BUTTON_RIGHT_EB;
  841.             }
  842.             else if (Character.toLowerCase(screen[x+1]) == 't' &&
  843.                   Character.toLowerCase(screen[x+2]) == 't' &&
  844.                   Character.toLowerCase(screen[x+3]) == 'p' &&
  845.   Character.toLowerCase(screen[x+4]) == 's' &&
  846.                   screen[x+5] == ':' &&
  847.                   screen[x+6] == '/' &&
  848.                   screen[x+7] == '/' ) {
  849.                hs = true;
  850.                screenGUI[x] = BUTTON_LEFT_EB;
  851.                while (screen[++x] > ' ') {
  852.                   screenGUI[x] = BUTTON_MIDDLE_EB;
  853.                }
  854.                screenGUI[--x] = BUTTON_RIGHT_EB;
  855.             }
  856.          }
  857.             else {
  858.                // now lets check for MAILTO: .
  859.                if (!hs && x > 0 && x < lenScreen - 7 &&
  860.                      Character.toLowerCase(screen[x]) == 'm' &&
  861.                      screen[x - 1] <= ' ' &&
  862.                      screenGUI[x] == NO_GUI &&
  863.                      (screenExtended[x] & EXTENDED_5250_NON_DSP) == 0
  864.                   ) {
  865.                   if (Character.toLowerCase(screen[x+1]) == 'a' &&
  866.                         Character.toLowerCase(screen[x+2]) == 'i' &&
  867.                         Character.toLowerCase(screen[x+3]) == 'l' &&
  868.                         Character.toLowerCase(screen[x+4]) == 't' &&
  869.                         Character.toLowerCase(screen[x+5]) == 'o' &&
  870.                         screen[x+6] == ':') {
  871.                      hs = true;
  872.                      screenGUI[x] = BUTTON_LEFT_EB;
  873.                      while (screen[++x] > ' ') {
  874.                         screenGUI[x] = BUTTON_MIDDLE_EB;
  875.                      }
  876.                      screenGUI[--x] = BUTTON_RIGHT_EB;
  877.                   }
  878.                }
  879.             }
  880.          if (!retHS && hs)
  881.             retHS = true;
  882.       }
  883.       return retHS;
  884. }
  885. private int isOption(char[] screen,
  886.                               int x,
  887.                               int lenScreen,
  888.                               int numPref,
  889.                               int numSuff,
  890.                               char suff) {
  891.    boolean hs =true;
  892.    int sp = x;
  893.    int os = 0;
  894.    // check to the left for option
  895.    while (--sp >=0 &&  screen[sp] <= ' ' ) {
  896.       if (x - sp > numPref || screen[sp] == suff||
  897.                screen[sp] == '.' ||
  898.                screen[sp] == '*') {
  899.          hs =false;
  900.          break;
  901.       }
  902.    }
  903.    // now lets check for how long the option is it has to be numPref or less
  904.    os = sp;
  905.    while (hs && --os > 0 && screen[os] > ' ' ) {
  906.       if (sp - os >= numPref || screen[os] == suff ||
  907.                screen[os] == '.' ||
  908.                screen[os] == '*') {
  909.          hs = false;
  910.          break;
  911.       }
  912.    }
  913.    if (sp - os > 1 && !Character.isDigit(screen[os+1])) {
  914.       hs = false;
  915.    }
  916.    sp = x;
  917.    if (Character.isDigit(screen[sp+1]))
  918.       hs = false;
  919.    // now lets make sure there are no more than numSuff spaces after option
  920.    while (hs && (++sp < lenScreen && screen[sp] <= ' '
  921.                   || screen[sp] == suff )) {
  922.       if (sp - x >= numSuff || screen[sp] == suff ||
  923.                   screen[sp] == '.' ||
  924.                screen[sp] == '*') {
  925.          hs =false;
  926.          break;
  927.       }
  928.    }
  929.    if (hs && !Character.isLetterOrDigit(screen[sp]))
  930.       hs = false;
  931.    if (hs) {
  932.       return os;
  933.    }
  934.    return -1;
  935. }
  936. }