Mercurial > 510Connectbot
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 } |