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