comparison app/src/main/java/org/tn5250j/framework/tn5250/Screen5250.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/Screen5250.java@b525a8141923
children
comparison
equal deleted inserted replaced
437:208b31032318 438:d29cce60f393
1 /*
2 * Title: Screen5250.java
3 * Copyright: Copyright (c) 2001 - 2004
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 import java.text.DecimalFormat;
31 import java.text.DecimalFormatSymbols;
32 import java.text.NumberFormat;
33 import java.text.ParseException;
34 import java.util.Vector;
35
36 import org.tn5250j.TN5250jConstants;
37
38 import android.util.Log;
39 import de.mud.terminal.VDUBuffer;
40 import de.mud.terminal.vt320;
41 import com.five_ten_sg.connectbot.service.FontSizeChangedListener;
42
43
44 public class Screen5250 implements FontSizeChangedListener {
45 private static final String TAG = "Screen5250";
46 private ScreenFields screenFields;
47 private int lastAttr;
48 private int lastPos;
49 private int lenScreen;
50 private KeyStrokenizer strokenizer;
51 private tnvt sessionVT;
52 private vt320 buffer; // used to draw the screen
53 private int numRows = 0;
54 private int numCols = 0;
55 protected static final int initAttr = 32;
56 protected static final char initChar = 0;
57 public boolean cursorActive = false;
58 public boolean cursorShown = false;
59 protected boolean insertMode = false;
60 private boolean keyProcessed = false;
61 private Rect dirtyScreen = new Rect();
62
63 public int homePos = 0;
64 public int saveHomePos = 0;
65 private String bufferedKeys;
66 public boolean pendingInsert = false;
67
68 public final static byte STATUS_SYSTEM = 1;
69 public final static byte STATUS_ERROR_CODE = 2;
70 public final static byte STATUS_VALUE_ON = 1;
71 public final static byte STATUS_VALUE_OFF = 2;
72
73 private StringBuffer hsMore = new StringBuffer("More...");
74 private StringBuffer hsBottom = new StringBuffer("Bottom");
75
76 // error codes to be sent to the host on an error
77 private final static int ERR_CURSOR_PROTECTED = 0x05;
78 private final static int ERR_INVALID_SIGN = 0x11;
79 private final static int ERR_NO_ROOM_INSERT = 0x12;
80 private final static int ERR_NUMERIC_ONLY = 0x09;
81 private final static int ERR_DUP_KEY_NOT_ALLOWED = 0x19;
82 private final static int ERR_NUMERIC_09 = 0x10;
83 private final static int ERR_FIELD_MINUS = 0x16;
84 private final static int ERR_FIELD_EXIT_INVALID = 0x18;
85 private final static int ERR_ENTER_NO_ALLOWED = 0x20;
86 private final static int ERR_MANDATORY_ENTER = 0x21;
87
88 private boolean guiInterface = false;
89 private boolean resetRequired = false;
90 private boolean backspaceError = true;
91 private boolean feError;
92
93 // Operator Information Area
94 private ScreenOIA oia;
95
96 // screen planes
97 protected ScreenPlanes planes;
98
99
100
101 public Screen5250() {
102 try {
103 jbInit();
104 }
105 catch (Exception ex) {
106 Log.w(TAG, "In constructor: ", ex);
107 }
108 }
109
110 void jbInit() throws Exception {
111 lastAttr = 32;
112 // default number of rows and columns
113 numRows = 24;
114 numCols = 80;
115 setCursor(1, 1); // set initial cursor position
116 oia = new ScreenOIA(this);
117 oia.setKeyBoardLocked(true);
118 lenScreen = numRows * numCols;
119 planes = new ScreenPlanes(this, numRows);
120 screenFields = new ScreenFields(this);
121 strokenizer = new KeyStrokenizer();
122 }
123
124 protected ScreenPlanes getPlanes() {
125 return planes;
126 }
127
128 public final ScreenOIA getOIA() {
129 return oia;
130 }
131
132 protected final void setRowsCols(int rows, int cols) {
133 int oldRows = numRows;
134 int oldCols = numCols;
135 // default number of rows and columns
136 numRows = rows;
137 numCols = cols;
138 lenScreen = numRows * numCols;
139 planes.setSize(rows);
140
141 // If they are not the same then we need to inform the listeners that
142 // the size changed.
143 if (oldRows != numRows || oldCols != numCols)
144 fireScreenSizeChanged();
145 }
146
147
148 public boolean isCursorActive() {
149 return cursorActive;
150 }
151
152 public boolean isCursorShown() {
153 return cursorShown;
154 }
155
156 public void setUseGUIInterface(boolean gui) {
157 guiInterface = gui;
158 }
159
160 public void toggleGUIInterface() {
161 guiInterface = !guiInterface;
162 }
163
164 public void setResetRequired(boolean reset) {
165 resetRequired = reset;
166 }
167
168 public void setBackspaceError(boolean onError) {
169 backspaceError = onError;
170 }
171
172 /**
173 * Copy & Paste support
174 *
175 * @see {@link #pasteText(String, boolean)}
176 * @see {@link #copyTextField(int)}
177 */
178 public final String copyText(Rect area) {
179 StringBuilder sb = new StringBuilder();
180 Rect workR = new Rect();
181 workR.setBounds(area);
182 Log.d(TAG, "Copying " + workR);
183 // loop through all the screen characters to send them to the clip board
184 int m = workR.x;
185 int i = 0;
186 int t = 0;
187
188 while (workR.height-- > 0) {
189 t = workR.width;
190 i = workR.y;
191
192 while (t-- > 0) {
193 // only copy printable characters (in this case >= ' ')
194 char c = planes.getChar(getPos(m - 1, i - 1));
195
196 if (c >= ' ' && (planes.screenExtended[getPos(m - 1, i - 1)] & EXTENDED_5250_NON_DSP)
197 == 0)
198 sb.append(c);
199 else
200 sb.append(' ');
201
202 i++;
203 }
204
205 sb.append('\n');
206 m++;
207 }
208
209 return sb.toString();
210 }
211
212 /**
213 * Copy & Paste support
214 *
215 * @param content
216 * @see {@link #copyText(Rectangle)}
217 */
218 public final void pasteText(String content, boolean special) {
219 Log.d(TAG, "Pasting, special:" + special);
220 setCursorActive(false);
221 StringBuilder sb = new StringBuilder(content);
222 StringBuilder pd = new StringBuilder();
223 // character counters within the string to be pasted.
224 int nextChar = 0;
225 int nChars = sb.length();
226 int lr = getRow(lastPos);
227 int lc = getCol(lastPos);
228 resetDirty(lastPos);
229 int cpos = lastPos;
230 int length = getScreenLength();
231 char c = 0;
232 boolean setIt;
233 // save our current place within the FFT.
234 screenFields.saveCurrentField();
235
236 for (int x = nextChar; x < nChars; x++) {
237 c = sb.charAt(x);
238
239 if ((c == '\n') || (c == '\r')) {
240 Log.i(TAG, "pasted cr-lf>" + pd + "<");
241 pd.setLength(0);
242 // if we read in a cr lf in the data stream we need to go
243 // to the starting column of the next row and start from there
244 cpos = getPos(getRow(cpos) + 1, lc);
245
246 // If we go paste the end of the screen then let's start over from
247 // the beginning of the screen space.
248 if (cpos > length)
249 cpos = 0;
250 }
251 else {
252 // we will default to set the character always.
253 setIt = true;
254
255 // If we are in a special paste scenario then we check for valid
256 // characters to paste.
257 if (special && (!Character.isLetter(c) && !Character.isDigit(c)))
258 setIt = false;
259
260 // we will only push a character to the screen space if we are in
261 // a field
262 if (isInField(cpos) && setIt) {
263 planes.setChar(cpos, c);
264 setDirty(cpos);
265 screenFields.setCurrentFieldMDT();
266 }
267
268 // If we placed a character then we go to the next position.
269 if (setIt)
270 cpos++;
271
272 // we will append the information to our debug buffer.
273 pd.append(c);
274 }
275 }
276
277 // if we have anything else not logged then log it out.
278 if (pd.length() > 0)
279 Log.i(TAG, "pasted >" + pd + "<");
280
281 // restore out position within the FFT.
282 screenFields.restoreCurrentField();
283 updateDirty();
284 // restore our cursor position.
285 setCursor(lr + 1, lc + 1);
286 setCursorActive(true);
287 }
288
289 /**
290 * Copy & Paste support
291 *
292 * @param position
293 * @return
294 * @see {@link #copyText(int)}
295 */
296 public final String copyTextField(int position) {
297 screenFields.saveCurrentField();
298 isInField(position);
299 String result = screenFields.getCurrentFieldText();
300 screenFields.restoreCurrentField();
301 return result;
302 }
303
304 /**
305 *
306 * Copy & Paste end code
307 *
308 */
309
310 /**
311 * Sum them
312 *
313 * @param which
314 * formatting option to use
315 * @return vector string of numberic values
316 */
317 public final Vector<Double> sumThem(boolean which, Rect area) {
318 StringBuilder sb = new StringBuilder();
319 Rect workR = new Rect();
320 workR.setBounds(area);
321 // gui.rubberband.reset();
322 // gui.repaint();
323 Log.d(TAG, "Summing");
324 // obtain the decimal format for parsing
325 DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
326 DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
327
328 if (which) {
329 dfs.setDecimalSeparator('.');
330 dfs.setGroupingSeparator(',');
331 }
332 else {
333 dfs.setDecimalSeparator(',');
334 dfs.setGroupingSeparator('.');
335 }
336
337 df.setDecimalFormatSymbols(dfs);
338 Vector<Double> sumVector = new Vector<Double>();
339 // loop through all the screen characters to send them to the clip board
340 int m = workR.x;
341 int i = 0;
342 int t = 0;
343 double sum = 0.0;
344
345 while (workR.height-- > 0) {
346 t = workR.width;
347 i = workR.y;
348
349 while (t-- > 0) {
350 // only copy printable numeric characters (in this case >= ' ')
351 // char c = screen[getPos(m - 1, i - 1)].getChar();
352 char c = planes.getChar(getPos(m - 1, i - 1));
353 // if (((c >= '0' && c <= '9') || c == '.' || c == ',' || c == '-')
354 // && !screen[getPos(m - 1, i - 1)].nonDisplay) {
355
356 // TODO: update me here to implement the nonDisplay check as well
357 if (((c >= '0' && c <= '9') || c == '.' || c == ',' || c == '-')) {
358 sb.append(c);
359 }
360
361 i++;
362 }
363
364 if (sb.length() > 0) {
365 if (sb.charAt(sb.length() - 1) == '-') {
366 sb.insert(0, '-');
367 sb.deleteCharAt(sb.length() - 1);
368 }
369
370 try {
371 Number n = df.parse(sb.toString());
372 // System.out.println(s + " " + n.doubleValue());
373 sumVector.add(new Double(n.doubleValue()));
374 sum += n.doubleValue();
375 }
376 catch (ParseException pe) {
377 Log.w(TAG, pe.getMessage() + " at "
378 + pe.getErrorOffset());
379 }
380 }
381
382 sb.setLength(0);
383 m++;
384 }
385
386 Log.d(TAG, "" + sum);
387 return sumVector;
388 }
389
390 public void setVT(tnvt v) {
391 sessionVT = v;
392 }
393
394 public void setBuffer(vt320 buffer) {
395 this.buffer = buffer;
396 }
397
398 /**
399 * converts mnemonic string values into aid integers
400 *
401 * @see #sendKeys
402 * @param mnem string mnemonic value
403 * @return key value of Mnemonic
404 */
405 private int getMnemonicValue(String mnem) {
406 if (mnemonicMap.containsKey(mnem)) return mnemonicMap.get(mnem);
407
408 return 0;
409 }
410
411 protected void setPrehelpState(boolean setErrorCode, boolean lockKeyboard,
412 boolean unlockIfLocked) {
413 if (oia.isKeyBoardLocked() && unlockIfLocked)
414 oia.setKeyBoardLocked(false);
415 else
416 oia.setKeyBoardLocked(lockKeyboard);
417
418 bufferedKeys = null;
419 oia.setKeysBuffered(false);
420 }
421
422 /**
423 * Activate the cursor on screen
424 *
425 * @param activate
426 */
427 public void setCursorActive(boolean activate) {
428 // System.out.println("cursor active " + updateCursorLoc + " " +
429 // cursorActive + " " + activate);
430 if (cursorActive && !activate) {
431 setCursorOff();
432 cursorActive = activate;
433 }
434 else {
435 if (!cursorActive && activate) {
436 cursorActive = activate;
437 setCursorOn();
438 }
439 }
440 }
441
442 /**
443 * Set the cursor on
444 */
445 public void setCursorOn() {
446 cursorShown = true;
447 updateCursorLoc();
448 }
449
450 /**
451 * Set the cursor off
452 */
453 public void setCursorOff() {
454 cursorShown = false;
455 updateCursorLoc();
456 // System.out.println("cursor off " + updateCursorLoc + " " +
457 // cursorActive);
458 }
459
460 /**
461 *
462 */
463 private void updateCursorLoc() {
464 if (cursorActive) {
465 fireCursorChanged();
466 }
467 }
468
469 /**
470 * The sendKeys method sends a string of keys to the virtual screen. This
471 * method acts as if keystrokes were being typed from the keyboard. The
472 * keystrokes will be sent to the location given. The string being passed
473 * can also contain mnemonic values such as [enter] enter key,[tab] tab key,
474 * [pf1] pf1 etc...
475 *
476 * These will be processed as if you had pressed these keys from the
477 * keyboard. All the valid special key values are contained in the MNEMONIC
478 * enumeration:
479 *
480 * <table BORDER COLS=2 WIDTH="50%" >
481 *
482 * <tr>
483 * <td>MNEMONIC_CLEAR</td>
484 * <td>[clear]</td>
485 * </tr>
486 * <tr>
487 * <td>MNEMONIC_ENTER</td>
488 * <td>[enter]</td>
489 * </tr>
490 * <tr>
491 * <td>MNEMONIC_HELP</td>
492 * <td>[help]</td>
493 * </tr>
494 * <tr>
495 * <td>MNEMONIC_PAGE_DOWN</td>
496 * <td>[pgdown]</td>
497 * </tr>
498 * <tr>
499 * <td>MNEMONIC_PAGE_UP</td>
500 * <td>[pgup]</td>
501 * </tr>
502 * <tr>
503 * <td>MNEMONIC_PRINT</td>
504 * <td>[print]</td>
505 * </tr>
506 * <tr>
507 * <td>MNEMONIC_PF1</td>
508 * <td>[pf1]</td>
509 * </tr>
510 * <tr>
511 * <td>MNEMONIC_PF2</td>
512 * <td>[pf2]</td>
513 * </tr>
514 * <tr>
515 * <td>MNEMONIC_PF3</td>
516 * <td>[pf3]</td>
517 * </tr>
518 * <tr>
519 * <td>MNEMONIC_PF4</td>
520 * <td>[pf4]</td>
521 * </tr>
522 * <tr>
523 * <td>MNEMONIC_PF5</td>
524 * <td>[pf5]</td>
525 * </tr>
526 * <tr>
527 * <td>MNEMONIC_PF6</td>
528 * <td>[pf6]</td>
529 * </tr>
530 * <tr>
531 * <td>MNEMONIC_PF7</td>
532 * <td>[pf7]</td>
533 * </tr>
534 * <tr>
535 * <td>MNEMONIC_PF8</td>
536 * <td>[pf8]</td>
537 * </tr>
538 * <tr>
539 * <td>MNEMONIC_PF9</td>
540 * <td>[pf9]</td>
541 * </tr>
542 * <tr>
543 * <td>MNEMONIC_PF10</td>
544 * <td>[pf10]</td>
545 * </tr>
546 * <tr>
547 * <td>MNEMONIC_PF11</td>
548 * <td>[pf11]</td>
549 * </tr>
550 * <tr>
551 * <td>MNEMONIC_PF12</td>
552 * <td>[pf12]</td>
553 * </tr>
554 * <tr>
555 * <td>MNEMONIC_PF13</td>
556 * <td>[pf13]</td>
557 * </tr>
558 * <tr>
559 * <td>MNEMONIC_PF14</td>
560 * <td>[pf14]</td>
561 * </tr>
562 * <tr>
563 * <td>MNEMONIC_PF15</td>
564 * <td>[pf15]</td>
565 * </tr>
566 * <tr>
567 * <td>MNEMONIC_PF16</td>
568 * <td>[pf16]</td>
569 * </tr>
570 * <tr>
571 * <td>MNEMONIC_PF17</td>
572 * <td>[pf17]</td>
573 * </tr>
574 * <tr>
575 * <td>MNEMONIC_PF18</td>
576 * <td>[pf18]</td>
577 * </tr>
578 * <tr>
579 * <td>MNEMONIC_PF19</td>
580 * <td>[pf19]</td>
581 * </tr>
582 * <tr>
583 * <td>MNEMONIC_PF20</td>
584 * <td>[pf20]</td>
585 * </tr>
586 * <tr>
587 * <td>MNEMONIC_PF21</td>
588 * <td>[pf21]</td>
589 * </tr>
590 * <tr>
591 * <td>MNEMONIC_PF22</td>
592 * <td>[pf22]</td>
593 * </tr>
594 * <tr>
595 * <td>MNEMONIC_PF23</td>
596 * <td>[pf23]</td>
597 * </tr>
598 * <tr>
599 * <td>MNEMONIC_PF24</td>
600 * <td>[pf24]</td>
601 * </tr>
602 * <tr>
603 * <td>MNEMONIC_BACK_SPACE</td>
604 * <td>[backspace]</td>
605 * </tr>
606 * <tr>
607 * <td>MNEMONIC_BACK_TAB</td>
608 * <td>[backtab]</td>
609 * </tr>
610 * <tr>
611 * <td>MNEMONIC_UP</td>
612 * <td>[up]</td>
613 * </tr>
614 * <tr>
615 * <td>MNEMONIC_DOWN</td>
616 * <td>[down]</td>
617 * </tr>
618 * <tr>
619 * <td>MNEMONIC_LEFT</td>
620 * <td>[left]</td>
621 * </tr>
622 * <tr>
623 * <td>MNEMONIC_RIGHT</td>
624 * <td>[right]</td>
625 * </tr>
626 * <tr>
627 * <td>MNEMONIC_DELETE</td>
628 * <td>[delete]</td>
629 * </tr>
630 * <tr>
631 * <td>MNEMONIC_TAB</td>
632 * <td>"[tab]</td>
633 * </tr>
634 * <tr>
635 * <td>MNEMONIC_END_OF_FIELD</td>
636 * <td>[eof]</td>
637 * </tr>
638 * <tr>
639 * <td>MNEMONIC_ERASE_EOF</td>
640 * <td>[eraseeof]</td>
641 * </tr>
642 * <tr>
643 * <td>MNEMONIC_ERASE_FIELD</td>
644 * <td>[erasefld]</td>
645 * </tr>
646 * <tr>
647 * <td>MNEMONIC_INSERT</td>
648 * <td>[insert]</td>
649 * </tr>
650 * <tr>
651 * <td>MNEMONIC_HOME</td>
652 * <td>[home]</td>
653 * </tr>
654 * <tr>
655 * <td>MNEMONIC_KEYPAD0</td>
656 * <td>[keypad0]</td>
657 * </tr>
658 * <tr>
659 * <td>MNEMONIC_KEYPAD1</td>
660 * <td>[keypad1]</td>
661 * </tr>
662 * <tr>
663 * <td>MNEMONIC_KEYPAD2</td>
664 * <td>[keypad2]</td>
665 * </tr>
666 * <tr>
667 * <td>MNEMONIC_KEYPAD3</td>
668 * <td>[keypad3]</td>
669 * </tr>
670 * <tr>
671 * <td>MNEMONIC_KEYPAD4</td>
672 * <td>[keypad4]</td>
673 * </tr>
674 * <tr>
675 * <td>MNEMONIC_KEYPAD5</td>
676 * <td>[keypad5]</td>
677 * </tr>
678 * <tr>
679 * <td>MNEMONIC_KEYPAD6</td>
680 * <td>[keypad6]</td>
681 * </tr>
682 * <tr>
683 * <td>MNEMONIC_KEYPAD7</td>
684 * <td>[keypad7]</td>
685 * </tr>
686 * <tr>
687 * <td>MNEMONIC_KEYPAD8</td>
688 * <td>[keypad8]</td>
689 * </tr>
690 * <tr>
691 * <td>MNEMONIC_KEYPAD9</td>
692 * <td>[keypad9]</td>
693 * </tr>
694 * <tr>
695 * <td>MNEMONIC_KEYPAD_PERIOD</td>
696 * <td>[keypad.]</td>
697 * </tr>
698 * <tr>
699 * <td>MNEMONIC_KEYPAD_COMMA</td>
700 * <td>[keypad,]</td>
701 * </tr>
702 * <tr>
703 * <td>MNEMONIC_KEYPAD_MINUS</td>
704 * <td>[keypad-]</td>
705 * </tr>
706 * <tr>
707 * <td>MNEMONIC_FIELD_EXIT</td>
708 * <td>[fldext]</td>
709 * </tr>
710 * <tr>
711 * <td>MNEMONIC_FIELD_PLUS</td>
712 * <td>[field+]</td>
713 * </tr>
714 * <tr>
715 * <td>MNEMONIC_FIELD_MINUS</td>
716 * <td>[field-]</td>
717 * </tr>
718 * <tr>
719 * <td>MNEMONIC_BEGIN_OF_FIELD</td>
720 * <td>[bof]</td>
721 * </tr>
722 * <tr>
723 * <td>MNEMONIC_PA1</td>
724 * <td>[pa1]</td>
725 * </tr>
726 * <tr>
727 * <td>MNEMONIC_PA2</td>
728 * <td>[pa2]</td>
729 * </tr>
730 * <tr>
731 * <td>MNEMONIC_PA3</td>
732 * <td>[pa3]</td>
733 * </tr>
734 * <tr>
735 * <td>MNEMONIC_SYSREQ</td>
736 * <td>[sysreq]</td>
737 * </tr>
738 * <tr>
739 * <td>MNEMONIC_RESET</td>
740 * <td>[reset]</td>
741 * </tr>
742 * <tr>
743 * <td>MNEMONIC_ATTN</td>
744 * <td>[attn]</td>
745 * </tr>
746 * <tr>
747 * <td>MNEMONIC_MARK_LEFT</td>
748 * <td>[markleft]</td>
749 * </tr>
750 * <tr>
751 * <td>MNEMONIC_MARK_RIGHT</td>
752 * <td>[markright]</td>
753 * </tr>
754 * <tr>
755 * <td>MNEMONIC_MARK_UP</td>
756 * <td>[markup]</td>
757 * </tr>
758 * <tr>
759 * <td>MNEMONIC_MARK_DOWN</td>
760 * <td>[markdown]</td>
761 * </tr>
762 *
763 * </table>
764 *
765 * @param text
766 * The string of characters to be sent
767 *
768 * @see #sendAid
769 *
770 */
771
772 public synchronized void sendKeys(String text) {
773 if (isStatusErrorCode() && !resetRequired) {
774 setCursorActive(false);
775 simulateMnemonic(getMnemonicValue("[reset]"));
776 setCursorActive(true);
777 }
778
779 if (oia.isKeyBoardLocked()) {
780 if (text.equals("[reset]") || text.equals("[sysreq]")
781 || text.equals("[attn]")) {
782 setCursorActive(false);
783 simulateMnemonic(getMnemonicValue(text));
784 setCursorActive(true);
785 }
786 else {
787 if (isStatusErrorCode()) {
788 sessionVT.signalBell();
789 return;
790 }
791
792 oia.setKeysBuffered(true);
793
794 if (bufferedKeys == null) bufferedKeys = text;
795 else bufferedKeys += text;
796
797 return;
798 }
799 }
800 else {
801 if (oia.isKeysBuffered()) {
802 if (bufferedKeys != null) {
803 text = bufferedKeys + text;
804 }
805
806 oia.setKeysBuffered(false);
807 bufferedKeys = null;
808 }
809
810 isInField();
811
812 if (text.length() == 1 && !text.equals("[") && !text.equals("]")) {
813 setCursorActive(false);
814 simulateKeyStroke(text.charAt(0));
815 setCursorActive(true);
816 }
817 else {
818 strokenizer.setKeyStrokes(text);
819 String s;
820 boolean done = false;
821 // setCursorOff2();
822 setCursorActive(false);
823
824 while (!done) {
825 if (strokenizer.hasMoreKeyStrokes()) {
826 isInField();
827 s = strokenizer.nextKeyStroke();
828
829 if (s.length() == 1) {
830 simulateKeyStroke(s.charAt(0));
831 }
832 else {
833 simulateMnemonic(getMnemonicValue(s));
834 }
835
836 if (oia.isKeyBoardLocked()) {
837 bufferedKeys = strokenizer
838 .getUnprocessedKeyStroked();
839
840 if (bufferedKeys != null) {
841 oia.setKeysBuffered(true);
842 }
843
844 done = true;
845 }
846 }
847 else {
848 done = true;
849 }
850 }
851
852 setCursorActive(true);
853 }
854 }
855 }
856
857 /**
858 * The sendAid method sends an "aid" keystroke to the virtual screen. These
859 * aid keys can be thought of as special keystrokes, like the Enter key,
860 * PF1-24 keys or the Page Up key. All the valid special key values are
861 * contained in the AID_ enumeration:
862 *
863 * @param aidKey
864 * The aid key to be sent to the host
865 *
866 * @see #sendKeys
867 * @see TN5250jConstants#AID_CLEAR
868 * @see #AID_ENTER
869 * @see #AID_HELP
870 * @see #AID_ROLL_UP
871 * @see #AID_ROLL_DOWN
872 * @see #AID_ROLL_LEFT
873 * @see #AID_ROLL_RIGHT
874 * @see #AID_PRINT
875 * @see #AID_PF1
876 * @see #AID_PF2
877 * @see #AID_PF3
878 * @see #AID_PF4
879 * @see #AID_PF5
880 * @see #AID_PF6
881 * @see #AID_PF7
882 * @see #AID_PF8
883 * @see #AID_PF9
884 * @see #AID_PF10
885 * @see #AID_PF11
886 * @see #AID_PF12
887 * @see #AID_PF13
888 * @see #AID_PF14
889 * @see #AID_PF15
890 * @see #AID_PF16
891 * @see #AID_PF17
892 * @see #AID_PF18
893 * @see #AID_PF19
894 * @see #AID_PF20
895 * @see #AID_PF21
896 * @see #AID_PF22
897 * @see #AID_PF23
898 * @see #AID_PF24
899 */
900 public void sendAid(int aidKey) {
901 sessionVT.sendAidKey(aidKey);
902 }
903
904 /**
905 * Restores the error line and sets the error mode off.
906 *
907 */
908 protected void resetError() {
909 restoreErrorLine();
910 setStatus(STATUS_ERROR_CODE, STATUS_VALUE_OFF, "");
911 }
912
913 protected boolean simulateMnemonic(int mnem) {
914 boolean simulated = false;
915
916 switch (mnem) {
917 case AID_CLEAR:
918 case AID_ENTER:
919 case AID_PF1:
920 case AID_PF2:
921 case AID_PF3:
922 case AID_PF4:
923 case AID_PF5:
924 case AID_PF6:
925 case AID_PF7:
926 case AID_PF8:
927 case AID_PF9:
928 case AID_PF10:
929 case AID_PF11:
930 case AID_PF12:
931 case AID_PF13:
932 case AID_PF14:
933 case AID_PF15:
934 case AID_PF16:
935 case AID_PF17:
936 case AID_PF18:
937 case AID_PF19:
938 case AID_PF20:
939 case AID_PF21:
940 case AID_PF22:
941 case AID_PF23:
942 case AID_PF24:
943 case AID_ROLL_DOWN:
944 case AID_ROLL_UP:
945 case AID_ROLL_LEFT:
946 case AID_ROLL_RIGHT:
947 if (!screenFields.isCanSendAid()) {
948 displayError(ERR_ENTER_NO_ALLOWED);
949 }
950 else
951 sendAid(mnem);
952
953 simulated = true;
954 break;
955
956 case AID_HELP:
957 sessionVT.sendHelpRequest();
958 simulated = true;
959 break;
960
961 case AID_PRINT:
962 sessionVT.hostPrint(1);
963 simulated = true;
964 break;
965
966 case BACK_SPACE:
967 if (screenFields.getCurrentField() != null
968 && screenFields.withinCurrentField(lastPos)
969 && !screenFields.isCurrentFieldBypassField()) {
970 if (screenFields.getCurrentField().startPos() == lastPos) {
971 if (backspaceError)
972 displayError(ERR_CURSOR_PROTECTED);
973 else {
974 gotoFieldPrev();
975 goto_XY(screenFields.getCurrentField().endPos());
976 updateDirty();
977 }
978 }
979 else {
980 screenFields.getCurrentField().getKeyPos(lastPos);
981 screenFields.getCurrentField().changePos(-1);
982 resetDirty(screenFields.getCurrentField().getCurrentPos());
983 shiftLeft(screenFields.getCurrentField().getCurrentPos());
984 updateDirty();
985 screenFields.setCurrentFieldMDT();
986 simulated = true;
987 }
988 }
989 else {
990 displayError(ERR_CURSOR_PROTECTED);
991 }
992
993 break;
994
995 case BACK_TAB:
996 if (screenFields.getCurrentField() != null
997 && screenFields.isCurrentFieldHighlightedEntry()) {
998 resetDirty(screenFields.getCurrentField().startPos);
999 gotoFieldPrev();
1000 updateDirty();
1001 }
1002 else
1003 gotoFieldPrev();
1004
1005 if (screenFields.isCurrentFieldContinued()) {
1006 do {
1007 gotoFieldPrev();
1008 }
1009 while (screenFields.isCurrentFieldContinuedMiddle()
1010 || screenFields.isCurrentFieldContinuedLast());
1011 }
1012
1013 isInField();
1014 simulated = true;
1015 break;
1016
1017 case UP:
1018 case MARK_UP:
1019 process_XY(lastPos - numCols);
1020 simulated = true;
1021 break;
1022
1023 case DOWN:
1024 case MARK_DOWN:
1025 process_XY(lastPos + numCols);
1026 simulated = true;
1027 break;
1028
1029 case LEFT:
1030 case MARK_LEFT:
1031 process_XY(lastPos - 1);
1032 simulated = true;
1033 break;
1034
1035 case RIGHT:
1036 case MARK_RIGHT:
1037 process_XY(lastPos + 1);
1038 simulated = true;
1039 break;
1040
1041 case NEXTWORD:
1042 gotoNextWord();
1043 simulated = true;
1044 break;
1045
1046 case PREVWORD:
1047 gotoPrevWord();
1048 simulated = true;
1049 break;
1050
1051 case DELETE:
1052 if (screenFields.getCurrentField() != null
1053 && screenFields.withinCurrentField(lastPos)
1054 && !screenFields.isCurrentFieldBypassField()) {
1055 resetDirty(lastPos);
1056 screenFields.getCurrentField().getKeyPos(lastPos);
1057 shiftLeft(screenFields.getCurrentFieldPos());
1058 screenFields.setCurrentFieldMDT();
1059 updateDirty();
1060 simulated = true;
1061 }
1062 else {
1063 displayError(ERR_CURSOR_PROTECTED);
1064 }
1065
1066 break;
1067
1068 case TAB:
1069 if (screenFields.getCurrentField() != null
1070 && !screenFields.isCurrentFieldContinued()) {
1071 if (screenFields.isCurrentFieldHighlightedEntry()) {
1072 resetDirty(screenFields.getCurrentField().startPos);
1073 gotoFieldNext();
1074 updateDirty();
1075 }
1076 else
1077 gotoFieldNext();
1078 }
1079 else {
1080 do {
1081 gotoFieldNext();
1082 }
1083 while (screenFields.getCurrentField() != null
1084 && (screenFields.isCurrentFieldContinuedMiddle() || screenFields
1085 .isCurrentFieldContinuedLast()));
1086 }
1087
1088 isInField();
1089 simulated = true;
1090 break;
1091
1092 case EOF:
1093 if (screenFields.getCurrentField() != null
1094 && screenFields.withinCurrentField(lastPos)
1095 && !screenFields.isCurrentFieldBypassField()) {
1096 int where = endOfField(screenFields.getCurrentField()
1097 .startPos(), true);
1098
1099 if (where > 0) {
1100 setCursor((where / numCols) + 1, (where % numCols) + 1);
1101 }
1102
1103 simulated = true;
1104 }
1105 else {
1106 displayError(ERR_CURSOR_PROTECTED);
1107 }
1108
1109 resetDirty(lastPos);
1110 break;
1111
1112 case ERASE_EOF:
1113 if (screenFields.getCurrentField() != null
1114 && screenFields.withinCurrentField(lastPos)
1115 && !screenFields.isCurrentFieldBypassField()) {
1116 int where = lastPos;
1117 resetDirty(lastPos);
1118
1119 if (fieldExit()) {
1120 screenFields.setCurrentFieldMDT();
1121
1122 if (!screenFields.isCurrentFieldContinued()) {
1123 gotoFieldNext();
1124 }
1125 else {
1126 do {
1127 gotoFieldNext();
1128
1129 if (screenFields.isCurrentFieldContinued())
1130 fieldExit();
1131 }
1132 while (screenFields.isCurrentFieldContinuedMiddle()
1133 || screenFields.isCurrentFieldContinuedLast());
1134 }
1135 }
1136
1137 updateDirty();
1138 goto_XY(where);
1139 simulated = true;
1140 }
1141 else {
1142 displayError(ERR_CURSOR_PROTECTED);
1143 }
1144
1145 break;
1146
1147 case ERASE_FIELD:
1148 if (screenFields.getCurrentField() != null
1149 && screenFields.withinCurrentField(lastPos)
1150 && !screenFields.isCurrentFieldBypassField()) {
1151 int where = lastPos;
1152 lastPos = screenFields.getCurrentField().startPos();
1153 resetDirty(lastPos);
1154
1155 if (fieldExit()) {
1156 screenFields.setCurrentFieldMDT();
1157
1158 if (!screenFields.isCurrentFieldContinued()) {
1159 gotoFieldNext();
1160 }
1161 else {
1162 do {
1163 gotoFieldNext();
1164
1165 if (screenFields.isCurrentFieldContinued())
1166 fieldExit();
1167 }
1168 while (screenFields.isCurrentFieldContinuedMiddle()
1169 || screenFields.isCurrentFieldContinuedLast());
1170 }
1171 }
1172
1173 updateDirty();
1174 goto_XY(where);
1175 simulated = true;
1176 }
1177 else {
1178 displayError(ERR_CURSOR_PROTECTED);
1179 }
1180
1181 break;
1182
1183 case INSERT:
1184 // we toggle it
1185 oia.setInsertMode(oia.isInsertMode() ? false : true);
1186 break;
1187
1188 case HOME:
1189
1190 // position to the home position set
1191 if (lastPos + numCols + 1 != homePos) {
1192 goto_XY(homePos - numCols - 1);
1193 isInField();
1194 }
1195 else
1196 gotoField(1);
1197
1198 break;
1199
1200 case KEYPAD_0:
1201 simulated = simulateKeyStroke('0');
1202 break;
1203
1204 case KEYPAD_1:
1205 simulated = simulateKeyStroke('1');
1206 break;
1207
1208 case KEYPAD_2:
1209 simulated = simulateKeyStroke('2');
1210 break;
1211
1212 case KEYPAD_3:
1213 simulated = simulateKeyStroke('3');
1214 break;
1215
1216 case KEYPAD_4:
1217 simulated = simulateKeyStroke('4');
1218 break;
1219
1220 case KEYPAD_5:
1221 simulated = simulateKeyStroke('5');
1222 break;
1223
1224 case KEYPAD_6:
1225 simulated = simulateKeyStroke('6');
1226 break;
1227
1228 case KEYPAD_7:
1229 simulated = simulateKeyStroke('7');
1230 break;
1231
1232 case KEYPAD_8:
1233 simulated = simulateKeyStroke('8');
1234 break;
1235
1236 case KEYPAD_9:
1237 simulated = simulateKeyStroke('9');
1238 break;
1239
1240 case KEYPAD_PERIOD:
1241 simulated = simulateKeyStroke('.');
1242 break;
1243
1244 case KEYPAD_COMMA:
1245 simulated = simulateKeyStroke(',');
1246 break;
1247
1248 case KEYPAD_MINUS:
1249 if (screenFields.getCurrentField() != null
1250 && screenFields.withinCurrentField(lastPos)
1251 && !screenFields.isCurrentFieldBypassField()) {
1252 int s = screenFields.getCurrentField().getFieldShift();
1253
1254 if (s == 3 || s == 5 || s == 7) {
1255 planes.setChar(lastPos, '-');
1256 resetDirty(lastPos);
1257 advancePos();
1258
1259 if (fieldExit()) {
1260 screenFields.setCurrentFieldMDT();
1261
1262 if (!screenFields.isCurrentFieldContinued()) {
1263 gotoFieldNext();
1264 }
1265 else {
1266 do {
1267 gotoFieldNext();
1268 }
1269 while (screenFields
1270 .isCurrentFieldContinuedMiddle()
1271 || screenFields
1272 .isCurrentFieldContinuedLast());
1273 }
1274
1275 simulated = true;
1276 updateDirty();
1277
1278 if (screenFields.isCurrentFieldAutoEnter())
1279 sendAid(AID_ENTER);
1280 }
1281 }
1282 else {
1283 displayError(ERR_FIELD_MINUS);
1284 }
1285 }
1286 else {
1287 displayError(ERR_CURSOR_PROTECTED);
1288 }
1289
1290 break;
1291
1292 case FIELD_EXIT:
1293 if (screenFields.getCurrentField() != null
1294 && screenFields.withinCurrentField(lastPos)
1295 && !screenFields.isCurrentFieldBypassField()) {
1296 resetDirty(lastPos);
1297 boolean autoFE = screenFields.isCurrentFieldAutoEnter();
1298
1299 if (fieldExit()) {
1300 screenFields.setCurrentFieldMDT();
1301
1302 if (!screenFields.isCurrentFieldContinued() &&
1303 !screenFields.isCurrentFieldAutoEnter()) {
1304 gotoFieldNext();
1305 }
1306 else {
1307 do {
1308 gotoFieldNext();
1309
1310 if (screenFields.isCurrentFieldContinued())
1311 fieldExit();
1312 }
1313 while (screenFields.isCurrentFieldContinuedMiddle()
1314 || screenFields.isCurrentFieldContinuedLast());
1315 }
1316 }
1317
1318 updateDirty();
1319 simulated = true;
1320
1321 if (autoFE)
1322 sendAid(AID_ENTER);
1323 }
1324 else {
1325 displayError(ERR_CURSOR_PROTECTED);
1326 }
1327
1328 break;
1329
1330 case FIELD_PLUS:
1331 if (screenFields.getCurrentField() != null
1332 && screenFields.withinCurrentField(lastPos)
1333 && !screenFields.isCurrentFieldBypassField()) {
1334 resetDirty(lastPos);
1335 boolean autoFE = screenFields.isCurrentFieldAutoEnter();
1336
1337 if (fieldExit()) {
1338 screenFields.setCurrentFieldMDT();
1339
1340 if (!screenFields.isCurrentFieldContinued() &&
1341 !screenFields.isCurrentFieldAutoEnter()) {
1342 gotoFieldNext();
1343 }
1344 else {
1345 do {
1346 gotoFieldNext();
1347 }
1348 while (screenFields.isCurrentFieldContinuedMiddle()
1349 || screenFields.isCurrentFieldContinuedLast());
1350 }
1351 }
1352
1353 updateDirty();
1354 simulated = true;
1355
1356 if (autoFE)
1357 sendAid(AID_ENTER);
1358 }
1359 else {
1360 displayError(ERR_CURSOR_PROTECTED);
1361 }
1362
1363 break;
1364
1365 case FIELD_MINUS:
1366 if (screenFields.getCurrentField() != null
1367 && screenFields.withinCurrentField(lastPos)
1368 && !screenFields.isCurrentFieldBypassField()) {
1369 int s = screenFields.getCurrentField().getFieldShift();
1370
1371 if (s == 3 || s == 5 || s == 7) {
1372 planes.setChar(lastPos, '-');
1373 resetDirty(lastPos);
1374 advancePos();
1375 boolean autoFE = screenFields.isCurrentFieldAutoEnter();
1376
1377 if (fieldExit()) {
1378 screenFields.setCurrentFieldMDT();
1379
1380 if (!screenFields.isCurrentFieldContinued()
1381 && !screenFields.isCurrentFieldAutoEnter()) {
1382 gotoFieldNext();
1383 }
1384 else {
1385 do {
1386 gotoFieldNext();
1387 }
1388 while (screenFields.isCurrentFieldContinuedMiddle()
1389 || screenFields.isCurrentFieldContinuedLast());
1390 }
1391 }
1392
1393 updateDirty();
1394 simulated = true;
1395
1396 if (autoFE)
1397 sendAid(AID_ENTER);
1398 }
1399 else {
1400 displayError(ERR_FIELD_MINUS);
1401 }
1402 }
1403 else {
1404 displayError(ERR_CURSOR_PROTECTED);
1405 }
1406
1407 break;
1408
1409 case BOF:
1410 if (screenFields.getCurrentField() != null
1411 && screenFields.withinCurrentField(lastPos)
1412 && !screenFields.isCurrentFieldBypassField()) {
1413 int where = screenFields.getCurrentField().startPos();
1414
1415 if (where > 0) {
1416 goto_XY(where);
1417 }
1418
1419 simulated = true;
1420 }
1421 else {
1422 displayError(ERR_CURSOR_PROTECTED);
1423 }
1424
1425 resetDirty(lastPos);
1426 break;
1427
1428 case SYSREQ:
1429 sessionVT.systemRequest();
1430 simulated = true;
1431 break;
1432
1433 case RESET:
1434 if (isStatusErrorCode()) {
1435 resetError();
1436 isInField();
1437 updateDirty();
1438 }
1439 else {
1440 setPrehelpState(false, oia.isKeyBoardLocked(), false);
1441 }
1442
1443 simulated = true;
1444 break;
1445
1446 case ATTN:
1447 sessionVT.sendAttentionKey();
1448 simulated = true;
1449 break;
1450
1451 case DUP_FIELD:
1452 if (screenFields.getCurrentField() != null
1453 && screenFields.withinCurrentField(lastPos)
1454 && !screenFields.isCurrentFieldBypassField()) {
1455 if (screenFields.isCurrentFieldDupEnabled()) {
1456 resetDirty(lastPos);
1457 screenFields.getCurrentField().setFieldChar(lastPos,
1458 (char) 0x1C);
1459 screenFields.setCurrentFieldMDT();
1460 gotoFieldNext();
1461 updateDirty();
1462 simulated = true;
1463 }
1464 else {
1465 displayError(ERR_DUP_KEY_NOT_ALLOWED);
1466 }
1467 }
1468 else {
1469 displayError(ERR_CURSOR_PROTECTED);
1470 }
1471
1472 break;
1473
1474 case NEW_LINE:
1475 if (screenFields.getSize() > 0) {
1476 int startRow = getRow(lastPos) + 1;
1477 int startPos = lastPos;
1478
1479 if (startRow == getRows())
1480 startRow = 0;
1481
1482 setCursor(++startRow, 1);
1483
1484 if (!isInField() && screenFields.getCurrentField() != null
1485 && !screenFields.isCurrentFieldBypassField()) {
1486 while (!isInField()
1487 && screenFields.getCurrentField() != null
1488 && !screenFields.isCurrentFieldBypassField()) {
1489 // lets keep going
1490 advancePos();
1491
1492 // Have we looped the screen?
1493 if (lastPos == startPos) {
1494 // if so then go back to starting point
1495 goto_XY(startPos);
1496 break;
1497 }
1498 }
1499 }
1500 }
1501
1502 simulated = true;
1503 break;
1504
1505 case FAST_CURSOR_DOWN:
1506 int rowNow = (getCurrentRow() - 1) + 3;
1507
1508 if (rowNow > getRows() - 1)
1509 rowNow = rowNow - getRows();
1510
1511 this.goto_XY(getPos(rowNow, getCurrentCol() - 1));
1512 simulated = true;
1513 break;
1514
1515 case FAST_CURSOR_UP:
1516 rowNow = (getCurrentRow() - 1) - 3;
1517
1518 if (rowNow < 0)
1519 rowNow = (getRows()) + rowNow;
1520
1521 this.goto_XY(getPos(rowNow, getCurrentCol() - 1));
1522 simulated = true;
1523 break;
1524
1525 case FAST_CURSOR_LEFT:
1526 int colNow = (getCurrentCol() - 1) - 3;
1527 rowNow = getCurrentRow() - 1;
1528
1529 if (colNow <= 0) {
1530 colNow = getColumns() + colNow;
1531 rowNow--;
1532 }
1533
1534 if (rowNow < 0)
1535 rowNow = getRows() - 1;
1536
1537 process_XY(getPos(rowNow, colNow));
1538 simulated = true;
1539 break;
1540
1541 case FAST_CURSOR_RIGHT:
1542 colNow = (getCurrentCol() - 1) + 3;
1543 rowNow = getCurrentRow() - 1;
1544
1545 if (colNow >= getColumns()) {
1546 colNow = colNow - getColumns();
1547 rowNow++;
1548 }
1549
1550 if (rowNow > getRows() - 1)
1551 rowNow = getRows() - rowNow;
1552
1553 process_XY(getPos(rowNow, colNow));
1554 simulated = true;
1555 break;
1556
1557 default:
1558 Log.i(TAG, " Mnemonic not supported " + mnem);
1559 break;
1560 }
1561
1562 return simulated;
1563 }
1564
1565 protected boolean simulateKeyStroke(char c) {
1566 if (isStatusErrorCode() && !Character.isISOControl(c) && !keyProcessed) {
1567 if (resetRequired) return false;
1568
1569 resetError();
1570 }
1571
1572 boolean updateField = false;
1573 boolean numericError = false;
1574 boolean updatePos = false;
1575 boolean autoEnter = false;
1576
1577 if (!Character.isISOControl(c)) {
1578 if (screenFields.getCurrentField() != null
1579 && screenFields.withinCurrentField(lastPos)
1580 && !screenFields.isCurrentFieldBypassField()) {
1581 if (screenFields.isCurrentFieldFER()
1582 && !screenFields.withinCurrentField(screenFields
1583 .getCurrentFieldPos())
1584 && lastPos == screenFields.getCurrentField().endPos()
1585 && screenFields.getCurrentFieldPos() > screenFields
1586 .getCurrentField().endPos()) {
1587 displayError(ERR_FIELD_EXIT_INVALID);
1588 feError = true;
1589 return false;
1590 }
1591
1592 switch (screenFields.getCurrentFieldShift()) {
1593 case 0: // Alpha shift
1594 case 2: // Numeric Shift
1595 case 4: // Kakana Shift
1596 updateField = true;
1597 break;
1598
1599 case 1: // Alpha Only
1600 if (Character.isLetter(c) || c == ',' || c == '-'
1601 || c == '.' || c == ' ')
1602 updateField = true;
1603
1604 break;
1605
1606 case 3: // Numeric only
1607 if (Character.isDigit(c) || c == '+' || c == ','
1608 || c == '-' || c == '.' || c == ' ')
1609 updateField = true;
1610 else
1611 numericError = true;
1612
1613 break;
1614
1615 case 5: // Digits only
1616 if (Character.isDigit(c))
1617 updateField = true;
1618 else
1619 displayError(ERR_NUMERIC_09);
1620
1621 break;
1622
1623 case 7: // Signed numeric
1624 if (Character.isDigit(c) || c == '+' || c == '-')
1625 if (lastPos == screenFields.getCurrentField().endPos()
1626 && (c != '+' && c != '-'))
1627 displayError(ERR_INVALID_SIGN);
1628 else
1629 updateField = true;
1630 else
1631 displayError(ERR_NUMERIC_09);
1632
1633 break;
1634 }
1635
1636 if (updateField) {
1637 if (screenFields.isCurrentFieldToUpper())
1638 c = Character.toUpperCase(c);
1639
1640 updatePos = true;
1641 resetDirty(lastPos);
1642
1643 if (oia.isInsertMode()) {
1644 if (endOfField(false) != screenFields.getCurrentField()
1645 .endPos())
1646 shiftRight(lastPos);
1647 else {
1648 displayError(ERR_NO_ROOM_INSERT);
1649 updatePos = false;
1650 }
1651 }
1652
1653 if (updatePos) {
1654 screenFields.getCurrentField().getKeyPos(
1655 getRow(lastPos), getCol(lastPos));
1656 screenFields.getCurrentField().changePos(1);
1657 planes.setChar(lastPos, c);
1658 screenFields.setCurrentFieldMDT();
1659
1660 // if we have gone passed the end of the field then goto
1661 // the next field
1662 if (!screenFields.withinCurrentField(screenFields
1663 .getCurrentFieldPos())) {
1664 if (screenFields.isCurrentFieldAutoEnter()) {
1665 autoEnter = true;
1666 }
1667 else if (!screenFields.isCurrentFieldFER())
1668 gotoFieldNext();
1669 else {
1670 // screenFields.getCurrentField().changePos(1);
1671 //
1672 // if (screenFields.
1673 // cursorPos == endPos)
1674 // System.out.println("end of field");
1675 //
1676 // feError != feError;
1677 // if (feError)
1678 // displayError(ERR_FIELD_EXIT_INVALID);
1679 }
1680 }
1681 else
1682 setCursor(screenFields.getCurrentField()
1683 .getCursorRow() + 1, screenFields
1684 .getCurrentField().getCursorCol() + 1);
1685 }
1686
1687 fireScreenChanged();
1688
1689 if (autoEnter)
1690 sendAid(AID_ENTER);
1691 }
1692 else {
1693 if (numericError) {
1694 displayError(ERR_NUMERIC_ONLY);
1695 }
1696 }
1697 }
1698 else {
1699 displayError(ERR_CURSOR_PROTECTED);
1700 }
1701 }
1702
1703 return updatePos;
1704 }
1705
1706 /**
1707 * Method: endOfField
1708 * <p>
1709 *
1710 * convenience method that call endOfField with lastRow lastCol and passes
1711 * the posSpace to that method
1712 *
1713 * @param posSpace
1714 * value of type boolean - specifying to return the position of
1715 * the the last space or not
1716 * @return a value of type int - the screen postion (row * columns) + col
1717 *
1718 */
1719 private int endOfField(boolean posSpace) {
1720 return endOfField(lastPos, posSpace);
1721 }
1722
1723 /**
1724 * Method: endOfField
1725 * <p>
1726 *
1727 * gets the position of the last character of the current field posSpace
1728 * parameter tells the routine whether to return the position of the last
1729 * space ( <= ' ') or the last non space posSpace == true last occurrence of
1730 * char <= ' ' posSpace == false last occurrence of char > ' '
1731 *
1732 * @param pos
1733 * value of type int - position to start from
1734 * @param posSpace
1735 * value of type boolean - specifying to return the position of
1736 * the the last space or not
1737 * @return a value of type int - the screen postion (row * columns) + col
1738 *
1739 */
1740 private int endOfField(int pos, boolean posSpace) {
1741 int endPos = screenFields.getCurrentField().endPos();
1742 int fePos = endPos;
1743 // get the number of characters to the right
1744 int count = endPos - pos;
1745
1746 // first lets get the real ending point without spaces and the such
1747 while (planes.getChar(endPos) <= ' ' && count-- > 0) {
1748 endPos--;
1749 }
1750
1751 if (endPos == fePos) {
1752 return endPos;
1753 }
1754
1755 screenFields.getCurrentField().getKeyPos(endPos);
1756
1757 if (posSpace) screenFields.getCurrentField().changePos(+1);
1758
1759 return screenFields.getCurrentFieldPos();
1760 }
1761
1762 private boolean fieldExit() {
1763 int pos = lastPos;
1764 boolean mdt = false;
1765 int end = endOfField(false); // get the ending position of the first
1766 // non blank character in field
1767 ScreenField sf = screenFields.getCurrentField();
1768
1769 if (sf.isMandatoryEnter() && end == sf.startPos()) {
1770 displayError(ERR_MANDATORY_ENTER);
1771 return false;
1772 }
1773
1774 // save off the current pos of the field for checking field exit required
1775 // positioning. the getKeyPos resets this information so it is useless
1776 // for comparing if we are positioned passed the end of field.
1777 // Maybe this should be changed to not update the current cursor position
1778 // of the field.
1779 int currentPos = sf.getCurrentPos();
1780 // get the number of characters to the right
1781 int count = (end - sf.startPos()) - sf.getKeyPos(pos);
1782
1783 if (count == 0 && sf.isFER()) {
1784 if (currentPos > sf.endPos()) {
1785 mdt = true;
1786 return mdt;
1787 }
1788 }
1789
1790 for (; count >= 0; count--) {
1791 planes.setChar(pos, initChar);
1792 setDirty(pos);
1793 pos++;
1794 mdt = true;
1795 }
1796
1797 // This checks for a field minus because a field minus places
1798 // a negative sign and then advances a position. If it is the
1799 // end of the field where the minus is placed then this offset will
1800 // place the count as -1.
1801 if (count == -1) {
1802 int s = sf.getFieldShift();
1803
1804 if (s == 3 || s == 5 || s == 7) {
1805 mdt = true;
1806 }
1807 }
1808
1809 int adj = sf.getAdjustment();
1810
1811 if (adj != 0) {
1812 switch (adj) {
1813 case 5:
1814 rightAdjustField('0');
1815 sf.setRightAdjusted();
1816 break;
1817
1818 case 6:
1819 rightAdjustField(' ');
1820 sf.setRightAdjusted();
1821 break;
1822
1823 case 7:
1824 sf.setMandatoryEntered();
1825 break;
1826 }
1827 }
1828 else {
1829 // we need to right adjust signed numeric fields as well.
1830 if (sf.isSignedNumeric()) {
1831 rightAdjustField(' ');
1832 }
1833 }
1834
1835 return mdt;
1836 }
1837
1838 private void rightAdjustField(char fill) {
1839 int end = endOfField(false); // get the ending position of the first
1840 // non blank character in field
1841 // get the number of characters to the right
1842 int count = screenFields.getCurrentField().endPos() - end;
1843
1844 // subtract 1 from count for signed numeric - note for later
1845 if (screenFields.getCurrentField().isSignedNumeric()) {
1846 if (planes.getChar(end - 1) != '-')
1847 count--;
1848 }
1849
1850 int pos = screenFields.getCurrentField().startPos();
1851
1852 while (count-- >= 0) {
1853 shiftRight(pos);
1854 planes.setChar(pos, fill);
1855 setDirty(pos);
1856 }
1857 }
1858
1859 private void shiftLeft(int sPos) {
1860 int endPos = 0;
1861 int pos = sPos;
1862 int pPos = sPos;
1863 ScreenField sf = screenFields.getCurrentField();
1864 int end;
1865 int count;
1866
1867 do {
1868 end = endOfField(pPos, false); // get the ending position of the
1869 // first
1870 // non blank character in field
1871 count = (end - screenFields.getCurrentField().startPos())
1872 - screenFields.getCurrentField().getKeyPos(pPos);
1873
1874 // now we loop through and shift the remaining characters to the
1875 // left
1876 while (count-- > 0) {
1877 pos++;
1878 planes.setChar(pPos, planes.getChar(pos));
1879 setDirty(pPos);
1880 pPos = pos;
1881 }
1882
1883 if (screenFields.isCurrentFieldContinued()) {
1884 gotoFieldNext();
1885
1886 if (screenFields.getCurrentField().isContinuedFirst())
1887 break;
1888
1889 pos = screenFields.getCurrentField().startPos();
1890 planes.setChar(pPos, planes.getChar(pos));
1891 setDirty(pPos);
1892 pPos = pos;
1893 }
1894 }
1895 while (screenFields.isCurrentFieldContinued()
1896 && !screenFields.getCurrentField().isContinuedFirst());
1897
1898 if (end >= 0 && count >= -1) {
1899 endPos = end;
1900 }
1901 else {
1902 endPos = sPos;
1903 }
1904
1905 screenFields.setCurrentField(sf);
1906 planes.setChar(endPos, initChar);
1907 setDirty(endPos);
1908 goto_XY(screenFields.getCurrentFieldPos());
1909 sf = null;
1910 }
1911
1912 private void shiftRight(int sPos) {
1913 int end = endOfField(true); // get the ending position of the first
1914 // non blank character in field
1915 int pos = end;
1916 int pPos = end;
1917 int count = end - sPos;
1918
1919 // now we loop through and shift the remaining characters to the right
1920 while (count-- > 0) {
1921 pos--;
1922 planes.setChar(pPos, planes.getChar(pos));
1923 setDirty(pPos);
1924 pPos = pos;
1925 }
1926 }
1927
1928 public int getRow(int pos) {
1929 // if (pos == 0)
1930 // return 1;
1931 int row = pos / numCols;
1932
1933 if (row < 0) {
1934 row = lastPos / numCols;
1935 }
1936
1937 if (row > (lenScreen / numCols) - 1)
1938 row = (lenScreen / numCols) - 1;
1939
1940 return row;
1941 }
1942
1943 public int getCol(int pos) {
1944 int col = pos % (getColumns());
1945
1946 if (col > 0) return col;
1947
1948 return 0;
1949 }
1950
1951 /**
1952 * This routine is 0 based offset. So to get row 20,1 then pass row 19,0
1953 *
1954 * @param row
1955 * @param col
1956 * @return
1957 */
1958 public int getPos(int row, int col) {
1959 return (row * numCols) + col;
1960 }
1961
1962 /**
1963 * Current position is based on offsets of 1,1 not 0,0 of the current
1964 * position of the screen
1965 *
1966 * @return int
1967 */
1968 public int getCurrentPos() {
1969 // return lastPos + numCols + 1;
1970 return lastPos + 1;
1971 }
1972
1973 /**
1974 * I got this information from a tcp trace of each error. I could not find
1975 * any documenation for this. Maybe there is but I could not find it. If
1976 * anybody finds this documention could you please send me a copy. Please
1977 * note that I did not look that hard either.
1978 * <p>
1979 * 0000: 00 50 73 1D 89 81 00 50 DA 44 C8 45 08 00 45 00 .Ps....P.D.E..E.
1980 * </p>
1981 * <p>
1982 * 0010: 00 36 E9 1C 40 00 80 06 9B F9 C1 A8 33 58 C0 A8 .6..@...k....3X..
1983 * </p>
1984 * <p>
1985 * 0020: C0 02 06 0E 00 17 00 52 6E 88 73 40 DE CB 50 18 .......Rn.s@..P.
1986 * </p>
1987 * <p>
1988 * 0030: 20 12 3C 53 00 00 00 0C 12 A0 00 00 04 01 00 00 . <S............
1989 * </p>
1990 * <p>
1991 * 0040: 00 05 FF EF .... ----------|| The 00 XX is the code to be sent. I
1992 * found the following <table BORDER COLS=2 WIDTH="50%" >
1993 * <tr>
1994 * <td>ERR_CURSOR_PROTECTED</td>
1995 * <td>0x05</td>
1996 * </tr>
1997 * <tr>
1998 * <td>ERR_INVALID_SIGN</td>
1999 * <td>0x11</td>
2000 * </tr>
2001 * <tr>
2002 * <td>ERR_NO_ROOM_INSERT</td>
2003 * <td>0x12</td>
2004 * </tr>
2005 * <tr>
2006 * <td>ERR_NUMERIC_ONLY</td>
2007 * <td>0x09</td>
2008 * </tr>
2009 * <tr>
2010 * <td>ERR_NUMERIC_09</td>
2011 * <td>0x10</td>
2012 * </tr>
2013 * <tr>
2014 * <td>ERR_FIELD_MINUS</td>
2015 * <td>0x16</td>
2016 * </tr>
2017 * <tr>
2018 * <td>ERR_ENTER_NOT_ALLOWED</td>
2019 * <td>0x20</td>
2020 * </tr>
2021 * <tr>
2022 * <td>ERR_MANDATORY_ENTER</td>
2023 * <td>0x21</td>
2024 * </tr>
2025 * <tr>
2026 * <td>ERR_ENTER_NOT_ALLOWED</td>
2027 * <td>0x20</td>
2028 * </tr>
2029 * </table> I am tired of typing and they should be self explanitory. Finding
2030 * them in the first place was the pain.
2031 * </p>
2032 *
2033 * @param ec error code
2034 */
2035 private void displayError(int ec) {
2036 saveHomePos = homePos;
2037 homePos = lastPos + numCols + 1;
2038 pendingInsert = true;
2039 sessionVT.sendNegResponse2(ec);
2040 }
2041
2042 private void process_XY(int pos) {
2043 if (pos < 0)
2044 pos = lenScreen + pos;
2045
2046 if (pos > lenScreen - 1)
2047 pos = pos - lenScreen;
2048
2049 // if there was a field exit error then we need to treat the movement
2050 // of the cursor in a special way that equals that of Client Access.
2051 // If the cursor is moved from the field then we need to reset the
2052 // position within the field so that the last character can be typed
2053 // over again instead of sending the field exit error again.
2054 // We also need to reset the field exit error flag.
2055 //
2056 // How we know we have a field exit error is when the field position is
2057 // set beyond the end of the field and a character is then typed we can
2058 // not position that character. To reset this we need to set the next
2059 // position of the field to not be beyond the end of field but to the
2060 // last character.
2061 //
2062 // Now to make it work like Client Access if the cursor is a back space
2063 // then do not move the cursor but place it on the last field. All
2064 // other keys will reset the field position so that entering over the
2065 // last character will not cause an error but replace that character or
2066 // just plain move the cursor if the key was to do that.
2067 ScreenField sf = screenFields.getCurrentField();
2068
2069 if (feError) {
2070 feError = false;
2071 sf.changePos(-1);
2072 }
2073 else {
2074 if (sf != null && sf.isFER()) {
2075 if ((sf.getCurrentPos()
2076 > sf.endPos())) {
2077 if (sf.withinField(pos)) {
2078 sf.getKeyPos(pos);
2079 return;
2080 }
2081
2082 sf.getKeyPos(sf.endPos());
2083 }
2084 }
2085
2086 goto_XY(pos);
2087 }
2088 }
2089
2090 public boolean isUsingGuiInterface() {
2091 return guiInterface;
2092 }
2093
2094 /**
2095 * Convinience class to return if the cursor is in a field or not.
2096 *
2097 * @return true or false
2098 */
2099
2100 protected boolean isInField() {
2101 return isInField(lastPos, true);
2102 }
2103
2104 /**
2105 *
2106 * Convinience class to return if the position that is passed is in a field
2107 * or not. If it is then the chgToField parameter will change the current
2108 * field to this field where the position indicates
2109 *
2110 * @param pos
2111 * @param chgToField
2112 * @return true or false
2113 */
2114 public boolean isInField(int pos, boolean chgToField) {
2115 return screenFields.isInField(pos, chgToField);
2116 }
2117
2118 /**
2119 *
2120 * Convinience class to return if the position that is passed is in a field
2121 * or not. If it is then the field at this position becomes the current
2122 * working field
2123 *
2124 * @param pos
2125 * @return true or false
2126 */
2127 public boolean isInField(int pos) {
2128 return screenFields.isInField(pos, true);
2129 }
2130
2131 /**
2132 * Convinience class to return if the position at row and column that is
2133 * passed is in a field or not. If it is then the field at this position
2134 * becomes the current working field.
2135 *
2136 * @param row
2137 * @param col
2138 * @return true or false
2139 */
2140 public boolean isInField(int row, int col) {
2141 return isInField(row, col, true);
2142 }
2143
2144 /**
2145 *
2146 * Convinience class to return if the position at row and column that is
2147 * passed is in a field or not. If it is then the chgToField parameter will
2148 * change the current field to this field where the row and column
2149 * indicates.
2150 *
2151 * @param row
2152 * @param col
2153 * @param chgToField
2154 * @return true or false
2155 */
2156 public boolean isInField(int row, int col, boolean chgToField) {
2157 return screenFields.isInField((row * numCols) + col, chgToField);
2158 }
2159
2160 /**
2161 * Gets the length of the screen - number of rows times number of columns
2162 *
2163 * @return int value of screen length
2164 */
2165 public int getScreenLength() {
2166 return lenScreen;
2167 }
2168
2169 /**
2170 * Get the number or rows available.
2171 *
2172 * @return number of rows
2173 */
2174 public int getRows() {
2175 return numRows;
2176 }
2177
2178 /**
2179 * Get the number of columns available.
2180 *
2181 * @return number of columns
2182 */
2183 public int getColumns() {
2184 return numCols;
2185 }
2186
2187 /**
2188 * Get the current row where the cursor is
2189 *
2190 * @return the cursor current row position 1,1 based
2191 */
2192 public int getCurrentRow() {
2193 return (lastPos / numCols) + 1;
2194 }
2195
2196 /**
2197 * Get the current column where the cursor is
2198 *
2199 * @return the cursor current column position 1,1 based
2200 */
2201 public int getCurrentCol() {
2202 return (lastPos % numCols) + 1;
2203 }
2204
2205 /**
2206 * The last position of the cursor on the screen - Note - position is based
2207 * 0,0
2208 *
2209 * @return last position
2210 */
2211 protected int getLastPos() {
2212 return lastPos;
2213 }
2214
2215 /**
2216 * Hotspot More... string
2217 *
2218 * @return string literal of More...
2219 */
2220 public StringBuffer getHSMore() {
2221 return hsMore;
2222 }
2223
2224 /**
2225 * Hotspot Bottom string
2226 *
2227 * @return string literal of Bottom
2228 */
2229 public StringBuffer getHSBottom() {
2230 return hsBottom;
2231 }
2232
2233 /**
2234 *
2235 * Return the screen represented as a character array
2236 *
2237 * @return character array containing the text
2238 */
2239 public char[] getScreenAsChars() {
2240 char[] sac = new char[lenScreen];
2241 char c;
2242
2243 for (int x = 0; x < lenScreen; x++) {
2244 c = planes.getChar(x);
2245
2246 // only draw printable characters (in this case >= ' ')
2247 if ((c >= ' ') && (!planes.isAttributePlace(x))) {
2248 sac[x] = c;
2249 // TODO: implement the underline check here
2250 // if (screen[x].underLine && c <= ' ')
2251 // sac[x] = '_';
2252 }
2253 else
2254 sac[x] = ' ';
2255 }
2256
2257 return sac;
2258 }
2259
2260 public char[] getData(int startRow, int startCol, int endRow, int endCol, int plane) {
2261 try {
2262 int from = getPos(startRow, startCol);
2263 int to = getPos(endRow, endCol);
2264
2265 if (from > to) {
2266 int f = from;
2267 to = f;
2268 from = f;
2269 }
2270
2271 return planes.getPlaneData(from, to, plane);
2272 }
2273 catch (Exception oe) {
2274 return null;
2275 }
2276 }
2277
2278 /**
2279 * <p>
2280 * GetScreen retrieves the various planes associated with the presentation
2281 * space. The data is returned as a linear array of character values in the
2282 * array provided. The array is not terminated by a null character except
2283 * when data is retrieved from the text plane, in which case a single null
2284 * character is appended.
2285 * </p>
2286 * <p>
2287 * The application must supply a buffer for the returned data and the length
2288 * of the buffer. Data is returned starting from the beginning of the
2289 * presentation space and continuing until the buffer is full or the entire
2290 * plane has been copied. For text plane data, the buffer must include one
2291 * extra position for the terminating null character.
2292 * <p>
2293 *
2294 * @param buffer
2295 * @param bufferLength
2296 * @param plane
2297 * @return The number of characters copied to the buffer
2298 * @throws OhioException
2299 */
2300
2301 public synchronized int GetScreen(char buffer[], int bufferLength, int plane)
2302 // throws OhioException {
2303 {
2304 return GetScreen(buffer, bufferLength, 0, lenScreen, plane);
2305 }
2306
2307 /**
2308 * <p>
2309 * GetScreen retrieves the various planes associated with the presentation
2310 * space. The data is returned as a linear array of character values in the
2311 * array provided. The array is not terminated by a null character except
2312 * when data is retrieved from the text plane, in which case a single null
2313 * character is appended.
2314 * </p>
2315 * <p>
2316 * The application must supply a buffer for the returned data and the length
2317 * of the buffer. Data is returned starting from the given position and
2318 * continuing until the specified number of characters have been copied, the
2319 * buffer is full or the entire plane has been copied. For text plane data,
2320 * the buffer must include one extra position for the terminating null character.
2321 * </p>
2322 *
2323 * @param buffer
2324 * @param bufferLength
2325 * @param from
2326 * @param length
2327 * @param plane
2328 * @return The number of characters copied to the buffer
2329 * @throws OhioException
2330 */
2331
2332 public synchronized int GetScreen(char buffer[], int bufferLength, int from,
2333 int length, int plane)
2334 // throws OhioException {
2335 {
2336 return planes.GetScreen(buffer, bufferLength, from, length, plane);
2337 }
2338
2339 /**
2340 * <p>
2341 * GetScreen retrieves the various planes associated with the presentation
2342 * space. The data is returned as a linear array of character values in the
2343 * array provided. The array is not terminated by a null character except
2344 * when data is retrieved from the text plane, in which case a single null
2345 * character is appended.
2346 * </p>
2347 * <p>
2348 * The application must supply a buffer for the returned data and the length
2349 * of the buffer. Data is returned starting from the given coordinates and
2350 * continuing until the specified number of characters have been copied,
2351 * the buffer is full, or the entire plane has been copied. For text plane
2352 * data, the buffer must include one extra position for the terminating null
2353 * character.
2354 * </p>
2355 *
2356 * @param buffer
2357 * @param bufferLength
2358 * @param row
2359 * @param col
2360 * @param length
2361 * @param plane
2362 * @return The number of characters copied to the buffer.
2363 * @throws OhioException
2364 */
2365
2366 public synchronized int GetScreen(char buffer[], int bufferLength, int row,
2367 int col, int length, int plane)
2368 // throws OhioException {
2369 {
2370 // Call GetScreen function after converting row and column to
2371 // a position.
2372 return planes.GetScreen(buffer, bufferLength, row, col, length, plane);
2373 }
2374
2375 /**
2376 * <p>
2377 * GetScreenRect retrieves data from the various planes associated with the
2378 * presentation space. The data is returned as a linear array of character
2379 * values in the buffer provided.
2380 * </p>
2381 *
2382 * <p>
2383 * The application supplies two positions that represent opposing corners of
2384 * a rectangle within the presentation space. The starting and ending
2385 * positions can have any spatial relationship to each other. The data
2386 * returned starts from the row containing the upper-most point to the row
2387 * containing the lower-most point, and from the left-most column to the
2388 * right-most column.
2389 * </p>
2390 * <p>
2391 * The specified buffer must be at least large enough to contain the number
2392 * of characters in the rectangle. If the buffer is too small, no data is
2393 * copied and zero is returned by the method. Otherwise, the method returns
2394 * the number of characters copied.
2395 * </p>
2396 *
2397 * @param buffer
2398 * @param bufferLength
2399 * @param startPos
2400 * @param endPos
2401 * @param plane
2402 * @return The number of characters copied to the buffer
2403 * @throws OhioException
2404 */
2405
2406 public synchronized int GetScreenRect(char buffer[], int bufferLength,
2407 int startPos, int endPos, int plane)
2408 // throws OhioException {
2409 {
2410 return planes.GetScreenRect(buffer, bufferLength, startPos, endPos, plane);
2411 }
2412
2413 /**
2414 * <p>
2415 * GetScreenRect retrieves data from the various planes associated with the
2416 * presentation space. The data is returned as a linear array of character
2417 * values in the buffer provided. The buffer is not terminated by a null
2418 * character.
2419 * </p>
2420 * <p>
2421 * The application supplies two coordinates that represent opposing corners
2422 * of a rectangle within the presentation space. The starting and ending
2423 * coordinates can have any spatial relationship to each other. The data
2424 * returned starts from the row containing the upper-most point to the row
2425 * containing the lower-most point, and from the left-most column to the
2426 * right-most column.
2427 * </p>
2428 * <p>
2429 * The specified buffer must be at least large enough to contain the number
2430 * of characters in the rectangle. If the buffer is too small, no data is
2431 * copied and zero is returned by the method. Otherwise, the method returns
2432 * the number of characters copied.
2433 * </p>
2434 *
2435 * @param buffer
2436 * @param bufferLength
2437 * @param startRow
2438 * @param startCol
2439 * @param endRow
2440 * @param endCol
2441 * @param plane
2442 * @return The number characters copied to the buffer
2443 * @throws OhioException
2444 */
2445
2446 public synchronized int GetScreenRect(char buffer[], int bufferLength,
2447 int startRow, int startCol,
2448 int endRow, int endCol, int plane)
2449 // throws OhioException {
2450 {
2451 return planes.GetScreenRect(buffer, bufferLength, startRow, startCol, endRow,
2452 endCol, plane);
2453 }
2454
2455 public synchronized boolean[] getActiveAidKeys() {
2456 return sessionVT.getActiveAidKeys();
2457 }
2458
2459 protected synchronized void setScreenData(String text, int location) {
2460 // throws OhioException {
2461 if (location < 0 || location > lenScreen) {
2462 return;
2463 // throw new OhioException(sessionVT.getSessionConfiguration(),
2464 // OhioScreen5250.class.getName(), "osohio.screen.ohio00300", 1);
2465 }
2466
2467 int pos = location;
2468 int l = text.length();
2469 boolean updated = false;
2470 boolean flag = false;
2471 int x = 0;
2472
2473 for (; x < l; x++) {
2474 if (isInField(pos + x, true)) {
2475 if (!screenFields.getCurrentField().isBypassField()) {
2476 if (!flag) {
2477 screenFields.getCurrentField().setMDT();
2478 updated = true;
2479 resetDirty(pos + x);
2480 screenFields.setMasterMDT();
2481 flag = true;
2482 }
2483
2484 planes.screen[pos + x] = text.charAt(x);
2485 setDirty(pos + x);
2486 }
2487 }
2488 }
2489
2490 lastPos = pos + x;
2491
2492 if (updated) {
2493 fireScreenChanged();
2494 }
2495 }
2496
2497 /**
2498 * This routine is based on offset 1,1 not 0,0 it will translate to offset
2499 * 0,0 and call the goto_XY(int pos) it is mostly used from external classes
2500 * that use the 1,1 offset
2501 *
2502 * @param row
2503 * @param col
2504 */
2505 public void setCursor(int row, int col) {
2506 goto_XY(((row - 1) * numCols) + (col - 1));
2507 }
2508
2509 // this routine is based on offset 0,0 not 1,1
2510 protected void goto_XY(int pos) {
2511 lastPos = pos;
2512 updateCursorLoc();
2513 }
2514
2515 /*
2516 * set the content of the field at (l,c) to data
2517 * if l == -1, set the current field contents to data
2518 */
2519 public void setField(int l, int c, char [] data) {
2520 ScreenField cf;
2521
2522 if (l >= 0) {
2523 lastPos = l * numCols + c;
2524
2525 while (!isInField()) advancePos();
2526
2527 setDirty(lastPos);
2528 fireCursorChanged();
2529 }
2530
2531 if ((data != null) && (data.length > 0)) {
2532 cf = screenFields.getCurrentField();
2533 cf.setString(new String(data));
2534 lastPos = cf.getStartPos();
2535 setDirty(lastPos);
2536 setDirty(lastPos + cf.getLength());
2537 lastPos += data.length;
2538
2539 if (!isInField()) {
2540 gotoFieldNext();
2541 isInField();
2542 cf = screenFields.getCurrentField();
2543 lastPos = cf.getStartPos();
2544 }
2545
2546 setDirty(lastPos);
2547 fireCursorChanged();
2548 }
2549
2550 updateDirty();
2551 }
2552
2553 /**
2554 * Set the current working field to the field number specified.
2555 *
2556 * @param f -
2557 * numeric field number on the screen
2558 * @return true or false whether it was sucessful
2559 */
2560 public boolean gotoField(int f) {
2561 int sizeFields = screenFields.getSize();
2562
2563 if (f > sizeFields || f <= 0)
2564 return false;
2565
2566 screenFields.setCurrentField(screenFields.getField(f - 1));
2567
2568 while (screenFields.isCurrentFieldBypassField() && f < sizeFields) {
2569 screenFields.setCurrentField(screenFields.getField(f++));
2570 }
2571
2572 return gotoField(screenFields.getCurrentField());
2573 }
2574
2575 /**
2576 * Convenience method to set the field object passed as the currect working
2577 * screen field
2578 *
2579 * @param f
2580 * @return true or false whether it was sucessful
2581 * @see org.tn5250j.ScreenField
2582 */
2583 protected boolean gotoField(ScreenField f) {
2584 if (f != null) {
2585 goto_XY(f.startPos());
2586 return true;
2587 }
2588
2589 return false;
2590 }
2591
2592 /**
2593 * Convenience class to position the cursor to the next word on the screen
2594 *
2595 */
2596 private void gotoNextWord() {
2597 int pos = lastPos;
2598
2599 if (planes.getChar(lastPos) > ' ') {
2600 advancePos();
2601
2602 // get the next space character
2603 while (planes.getChar(lastPos) > ' ' && pos != lastPos) {
2604 advancePos();
2605 }
2606 }
2607 else
2608 advancePos();
2609
2610 // now that we are positioned on the next space character get the
2611 // next none space character
2612 while (planes.getChar(lastPos) <= ' ' && pos != lastPos) {
2613 advancePos();
2614 }
2615 }
2616
2617 /**
2618 * Convenience class to position the cursor to the previous word on the
2619 * screen
2620 *
2621 */
2622 private void gotoPrevWord() {
2623 int pos = lastPos;
2624 changePos(-1);
2625
2626 // position previous white space character
2627 while (planes.getChar(lastPos) <= ' ') {
2628 changePos(-1);
2629
2630 if (pos == lastPos)
2631 break;
2632 }
2633
2634 changePos(-1);
2635
2636 // get the previous space character
2637 while (planes.getChar(lastPos) > ' ' && pos != lastPos) {
2638 changePos(-1);
2639 }
2640
2641 // and position one position more should give us the beginning of word
2642 advancePos();
2643 }
2644
2645 /**
2646 * Convinience class to position to the next field on the screen.
2647 *
2648 * @see org.tn5250j.ScreenFields
2649 */
2650 private void gotoFieldNext() {
2651 if (screenFields.isCurrentFieldHighlightedEntry())
2652 unsetFieldHighlighted(screenFields.getCurrentField());
2653
2654 screenFields.gotoFieldNext();
2655
2656 if (screenFields.isCurrentFieldHighlightedEntry())
2657 setFieldHighlighted(screenFields.getCurrentField());
2658 }
2659
2660 /**
2661 * Convinience class to position to the previous field on the screen.
2662 *
2663 * @see org.tn5250j.ScreenFields
2664 */
2665 private void gotoFieldPrev() {
2666 if (screenFields.isCurrentFieldHighlightedEntry())
2667 unsetFieldHighlighted(screenFields.getCurrentField());
2668
2669 screenFields.gotoFieldPrev();
2670
2671 if (screenFields.isCurrentFieldHighlightedEntry())
2672 setFieldHighlighted(screenFields.getCurrentField());
2673 }
2674
2675 /* *** NEVER USED LOCALLY ************************************************** */
2676 // /**
2677 // * Used to restrict the cursor to a particular position on the screen. Used
2678 // * in combination with windows to restrict the cursor to the active window
2679 // * show on the screen.
2680 // *
2681 // * Not supported yet. Please implement me :-(
2682 // *
2683 // * @param depth
2684 // * @param width
2685 // */
2686 // protected void setRestrictCursor(int depth, int width) {
2687 //
2688 // restrictCursor = true;
2689 // // restriction
2690 //
2691 // }
2692
2693 /**
2694 * Creates a window on the screen
2695 *
2696 * @param depth
2697 * @param width
2698 * @param type
2699 * @param gui
2700 * @param monoAttr
2701 * @param colorAttr
2702 * @param ul
2703 * @param upper
2704 * @param ur
2705 * @param left
2706 * @param right
2707 * @param ll
2708 * @param bottom
2709 * @param lr
2710 */
2711 protected void createWindow(int depth, int width, int type, boolean gui,
2712 int monoAttr, int colorAttr, int ul, int upper, int ur, int left,
2713 int right, int ll, int bottom, int lr) {
2714 int c = getCol(lastPos);
2715 int w = 0;
2716 width++;
2717 w = width;
2718 // set leading attribute byte
2719 // screen[lastPos].setCharAndAttr(initChar, initAttr, true);
2720 planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true);
2721 setDirty(lastPos);
2722 advancePos();
2723 // set upper left
2724 // screen[lastPos].setCharAndAttr((char) ul, colorAttr, false);
2725 planes.setScreenCharAndAttr(lastPos, (char) ul, colorAttr, false);
2726
2727 if (gui) {
2728 // screen[lastPos].setUseGUI(UPPER_LEFT);
2729 planes.setUseGUI(lastPos, UPPER_LEFT);
2730 }
2731
2732 setDirty(lastPos);
2733 advancePos();
2734
2735 // draw top row
2736
2737 while (w-- >= 0) {
2738 // screen[lastPos].setCharAndAttr((char) upper, colorAttr, false);
2739 planes.setScreenCharAndAttr(lastPos, (char) upper, colorAttr, false);
2740
2741 if (gui) {
2742 // screen[lastPos].setUseGUI(UPPER);
2743 planes.setUseGUI(lastPos, UPPER);
2744 }
2745
2746 setDirty(lastPos);
2747 advancePos();
2748 }
2749
2750 // set upper right
2751 // screen[lastPos].setCharAndAttr((char) ur, colorAttr, false);
2752 planes.setScreenCharAndAttr(lastPos, (char) ur, colorAttr, false);
2753
2754 if (gui) {
2755 // screen[lastPos].setUseGUI(UPPER_RIGHT);
2756 planes.setUseGUI(lastPos, UPPER_RIGHT);
2757 }
2758
2759 setDirty(lastPos);
2760 advancePos();
2761 // set ending attribute byte
2762 planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true);
2763 setDirty(lastPos);
2764 lastPos = ((getRow(lastPos) + 1) * numCols) + c;
2765
2766 // now handle body of window
2767 while (depth-- > 0) {
2768 // set leading attribute byte
2769 planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true);
2770 setDirty(lastPos);
2771 advancePos();
2772 // set left
2773 planes.setScreenCharAndAttr(lastPos, (char) left, colorAttr, false);
2774
2775 if (gui) {
2776 planes.setUseGUI(lastPos, GUI_LEFT);
2777 }
2778
2779 setDirty(lastPos);
2780 advancePos();
2781 w = width;
2782
2783 // fill it in
2784 while (w-- >= 0) {
2785 // screen[lastPos].setCharAndAttr(initChar, initAttr, true);
2786 planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true);
2787 // screen[lastPos].setUseGUI(NO_GUI);
2788 planes.setUseGUI(lastPos, NO_GUI);
2789 setDirty(lastPos);
2790 advancePos();
2791 }
2792
2793 // set right
2794 // screen[lastPos].setCharAndAttr((char) right, colorAttr, false);
2795 planes.setScreenCharAndAttr(lastPos, (char) right, colorAttr, false);
2796
2797 if (gui) {
2798 // screen[lastPos].setUseGUI(RIGHT);
2799 planes.setUseGUI(lastPos, GUI_RIGHT);
2800 }
2801
2802 setDirty(lastPos);
2803 advancePos();
2804 // set ending attribute byte
2805 // screen[lastPos].setCharAndAttr(initChar, initAttr, true);
2806 planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true);
2807 setDirty(lastPos);
2808 lastPos = ((getRow(lastPos) + 1) * numCols) + c;
2809 }
2810
2811 // set leading attribute byte
2812 // screen[lastPos].setCharAndAttr(initChar, initAttr, true);
2813 planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true);
2814 setDirty(lastPos);
2815 advancePos();
2816 // set lower left
2817 // screen[lastPos].setCharAndAttr((char) ll, colorAttr, false);
2818 planes.setScreenCharAndAttr(lastPos, (char) ll, colorAttr, false);
2819
2820 if (gui) {
2821 // screen[lastPos].setUseGUI(LOWER_LEFT);
2822 planes.setUseGUI(lastPos, LOWER_LEFT);
2823 }
2824
2825 setDirty(lastPos);
2826 advancePos();
2827 w = width;
2828
2829 // draw bottom row
2830 while (w-- >= 0) {
2831 planes.setScreenCharAndAttr(lastPos, (char) bottom, colorAttr, false);
2832
2833 if (gui) {
2834 planes.setUseGUI(lastPos, BOTTOM);
2835 }
2836
2837 setDirty(lastPos);
2838 advancePos();
2839 }
2840
2841 // set lower right
2842 planes.setScreenCharAndAttr(lastPos, (char) lr, colorAttr, false);
2843
2844 if (gui) {
2845 planes.setUseGUI(lastPos, LOWER_RIGHT);
2846 }
2847
2848 setDirty(lastPos);
2849 advancePos();
2850 // set ending attribute byte
2851 planes.setScreenCharAndAttr(lastPos, initChar, initAttr, true);
2852 setDirty(lastPos);
2853 }
2854
2855 /**
2856 * Creates a scroll bar on the screen using the parameters provided.
2857 * ** we only support vertical scroll bars at the time.
2858 *
2859 * @param flag -
2860 * type to draw - vertical or horizontal
2861 * @param totalRowScrollable
2862 * @param totalColScrollable
2863 * @param sliderRowPos
2864 * @param sliderColPos
2865 * @param sbSize
2866 */
2867 protected void createScrollBar(int flag, int totalRowScrollable,
2868 int totalColScrollable, int sliderRowPos, int sliderColPos,
2869 int sbSize) {
2870 // System.out.println("Scrollbar flag: " + flag +
2871 // " scrollable Rows: " + totalRowScrollable +
2872 // " scrollable Cols: " + totalColScrollable +
2873 // " thumb Row: " + sliderRowPos +
2874 // " thumb Col: " + sliderColPos +
2875 // " size: " + sbSize +
2876 // " row: " + getRow(lastPos) +
2877 // " col: " + getCol(lastPos));
2878 int sp = lastPos;
2879 int size = sbSize - 2;
2880 int thumbPos = (int)(size * ((float) sliderColPos / (float) totalColScrollable));
2881 // System.out.println(thumbPos);
2882 planes.setScreenCharAndAttr(sp, ' ', 32, false);
2883 planes.setUseGUI(sp, BUTTON_SB_UP);
2884 int ctr = 0;
2885
2886 while (ctr < size) {
2887 sp += numCols;
2888 planes.setScreenCharAndAttr(sp, ' ', 32, false);
2889
2890 if (ctr == thumbPos)
2891 planes.setUseGUI(sp, BUTTON_SB_THUMB);
2892 else
2893 planes.setUseGUI(sp, BUTTON_SB_GUIDE);
2894
2895 ctr++;
2896 }
2897
2898 sp += numCols;
2899 planes.setScreenCharAndAttr(sp, ' ', 32, false);
2900 planes.setUseGUI(sp, BUTTON_SB_DN);
2901 }
2902
2903 /**
2904 * Write the title of the window that is on the screen
2905 *
2906 * @param pos
2907 * @param depth
2908 * @param width
2909 * @param orientation
2910 * @param monoAttr
2911 * @param colorAttr
2912 * @param title
2913 */
2914 protected void writeWindowTitle(int pos, int depth, int width,
2915 byte orientation, int monoAttr, int colorAttr, StringBuffer title) {
2916 int len = title.length();
2917
2918 // get bit 0 and 1 for interrogation
2919 switch (orientation & 0xc0) {
2920 case 0x40: // right
2921 pos += (4 + width - len);
2922 break;
2923
2924 case 0x80: // left
2925 pos += 2;
2926 break;
2927
2928 default: // center
2929 // this is to place the position to the first text position of the
2930 // window
2931 // the position passed in is the first attribute position, the next
2932 // is the border character and then there is another attribute after
2933 // that.
2934 pos += (3 + ((width / 2) - (len / 2)));
2935 break;
2936 }
2937
2938 // if bit 2 is on then this is a footer
2939 if ((orientation & 0x20) == 0x20)
2940 pos += ((depth + 1) * numCols);
2941
2942 // System.out.println(pos + "," + width + "," + len+ "," + getRow(pos)
2943 // + "," + getCol(pos) + "," + ((orientation >> 6) & 0xf0));
2944
2945 for (int x = 0; x < len; x++) {
2946 planes.setChar(pos, title.charAt(x));
2947 planes.setUseGUI(pos++, NO_GUI);
2948 }
2949 }
2950
2951 /**
2952 * Roll the screen up or down.
2953 *
2954 * Byte 1: Bit 0 0 = Roll up 1 = Roll down Bits 1-2 Reserved Bits 3-7 Number
2955 * of lines that the designated area is to be rolled Byte 2: Bits 0-7 Line
2956 * number defining the top line of the area that will participate in the
2957 * roll. Byte 3: Bits 0-7 Line number defining the bottom line of the area
2958 * that will participate in the roll.
2959 *
2960 * @param direction
2961 * @param topLine
2962 * @param bottomLine
2963 */
2964 protected void rollScreen(int direction, int topLine, int bottomLine) {
2965 // get the number of lines which are the last 5 bits
2966 /* int lines = direction & 0x7F; */
2967 // get the direction of the roll which is the first bit
2968 // 0 - up
2969 // 1 - down
2970 int updown = direction & 0x80;
2971 final int lines = direction & 0x7F;
2972 // calculate the reference points for the move.
2973 int start = this.getPos(topLine - 1, 0);
2974 int end = this.getPos(bottomLine - 1, numCols - 1);
2975 int len = end - start;
2976
2977 // System.out.println(" starting roll");
2978 // dumpScreen();
2979 switch (updown) {
2980 case 0:
2981
2982 // Now round em up and head em UP.
2983 for (int x = start; x < end + numCols; x++) {
2984 if (x + lines * numCols >= lenScreen) {
2985 //Clear at the end
2986 planes.setChar(x, ' ');
2987 }
2988 else {
2989 planes.setChar(x, planes.getChar(x + lines * numCols));
2990 }
2991 }
2992
2993 break;
2994
2995 case 1:
2996
2997 // Now round em up and head em DOWN.
2998 for (int x = end + numCols; x > 0; x--) {
2999 if ((x - lines * numCols) < 0) {
3000 //Do nothing ... tooo small!!!
3001 }
3002 else {
3003 planes.setChar(x - lines * numCols, planes.getChar(x));
3004 //and clear
3005 planes.setChar(x, ' ');
3006 }
3007 }
3008
3009 break;
3010
3011 default:
3012 Log.w(TAG, " Invalid roll parameter - please report this");
3013 }
3014
3015 // System.out.println(" end roll");
3016 // dumpScreen();
3017 }
3018
3019 public void dumpScreen() {
3020 StringBuffer sb = new StringBuffer();
3021 char[] s = getScreenAsChars();
3022 int c = getColumns();
3023 int l = getRows() * c;
3024 int col = 0;
3025
3026 for (int x = 0; x < l; x++, col++) {
3027 sb.append(s[x]);
3028
3029 if (col == c) {
3030 sb.append('\n');
3031 col = 0;
3032 }
3033 }
3034
3035 Log.i(TAG, sb.toString());
3036 }
3037
3038 /**
3039 * Add a field to the field format table.
3040 *
3041 * @param attr - Field attribute
3042 * @param len - length of field
3043 * @param ffw1 - Field format word 1
3044 * @param ffw2 - Field format word 2
3045 * @param fcw1 - Field control word 1
3046 * @param fcw2 - Field control word 2
3047 */
3048 protected void addField(int attr, int len, int ffw1, int ffw2, int fcw1,
3049 int fcw2) {
3050 lastAttr = attr;
3051 planes.setScreenCharAndAttr(lastPos, initChar, lastAttr, true);
3052 setDirty(lastPos);
3053 advancePos();
3054 ScreenField sf = null;
3055
3056 // from 14.6.12 for Start of Field Order 5940 function manual
3057 // examine the format table for an entry that begins at the current
3058 // starting address plus 1.
3059 if (screenFields.existsAtPos(lastPos)) {
3060 screenFields.setCurrentFieldFFWs(ffw1, ffw2);
3061 }
3062 else {
3063 sf = screenFields.setField(attr, getRow(lastPos), getCol(lastPos),
3064 len, ffw1, ffw2, fcw1, fcw2);
3065 lastPos = sf.startPos();
3066 int x = len;
3067 boolean gui = guiInterface;
3068
3069 if (sf.isBypassField())
3070 gui = false;
3071
3072 while (x-- > 0) {
3073 if (planes.getChar(lastPos) == 0)
3074 planes.setScreenCharAndAttr(lastPos, ' ', lastAttr, false);
3075 else
3076 planes.setScreenAttr(lastPos, lastAttr);
3077
3078 if (gui) {
3079 planes.setUseGUI(lastPos, FIELD_MIDDLE);
3080 }
3081
3082 // now we set the field plane attributes
3083 planes.setScreenFieldAttr(lastPos, ffw1);
3084 advancePos();
3085 }
3086
3087 if (gui)
3088 if (len > 1) {
3089 planes.setUseGUI(sf.startPos(), FIELD_LEFT);
3090
3091 if (lastPos > 0)
3092 planes.setUseGUI(lastPos - 1, FIELD_RIGHT);
3093 else
3094 planes.setUseGUI(lastPos, FIELD_RIGHT);
3095 }
3096 else {
3097 planes.setUseGUI(lastPos - 1, FIELD_ONE);
3098 }
3099
3100 // screen[lastPos].setCharAndAttr(initChar,initAttr,true);
3101 setEndingAttr(initAttr);
3102 lastPos = sf.startPos();
3103 }
3104
3105 // if (fcw1 != 0 || fcw2 != 0) {
3106 // System.out.println("lr = " + lastRow + " lc = " + lastCol + " " +
3107 // sf.toString());
3108 // }
3109 sf = null;
3110 }
3111
3112
3113 // public void addChoiceField(int attr, int len, int ffw1, int ffw2, int
3114 // fcw1, int fcw2) {
3115 //
3116 // lastAttr = attr;
3117 //
3118 // screen[lastPos].setCharAndAttr(initChar,lastAttr,true);
3119 // setDirty(lastPos);
3120 //
3121 // advancePos();
3122 //
3123 // boolean found = false;
3124 // ScreenField sf = null;
3125 //
3126 // // from 14.6.12 for Start of Field Order 5940 function manual
3127 // // examine the format table for an entry that begins at the current
3128 // // starting address plus 1.
3129 // for (int x = 0;x < sizeFields; x++) {
3130 // sf = screenFields[x];
3131 //
3132 // if (lastPos == sf.startPos()) {
3133 // screenFields.getCurrentField() = sf;
3134 // screenFields.getCurrentField().setFFWs(ffw1,ffw2);
3135 // found = true;
3136 // }
3137 //
3138 // }
3139 //
3140 // if (!found) {
3141 // sf =
3142 // setField(attr,getRow(lastPos),getCol(lastPos),len,ffw1,ffw2,fcw1,fcw2);
3143 //
3144 // lastPos = sf.startPos();
3145 // int x = len;
3146 //
3147 // boolean gui = guiInterface;
3148 // if (sf.isBypassField())
3149 // gui = false;
3150 //
3151 // while (x-- > 0) {
3152 //
3153 // if (screen[lastPos].getChar() == 0)
3154 // screen[lastPos].setCharAndAttr(' ',lastAttr,false);
3155 // else
3156 // screen[lastPos].setAttribute(lastAttr);
3157 //
3158 // if (gui)
3159 // screen[lastPos].setUseGUI(FIELD_MIDDLE);
3160 //
3161 // advancePos();
3162 //
3163 // }
3164 //
3165 // if (gui)
3166 // if (len > 1) {
3167 // screen[sf.startPos()].setUseGUI(FIELD_LEFT);
3168 // if (lastPos > 0)
3169 // screen[lastPos-1].setUseGUI(FIELD_RIGHT);
3170 // else
3171 // screen[lastPos].setUseGUI(FIELD_RIGHT);
3172 //
3173 // }
3174 // else
3175 // screen[lastPos-1].setUseGUI(FIELD_ONE);
3176 //
3177 // setEndingAttr(initAttr);
3178 //
3179 // lastPos = sf.startPos();
3180 // }
3181 //
3182 // // if (fcw1 != 0 || fcw2 != 0) {
3183 // //
3184 // // System.out.println("lr = " + lastRow + " lc = " + lastCol + " " +
3185 // sf.toString());
3186 // // }
3187 // sf = null;
3188 //
3189 // }
3190
3191 /**
3192 * Return the fields that are contained in the Field Format Table
3193 *
3194 * @return ScreenFields object
3195 * @see org.tn5250j.ScreenFields
3196 */
3197 public ScreenFields getScreenFields() {
3198 return screenFields;
3199 }
3200
3201 /**
3202 * Redraw the fields on the screen. Used for gui enhancement to redraw the
3203 * fields when toggling
3204 *
3205 */
3206 protected void drawFields() {
3207 ScreenField sf;
3208 int sizeFields = screenFields.getSize();
3209
3210 for (int x = 0; x < sizeFields; x++) {
3211 sf = screenFields.getField(x);
3212
3213 if (!sf.isBypassField()) {
3214 int pos = sf.startPos();
3215 int l = sf.length;
3216 boolean f = true;
3217
3218 if (l >= lenScreen)
3219 l = lenScreen - 1;
3220
3221 if (l > 1) {
3222 while (l-- > 0) {
3223 if (guiInterface && f) {
3224 planes.setUseGUI(pos, FIELD_LEFT);
3225 f = false;
3226 }
3227 else {
3228 planes.setUseGUI(pos, FIELD_MIDDLE);
3229 }
3230
3231 if (guiInterface && l == 0) {
3232 planes.setUseGUI(pos, FIELD_RIGHT);
3233 }
3234
3235 setDirty(pos++);
3236 }
3237 }
3238 else {
3239 planes.setUseGUI(pos, FIELD_ONE);
3240 }
3241 }
3242 }
3243
3244 //updateDirty();
3245 }
3246
3247 /**
3248 * Draws the field on the screen. Used to redraw or change the attributes of
3249 * the field.
3250 *
3251 * @param sf -
3252 * Field to be redrawn
3253 * @see org.tn5250j.ScreenField.java
3254 */
3255 protected void drawField(ScreenField sf) {
3256 int pos = sf.startPos();
3257 int x = sf.length;
3258
3259 while (x-- > 0) {
3260 setDirty(pos++);
3261 }
3262
3263 updateDirty();
3264 }
3265
3266 /**
3267 * Set the field to be displayed as highlighted.
3268 *
3269 * @param sf -
3270 * Field to be highlighted
3271 */
3272 protected void setFieldHighlighted(ScreenField sf) {
3273 int pos = sf.startPos();
3274 int x = sf.length;
3275 int na = sf.getHighlightedAttr();
3276
3277 while (x-- > 0) {
3278 planes.setScreenAttr(pos, na);
3279 setDirty(pos++);
3280 }
3281
3282 fireScreenChanged();
3283 }
3284
3285 /**
3286 * Draw the field as un higlighted. This is used to reset the field
3287 * presentation on the screen after the field is exited.
3288 *
3289 * @param sf -
3290 * Field to be unhighlighted
3291 */
3292 protected void unsetFieldHighlighted(ScreenField sf) {
3293 int pos = sf.startPos();
3294 int x = sf.length;
3295 int na = sf.getAttr();
3296
3297 while (x-- > 0) {
3298 planes.setScreenAttr(pos, na);
3299 setDirty(pos++);
3300 }
3301
3302 fireScreenChanged();
3303 }
3304
3305 protected void setChar(int cByte) {
3306 if (lastPos > 0) {
3307 lastAttr = planes.getCharAttr(lastPos - 1);
3308 }
3309
3310 if (cByte > 0 && (char)cByte < ' ') {
3311 planes.setScreenCharAndAttr(lastPos, (char) 0x00, 33, false);
3312 setDirty(lastPos);
3313 advancePos();
3314 }
3315 else {
3316 planes.setScreenCharAndAttr(lastPos, (char) cByte, lastAttr, false);
3317 setDirty(lastPos);
3318
3319 if (guiInterface && !isInField(lastPos, false)) {
3320 planes.setUseGUI(lastPos, NO_GUI);
3321 }
3322
3323 advancePos();
3324 }
3325 }
3326
3327 protected void setEndingAttr(int cByte) {
3328 int attr = lastAttr;
3329 setAttr(cByte);
3330 lastAttr = attr;
3331 }
3332
3333 protected void setAttr(int cByte) {
3334 lastAttr = cByte;
3335 // int sattr = screen[lastPos].getCharAttr();
3336 // System.out.println("changing from " + sattr + " to attr " + lastAttr
3337 // +
3338 // " at " + (this.getRow(lastPos) + 1) + "," + (this.getCol(lastPos) +
3339 // 1));
3340 planes.setScreenCharAndAttr(lastPos, initChar, lastAttr, true);
3341 setDirty(lastPos);
3342 advancePos();
3343 int pos = lastPos;
3344 int times = 0;
3345 // sattr = screen[lastPos].getCharAttr();
3346 // System.out.println(" next position after change " + sattr + " last
3347 // attr " + lastAttr +
3348 // " at " + (this.getRow(lastPos) + 1) + "," + (this.getCol(lastPos) +
3349 // 1) +
3350 // " attr place " + screen[lastPos].isAttributePlace());
3351
3352 while (planes.getCharAttr(lastPos) != lastAttr
3353 && !planes.isAttributePlace(lastPos)) {
3354 planes.setScreenAttr(lastPos, lastAttr);
3355
3356 if (guiInterface && !isInField(lastPos, false)) {
3357 int g = planes.getWhichGUI(lastPos);
3358
3359 if (g >= FIELD_LEFT && g <= FIELD_ONE)
3360 planes.setUseGUI(lastPos, NO_GUI);
3361 }
3362
3363 setDirty(lastPos);
3364 times++;
3365 advancePos();
3366 }
3367
3368 // sanity check for right now
3369 // if (times > 200)
3370 // System.out.println(" setAttr = " + times + " start = " + (sr + 1) +
3371 // "," + (sc + 1));
3372 lastPos = pos;
3373 }
3374
3375 protected void setScreenCharAndAttr(char right, int colorAttr, boolean isAttr) {
3376 planes.setScreenCharAndAttr(lastPos, right, colorAttr, isAttr);
3377 setDirty(lastPos);
3378 advancePos();
3379 }
3380
3381 protected void setScreenCharAndAttr(char right, int colorAttr,
3382 int whichGui, boolean isAttr) {
3383 planes.setScreenCharAndAttr(lastPos, right, colorAttr, isAttr);
3384 planes.setUseGUI(lastPos, whichGui);
3385 setDirty(lastPos);
3386 advancePos();
3387 }
3388
3389 /**
3390 * Draw or redraw the dirty parts of the screen and display them.
3391 *
3392 * Rectangle dirty holds the dirty area of the screen to be updated.
3393 *
3394 * If you want to change the screen in anyway you need to set the screen
3395 * attributes before calling this routine.
3396 */
3397 protected void updateDirty() {
3398 fireScreenChanged();
3399 }
3400
3401 protected void setDirty(int pos) {
3402 int minr = Math.min(getRow(pos), getRow(dirtyScreen.x));
3403 int minc = Math.min(getCol(pos), getCol(dirtyScreen.x));
3404 int maxr = Math.max(getRow(pos), getRow(dirtyScreen.y));
3405 int maxc = Math.max(getCol(pos), getCol(dirtyScreen.y));
3406 int x1 = getPos(minr, minc);
3407 int x2 = getPos(maxr, maxc);
3408 dirtyScreen.setBounds(x1, x2, 0, 0);
3409 }
3410
3411 private void resetDirty(int pos) {
3412 dirtyScreen.setBounds(pos, pos, 0, 0);
3413 }
3414
3415 /**
3416 * Change the screen position by one column
3417 */
3418 protected void advancePos() {
3419 changePos(1);
3420 }
3421
3422 /**
3423 * Change position of the screen by the increment of parameter passed.
3424 *
3425 * If the position change is under the minimum of the first screen position
3426 * then the position is moved to the last row and column of the screen.
3427 *
3428 * If the position change is over the last row and column of the screen then
3429 * cursor is moved to first position of the screen.
3430 *
3431 * @param i
3432 */
3433 protected void changePos(int i) {
3434 lastPos += i;
3435
3436 while (lastPos < 0) lastPos += lenScreen;
3437
3438 while (lastPos >= lenScreen) lastPos -= lenScreen;
3439 }
3440
3441
3442 protected void goHome() {
3443 // now we try to move to first input field according to
3444 // 14.6 WRITE TO DISPLAY Command
3445 // ? If the WTD command is valid, after the command is processed,
3446 // the cursor moves to one of three locations:
3447 // - The location set by an insert cursor order (unless control
3448 // character byte 1, bit 1 is equal to B'1'.)
3449 // - The start of the first non-bypass input field defined in the
3450 // format table
3451 // - A default starting address of row 1 column 1.
3452 if (pendingInsert && homePos > 0) {
3453 setCursor(getRow(homePos), getCol(homePos));
3454 isInField();
3455 }
3456 else {
3457 if (!gotoField(1)) {
3458 homePos = getPos(1, 1);
3459 setCursor(1, 1);
3460 isInField(0, 0);
3461 }
3462 else {
3463 homePos = getPos(getCurrentRow(), getCurrentCol());
3464 }
3465 }
3466 }
3467
3468 protected void setPendingInsert(boolean flag, int icX, int icY) {
3469 pendingInsert = flag;
3470
3471 if (pendingInsert) {
3472 homePos = getPos(icX, icY);
3473 }
3474
3475 if (!isStatusErrorCode()) {
3476 setCursor(icX, icY);
3477 }
3478 }
3479
3480 protected void setPendingInsert(boolean flag) {
3481 if (homePos != -1)
3482 pendingInsert = flag;
3483 }
3484
3485 /**
3486 * Set the error line number to that of number passed.
3487 *
3488 * @param line
3489 */
3490 protected void setErrorLine(int line) {
3491 planes.setErrorLine(line);
3492 }
3493
3494 /**
3495 * Returns the current error line number
3496 *
3497 * @return current error line number
3498 */
3499 protected int getErrorLine() {
3500 return planes.getErrorLine();
3501 }
3502
3503 /**
3504 * Saves off the current error line characters to be used later.
3505 *
3506 */
3507 protected void saveErrorLine() {
3508 planes.saveErrorLine();
3509 }
3510
3511 /**
3512 * Restores the error line characters from the save buffer.
3513 *
3514 * @see #saveErrorLine()
3515 */
3516 protected void restoreErrorLine() {
3517 if (planes.isErrorLineSaved()) {
3518 planes.restoreErrorLine();
3519 fireScreenChanged(planes.getErrorLine() - 1, 0, planes.getErrorLine() - 1, numCols - 1);
3520 }
3521 }
3522
3523 protected void setStatus(byte attr, byte value, String s) {
3524 // set the status area
3525 switch (attr) {
3526 case STATUS_SYSTEM:
3527 if (value == STATUS_VALUE_ON) {
3528 oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT, ScreenOIA.OIA_LEVEL_INPUT_INHIBITED, s);
3529 }
3530 else {
3531 oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_NOTINHIBITED, ScreenOIA.OIA_LEVEL_NOT_INHIBITED, s);
3532 }
3533
3534 break;
3535
3536 case STATUS_ERROR_CODE:
3537 if (value == STATUS_VALUE_ON) {
3538 setPrehelpState(true, true, false);
3539 oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT,
3540 ScreenOIA.OIA_LEVEL_INPUT_ERROR, s);
3541 sessionVT.signalBell();
3542 }
3543 else {
3544 oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_NOTINHIBITED,
3545 ScreenOIA.OIA_LEVEL_NOT_INHIBITED);
3546 setPrehelpState(false, true, true);
3547 homePos = saveHomePos;
3548 saveHomePos = 0;
3549 pendingInsert = false;
3550 }
3551
3552 break;
3553 }
3554 }
3555
3556 protected boolean isStatusErrorCode() {
3557 return oia.getLevel() == ScreenOIA.OIA_LEVEL_INPUT_ERROR;
3558 }
3559
3560 /**
3561 * This routine clears the screen, resets row and column to 0, resets the
3562 * last attribute to 32, clears the fields, turns insert mode off,
3563 * clears/initializes the screen character array.
3564 */
3565 protected void clearAll() {
3566 lastAttr = 32;
3567 lastPos = 0;
3568 clearTable();
3569 clearScreen();
3570 planes.setScreenAttr(0, initAttr);
3571 oia.setInsertMode(false);
3572 }
3573
3574 /**
3575 * Clear the fields table
3576 */
3577 protected void clearTable() {
3578 oia.setKeyBoardLocked(true);
3579 screenFields.clearFFT();
3580 planes.initalizeFieldPlanes();
3581 pendingInsert = false;
3582 homePos = -1;
3583 }
3584
3585 /**
3586 * Clear the gui constructs
3587 *
3588 */
3589 protected void clearGuiStuff() {
3590 for (int x = 0; x < lenScreen; x++) {
3591 planes.setUseGUI(x, NO_GUI);
3592 }
3593
3594 dirtyScreen.setBounds(0, lenScreen - 1, 0, 0);
3595 }
3596
3597 /**
3598 * Clear the screen by setting the initial character and initial attribute
3599 * to all the positions on the screen
3600 */
3601 protected void clearScreen() {
3602 planes.initalizePlanes();
3603 dirtyScreen.setBounds(0, lenScreen - 1, 0, 0);
3604 oia.clearScreen();
3605 }
3606
3607 protected void restoreScreen() {
3608 lastAttr = 32;
3609 dirtyScreen.setBounds(0, lenScreen - 1, 0, 0);
3610 updateDirty();
3611 }
3612
3613 public void onFontSizeChanged(float size) {
3614 fireScreenChanged(0, 0, numRows - 1, numCols - 1);
3615 }
3616
3617 /**
3618 * repaint part of the screen
3619 *
3620 */
3621 private void fireScreenChanged(int startRow, int startCol, int endRow, int endCol) {
3622 int [] vt320color = {0x0, // black
3623 0x4, // blue
3624 0x2, // green
3625 0x6, // cyan
3626 0x1, // red
3627 0x5, // magenta/purple
3628 0xb, // yellow
3629 0x7, // light gray/white
3630 0x8, // dark gray
3631 0xc, // light blue
3632 0xa, // light green
3633 0xe, // light cyan
3634 0x9, // light red
3635 0xd, // light magenta/purple
3636 0x3, // brown
3637 0xf // bright white
3638 };
3639
3640 for (int r = startRow; r <= endRow; r++) {
3641 for (int c = startCol; c <= endCol; c++) {
3642 int p = getPos(r, c);
3643 char ch = planes.getChar(p);
3644 char co = planes.getCharColor(p);
3645 char at = planes.getCharExtended(p);
3646 boolean ia = planes.isAttributePlace(p);
3647
3648 if (ch < ' ') ch = ' ';
3649
3650 int bg = vt320color[(co >> 8) & 0x0f] + 1;
3651 int fg = vt320color[co & 0x0f] + 1;
3652 int ul = at & EXTENDED_5250_UNDERLINE;
3653 int nd = at & EXTENDED_5250_NON_DSP;
3654 int vt_attr = (fg << VDUBuffer.COLOR_FG_SHIFT) + (bg << VDUBuffer.COLOR_BG_SHIFT);
3655
3656 if (ul > 0) vt_attr |= VDUBuffer.UNDERLINE;
3657
3658 if (ia || (nd > 0)) vt_attr |= VDUBuffer.INVISIBLE;
3659
3660 buffer.putChar(c, r, ch, vt_attr);
3661 }
3662 }
3663
3664 buffer.redrawPassthru();
3665 dirtyScreen.setBounds(lenScreen, 0, 0, 0);
3666 }
3667
3668 /**
3669 * repaint the dirty part of the screen
3670 *
3671 */
3672
3673 private synchronized void fireScreenChanged() {
3674 if (dirtyScreen.x > dirtyScreen.y) return;
3675 fireScreenChanged(getRow(dirtyScreen.x), getCol(dirtyScreen.x),
3676 getRow(dirtyScreen.y), getCol(dirtyScreen.y));
3677 }
3678
3679 /**
3680 * update the cursor position
3681 *
3682 */
3683
3684 private synchronized void fireCursorChanged() {
3685 int l = getRow(lastPos);
3686 int c = getCol(lastPos);
3687 buffer.setCursorPosition(c, l);
3688 }
3689
3690 /**
3691 * update the screen size.
3692 */
3693 private void fireScreenSizeChanged() {
3694 buffer.setScreenSize(numCols, numRows, true);
3695 }
3696
3697 /**
3698 * This method does a complete refresh of the screen.
3699 */
3700 public final void updateScreen() {
3701 repaintScreen();
3702 setCursorActive(false);
3703 setCursorActive(true);
3704 }
3705
3706 /**
3707 * Utility method to share the repaint behaviour between setBounds() and
3708 * updateScreen.
3709 */
3710 public void repaintScreen() {
3711 setCursorOff();
3712 dirtyScreen.setBounds(0, lenScreen - 1, 0, 0);
3713 updateDirty();
3714
3715 // restore statuses that were on the screen before resize
3716 if (oia.getLevel() == ScreenOIA.OIA_LEVEL_INPUT_ERROR) {
3717 oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT,
3718 ScreenOIA.OIA_LEVEL_INPUT_ERROR);
3719 }
3720
3721 if (oia.getLevel() == ScreenOIA.OIA_LEVEL_INPUT_INHIBITED) {
3722 oia.setInputInhibited(ScreenOIA.INPUTINHIBITED_SYSTEM_WAIT,
3723 ScreenOIA.OIA_LEVEL_INPUT_INHIBITED);
3724 }
3725
3726 if (oia.isMessageWait())
3727 oia.setMessageLightOn();
3728
3729 setCursorOn();
3730 }
3731
3732 // ADDED BY BARRY - changed by Kenneth to use the character plane
3733 // This should be replaced with the getPlane methods when they are implemented
3734 public char[] getCharacters() {
3735 return planes.screen;
3736 }
3737
3738 }