Mercurial > 510Connectbot
annotate src/de/mud/terminal/VDUBuffer.java @ 153:3ca280646f2d
allow zero length setfield
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Mon, 23 Jun 2014 11:18:02 -0700 |
parents | 6eab98e58bed |
children | 071eccdff8ea |
rev | line source |
---|---|
0 | 1 /* |
2 * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform". | |
3 * | |
41
9621ac4dd5eb
start tn5250 integration
Carl Byington <carl@five-ten-sg.com>
parents:
0
diff
changeset
|
4 * (c) Matthias L. Jugel, Marcus Meißner 1996-2005. All Rights Reserved. |
0 | 5 * |
6 * Please visit http://javatelnet.org/ for updates and contact. | |
7 * | |
8 * --LICENSE NOTICE-- | |
9 * This program is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU General Public License | |
11 * as published by the Free Software Foundation; either version 2 | |
12 * of the License, or (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 * --LICENSE NOTICE-- | |
23 * | |
24 */ | |
25 | |
26 package de.mud.terminal; | |
27 | |
28 import java.util.Arrays; | |
29 | |
30 /** | |
31 * Implementation of a Video Display Unit (VDU) buffer. This class contains | |
32 * all methods to manipulate the buffer that stores characters and their | |
33 * attributes as well as the regions displayed. | |
34 * | |
35 * @author Matthias L. Jugel, Marcus Meißner | |
36 * @version $Id: VDUBuffer.java 503 2005-10-24 07:34:13Z marcus $ | |
37 */ | |
38 public class VDUBuffer { | |
39 | |
41
9621ac4dd5eb
start tn5250 integration
Carl Byington <carl@five-ten-sg.com>
parents:
0
diff
changeset
|
40 /** a generic display that should redraw on demand */ |
9621ac4dd5eb
start tn5250 integration
Carl Byington <carl@five-ten-sg.com>
parents:
0
diff
changeset
|
41 protected VDUDisplay display; |
0 | 42 |
43 /** Enable debug messages. */ | |
44 public final static int debug = 0; | |
45 | |
46 public int height, width; /* rows and columns */ | |
47 public boolean[] update; /* contains the lines that need update */ | |
48 public char[][] charArray; /* contains the characters */ | |
49 public int[][] charAttributes; /* contains character attrs */ | |
50 public int bufSize; | |
51 public int maxBufSize; /* buffer sizes */ | |
52 public int screenBase; /* the actual screen start */ | |
53 public int windowBase; /* where the start displaying */ | |
54 public int scrollMarker; /* marks the last line inserted */ | |
55 | |
56 private int topMargin; /* top scroll margin */ | |
57 private int bottomMargin; /* bottom scroll margin */ | |
58 | |
59 // cursor variables | |
60 protected boolean showcursor = true; | |
61 protected int cursorX, cursorY; | |
62 | |
63 /** Scroll up when inserting a line. */ | |
64 public final static boolean SCROLL_UP = false; | |
65 /** Scroll down when inserting a line. */ | |
66 public final static boolean SCROLL_DOWN = true; | |
67 | |
68 /* Attributes bit-field usage: | |
69 * | |
70 * 8421 8421 8421 8421 8421 8421 8421 8421 | |
71 * |||| |||| |||| |||| |||| |||| |||| |||`- Bold | |
72 * |||| |||| |||| |||| |||| |||| |||| ||`-- Underline | |
73 * |||| |||| |||| |||| |||| |||| |||| |`--- Invert | |
74 * |||| |||| |||| |||| |||| |||| |||| `---- Low | |
75 * |||| |||| |||| |||| |||| |||| |||`------ Invisible | |
76 * |||| |||| |||| |||| ||`+-++++-+++------- Foreground Color | |
77 * |||| |||| |`++-++++-++------------------ Background Color | |
78 * |||| |||| `----------------------------- Fullwidth character | |
79 * `+++-++++------------------------------- Reserved for future use | |
80 */ | |
81 | |
82 /** Make character normal. */ | |
83 public final static int NORMAL = 0x00; | |
84 /** Make character bold. */ | |
85 public final static int BOLD = 0x01; | |
86 /** Underline character. */ | |
87 public final static int UNDERLINE = 0x02; | |
88 /** Invert character. */ | |
89 public final static int INVERT = 0x04; | |
90 /** Lower intensity character. */ | |
91 public final static int LOW = 0x08; | |
92 /** Invisible character. */ | |
93 public final static int INVISIBLE = 0x10; | |
94 /** Unicode full-width character (CJK, et al.) */ | |
95 public final static int FULLWIDTH = 0x8000000; | |
96 | |
97 /** how much to left shift the foreground color */ | |
98 public final static int COLOR_FG_SHIFT = 5; | |
99 /** how much to left shift the background color */ | |
100 public final static int COLOR_BG_SHIFT = 14; | |
101 /** color mask */ | |
75
bf01d1eec5c6
convert 5250 to vt320 attributes
Carl Byington <carl@five-ten-sg.com>
parents:
41
diff
changeset
|
102 public final static int COLOR = 0x7fffe0; /* 0000 0000 0111 1111 1111 1111 1110 0000 */ |
0 | 103 /** foreground color mask */ |
75
bf01d1eec5c6
convert 5250 to vt320 attributes
Carl Byington <carl@five-ten-sg.com>
parents:
41
diff
changeset
|
104 public final static int COLOR_FG = 0x003fe0; /* 0000 0000 0000 0000 0011 1111 1110 0000 */ |
0 | 105 /** background color mask */ |
75
bf01d1eec5c6
convert 5250 to vt320 attributes
Carl Byington <carl@five-ten-sg.com>
parents:
41
diff
changeset
|
106 public final static int COLOR_BG = 0x7fc000; /* 0000 0000 0111 1111 1100 0000 0000 0000 */ |
0 | 107 |
108 /** | |
109 * Create a new video display buffer with the passed width and height in | |
110 * characters. | |
111 * @param width the length of the character lines | |
112 * @param height the amount of lines on the screen | |
113 */ | |
114 public VDUBuffer(int width, int height) { | |
115 // set the display screen size | |
116 setScreenSize(width, height, false); | |
117 } | |
118 | |
119 /** | |
120 * Create a standard video display buffer with 80 columns and 24 lines. | |
121 */ | |
122 public VDUBuffer() { | |
123 this(80, 24); | |
124 } | |
125 | |
126 /** | |
127 * Put a character on the screen with normal font and outline. | |
128 * The character previously on that position will be overwritten. | |
129 * You need to call redraw() to update the screen. | |
130 * @param c x-coordinate (column) | |
131 * @param l y-coordinate (line) | |
132 * @param ch the character to show on the screen | |
133 * @see #insertChar | |
134 * @see #deleteChar | |
135 * @see #redraw | |
136 */ | |
137 public void putChar(int c, int l, char ch) { | |
138 putChar(c, l, ch, NORMAL); | |
139 } | |
140 | |
141 /** | |
142 * Put a character on the screen with specific font and outline. | |
143 * The character previously on that position will be overwritten. | |
144 * You need to call redraw() to update the screen. | |
145 * @param c x-coordinate (column) | |
146 * @param l y-coordinate (line) | |
147 * @param ch the character to show on the screen | |
148 * @param attributes the character attributes | |
149 * @see #BOLD | |
150 * @see #UNDERLINE | |
151 * @see #INVERT | |
152 * @see #INVISIBLE | |
153 * @see #NORMAL | |
154 * @see #LOW | |
155 * @see #insertChar | |
156 * @see #deleteChar | |
157 * @see #redraw | |
158 */ | |
159 | |
160 public void putChar(int c, int l, char ch, int attributes) { | |
123
446dbcf606eb
add more 5250 config items; ignore drawing outside the screen
Carl Byington <carl@five-ten-sg.com>
parents:
75
diff
changeset
|
161 int ll = screenBase + l; |
446dbcf606eb
add more 5250 config items; ignore drawing outside the screen
Carl Byington <carl@five-ten-sg.com>
parents:
75
diff
changeset
|
162 if ((ll >= bufSize) || (c >= width)) return; // ignore characters outside our buffer |
446dbcf606eb
add more 5250 config items; ignore drawing outside the screen
Carl Byington <carl@five-ten-sg.com>
parents:
75
diff
changeset
|
163 charArray[ll][c] = ch; |
446dbcf606eb
add more 5250 config items; ignore drawing outside the screen
Carl Byington <carl@five-ten-sg.com>
parents:
75
diff
changeset
|
164 charAttributes[ll][c] = attributes; |
0 | 165 |
166 if (l < height) | |
167 update[l + 1] = true; | |
168 } | |
169 | |
170 /** | |
171 * Get the character at the specified position. | |
172 * @param c x-coordinate (column) | |
173 * @param l y-coordinate (line) | |
174 * @see #putChar | |
175 */ | |
176 public char getChar(int c, int l) { | |
177 return charArray[screenBase + l][c]; | |
178 } | |
179 | |
180 /** | |
181 * Get the attributes for the specified position. | |
182 * @param c x-coordinate (column) | |
183 * @param l y-coordinate (line) | |
184 * @see #putChar | |
185 */ | |
186 public int getAttributes(int c, int l) { | |
187 return charAttributes[screenBase + l][c]; | |
188 } | |
189 | |
190 /** | |
191 * Insert a character at a specific position on the screen. | |
192 * All character right to from this position will be moved one to the right. | |
193 * You need to call redraw() to update the screen. | |
194 * @param c x-coordinate (column) | |
195 * @param l y-coordinate (line) | |
196 * @param ch the character to insert | |
197 * @param attributes the character attributes | |
198 * @see #BOLD | |
199 * @see #UNDERLINE | |
200 * @see #INVERT | |
201 * @see #INVISIBLE | |
202 * @see #NORMAL | |
203 * @see #LOW | |
204 * @see #putChar | |
205 * @see #deleteChar | |
206 * @see #redraw | |
207 */ | |
208 public void insertChar(int c, int l, char ch, int attributes) { | |
209 System.arraycopy(charArray[screenBase + l], c, | |
210 charArray[screenBase + l], c + 1, width - c - 1); | |
211 System.arraycopy(charAttributes[screenBase + l], c, | |
212 charAttributes[screenBase + l], c + 1, width - c - 1); | |
213 putChar(c, l, ch, attributes); | |
214 } | |
215 | |
216 /** | |
217 * Delete a character at a given position on the screen. | |
218 * All characters right to the position will be moved one to the left. | |
219 * You need to call redraw() to update the screen. | |
220 * @param c x-coordinate (column) | |
221 * @param l y-coordinate (line) | |
222 * @see #putChar | |
223 * @see #insertChar | |
224 * @see #redraw | |
225 */ | |
226 public void deleteChar(int c, int l) { | |
227 if (c < width - 1) { | |
228 System.arraycopy(charArray[screenBase + l], c + 1, | |
229 charArray[screenBase + l], c, width - c - 1); | |
230 System.arraycopy(charAttributes[screenBase + l], c + 1, | |
231 charAttributes[screenBase + l], c, width - c - 1); | |
232 } | |
233 | |
234 putChar(width - 1, l, (char) 0); | |
235 } | |
236 | |
237 /** | |
238 * Put a String at a specific position. Any characters previously on that | |
239 * position will be overwritten. You need to call redraw() for screen update. | |
240 * @param c x-coordinate (column) | |
241 * @param l y-coordinate (line) | |
242 * @param s the string to be shown on the screen | |
243 * @see #BOLD | |
244 * @see #UNDERLINE | |
245 * @see #INVERT | |
246 * @see #INVISIBLE | |
247 * @see #NORMAL | |
248 * @see #LOW | |
249 * @see #putChar | |
250 * @see #insertLine | |
251 * @see #deleteLine | |
252 * @see #redraw | |
253 */ | |
254 public void putString(int c, int l, String s) { | |
255 putString(c, l, s, NORMAL); | |
256 } | |
257 | |
258 /** | |
259 * Put a String at a specific position giving all characters the same | |
260 * attributes. Any characters previously on that position will be | |
261 * overwritten. You need to call redraw() to update the screen. | |
262 * @param c x-coordinate (column) | |
263 * @param l y-coordinate (line) | |
264 * @param s the string to be shown on the screen | |
265 * @param attributes character attributes | |
266 * @see #BOLD | |
267 * @see #UNDERLINE | |
268 * @see #INVERT | |
269 * @see #INVISIBLE | |
270 * @see #NORMAL | |
271 * @see #LOW | |
272 * @see #putChar | |
273 * @see #insertLine | |
274 * @see #deleteLine | |
275 * @see #redraw | |
276 */ | |
277 public void putString(int c, int l, String s, int attributes) { | |
278 for (int i = 0; i < s.length() && c + i < width; i++) | |
279 putChar(c + i, l, s.charAt(i), attributes); | |
280 } | |
281 | |
282 /** | |
283 * Insert a blank line at a specific position. | |
284 * The current line and all previous lines are scrolled one line up. The | |
285 * top line is lost. You need to call redraw() to update the screen. | |
286 * @param l the y-coordinate to insert the line | |
287 * @see #deleteLine | |
288 * @see #redraw | |
289 */ | |
290 public void insertLine(int l) { | |
291 insertLine(l, 1, SCROLL_UP); | |
292 } | |
293 | |
294 /** | |
295 * Insert blank lines at a specific position. | |
296 * You need to call redraw() to update the screen | |
297 * @param l the y-coordinate to insert the line | |
298 * @param n amount of lines to be inserted | |
299 * @see #deleteLine | |
300 * @see #redraw | |
301 */ | |
302 public void insertLine(int l, int n) { | |
303 insertLine(l, n, SCROLL_UP); | |
304 } | |
305 | |
306 /** | |
307 * Insert a blank line at a specific position. Scroll text according to | |
308 * the argument. | |
309 * You need to call redraw() to update the screen | |
310 * @param l the y-coordinate to insert the line | |
311 * @param scrollDown scroll down | |
312 * @see #deleteLine | |
313 * @see #SCROLL_UP | |
314 * @see #SCROLL_DOWN | |
315 * @see #redraw | |
316 */ | |
317 public void insertLine(int l, boolean scrollDown) { | |
318 insertLine(l, 1, scrollDown); | |
319 } | |
320 | |
321 /** | |
322 * Insert blank lines at a specific position. | |
323 * The current line and all previous lines are scrolled one line up. The | |
324 * top line is lost. You need to call redraw() to update the screen. | |
325 * @param l the y-coordinate to insert the line | |
326 * @param n number of lines to be inserted | |
327 * @param scrollDown scroll down | |
328 * @see #deleteLine | |
329 * @see #SCROLL_UP | |
330 * @see #SCROLL_DOWN | |
331 * @see #redraw | |
332 */ | |
333 | |
334 public synchronized void insertLine(int l, int n, boolean scrollDown) { | |
335 char cbuf[][] = null; | |
336 int abuf[][] = null; | |
337 int offset = 0; | |
338 int oldBase = screenBase; | |
339 int newScreenBase = screenBase; | |
340 int newWindowBase = windowBase; | |
341 int newBufSize = bufSize; | |
342 | |
343 if (l > bottomMargin) /* We do not scroll below bottom margin (below the scrolling region). */ | |
344 return; | |
345 | |
346 int top = (l < topMargin ? | |
347 0 : (l > bottomMargin ? | |
348 (bottomMargin + 1 < height ? | |
349 bottomMargin + 1 : height - 1) : topMargin)); | |
350 int bottom = (l > bottomMargin ? | |
351 height - 1 : (l < topMargin ? | |
352 (topMargin > 0 ? | |
353 topMargin - 1 : 0) : bottomMargin)); | |
354 | |
355 // System.out.println("l is "+l+", top is "+top+", bottom is "+bottom+", bottomargin is "+bottomMargin+", topMargin is "+topMargin); | |
356 if (scrollDown) { | |
357 if (n > (bottom - top)) n = (bottom - top); | |
358 | |
359 int size = bottom - l - (n - 1); | |
360 | |
361 if (size < 0) size = 0; | |
362 | |
363 cbuf = new char[size][]; | |
364 abuf = new int[size][]; | |
365 System.arraycopy(charArray, oldBase + l, cbuf, 0, bottom - l - (n - 1)); | |
366 System.arraycopy(charAttributes, oldBase + l, | |
367 abuf, 0, bottom - l - (n - 1)); | |
368 System.arraycopy(cbuf, 0, charArray, oldBase + l + n, | |
369 bottom - l - (n - 1)); | |
370 System.arraycopy(abuf, 0, charAttributes, oldBase + l + n, | |
371 bottom - l - (n - 1)); | |
372 cbuf = charArray; | |
373 abuf = charAttributes; | |
374 } | |
375 else { | |
376 try { | |
377 if (n > (bottom - top) + 1) n = (bottom - top) + 1; | |
378 | |
379 if (bufSize < maxBufSize) { | |
380 if (bufSize + n > maxBufSize) { | |
381 offset = n - (maxBufSize - bufSize); | |
382 scrollMarker += offset; | |
383 newBufSize = maxBufSize; | |
384 newScreenBase = maxBufSize - height - 1; | |
385 newWindowBase = screenBase; | |
386 } | |
387 else { | |
388 scrollMarker += n; | |
389 newScreenBase += n; | |
390 newWindowBase += n; | |
391 newBufSize += n; | |
392 } | |
393 | |
394 cbuf = new char[newBufSize][]; | |
395 abuf = new int[newBufSize][]; | |
396 } | |
397 else { | |
398 offset = n; | |
399 cbuf = charArray; | |
400 abuf = charAttributes; | |
401 } | |
402 | |
403 // copy anything from the top of the buffer (+offset) to the new top | |
404 // up to the screenBase. | |
405 if (oldBase > 0) { | |
406 System.arraycopy(charArray, offset, | |
407 cbuf, 0, | |
408 oldBase - offset); | |
409 System.arraycopy(charAttributes, offset, | |
410 abuf, 0, | |
411 oldBase - offset); | |
412 } | |
413 | |
414 // copy anything from the top of the screen (screenBase) up to the | |
415 // topMargin to the new screen | |
416 if (top > 0) { | |
417 System.arraycopy(charArray, oldBase, | |
418 cbuf, newScreenBase, | |
419 top); | |
420 System.arraycopy(charAttributes, oldBase, | |
421 abuf, newScreenBase, | |
422 top); | |
423 } | |
424 | |
425 // copy anything from the topMargin up to the amount of lines inserted | |
426 // to the gap left over between scrollback buffer and screenBase | |
427 if (oldBase >= 0) { | |
428 System.arraycopy(charArray, oldBase + top, | |
429 cbuf, oldBase - offset, | |
430 n); | |
431 System.arraycopy(charAttributes, oldBase + top, | |
432 abuf, oldBase - offset, | |
433 n); | |
434 } | |
435 | |
436 // copy anything from topMargin + n up to the line linserted to the | |
437 // topMargin | |
438 System.arraycopy(charArray, oldBase + top + n, | |
439 cbuf, newScreenBase + top, | |
440 l - top - (n - 1)); | |
441 System.arraycopy(charAttributes, oldBase + top + n, | |
442 abuf, newScreenBase + top, | |
443 l - top - (n - 1)); | |
444 | |
445 // | |
446 // copy the all lines next to the inserted to the new buffer | |
447 if (l < height - 1) { | |
448 System.arraycopy(charArray, oldBase + l + 1, | |
449 cbuf, newScreenBase + l + 1, | |
450 (height - 1) - l); | |
451 System.arraycopy(charAttributes, oldBase + l + 1, | |
452 abuf, newScreenBase + l + 1, | |
453 (height - 1) - l); | |
454 } | |
455 } | |
456 catch (ArrayIndexOutOfBoundsException e) { | |
457 // this should not happen anymore, but I will leave the code | |
458 // here in case something happens anyway. That code above is | |
459 // so complex I always have a hard time understanding what | |
460 // I did, even though there are comments | |
461 System.err.println("*** Error while scrolling up:"); | |
462 System.err.println("--- BEGIN STACK TRACE ---"); | |
463 e.printStackTrace(); | |
464 System.err.println("--- END STACK TRACE ---"); | |
465 System.err.println("bufSize=" + bufSize + ", maxBufSize=" + maxBufSize); | |
466 System.err.println("top=" + top + ", bottom=" + bottom); | |
467 System.err.println("n=" + n + ", l=" + l); | |
468 System.err.println("screenBase=" + screenBase + ", windowBase=" + windowBase); | |
469 System.err.println("newScreenBase=" + newScreenBase + ", newWindowBase=" + newWindowBase); | |
470 System.err.println("oldBase=" + oldBase); | |
471 System.err.println("size.width=" + width + ", size.height=" + height); | |
472 System.err.println("abuf.length=" + abuf.length + ", cbuf.length=" + cbuf.length); | |
473 System.err.println("*** done dumping debug information"); | |
474 } | |
475 } | |
476 | |
477 // this is a little helper to mark the scrolling | |
478 scrollMarker -= n; | |
479 | |
480 for (int i = 0; i < n; i++) { | |
481 cbuf[(newScreenBase + l) + (scrollDown ? i : -i)] = new char[width]; | |
482 Arrays.fill(cbuf[(newScreenBase + l) + (scrollDown ? i : -i)], ' '); | |
483 abuf[(newScreenBase + l) + (scrollDown ? i : -i)] = new int[width]; | |
484 } | |
485 | |
486 charArray = cbuf; | |
487 charAttributes = abuf; | |
488 screenBase = newScreenBase; | |
489 windowBase = newWindowBase; | |
490 bufSize = newBufSize; | |
491 | |
492 if (scrollDown) | |
493 markLine(l, bottom - l + 1); | |
494 else | |
495 markLine(top, l - top + 1); | |
496 | |
497 display.updateScrollBar(); | |
498 } | |
499 | |
500 /** | |
501 * Delete a line at a specific position. Subsequent lines will be scrolled | |
502 * up to fill the space and a blank line is inserted at the end of the | |
503 * screen. | |
504 * @param l the y-coordinate to insert the line | |
505 * @see #deleteLine | |
506 */ | |
507 public void deleteLine(int l) { | |
508 int bottom = (l > bottomMargin ? height - 1 : | |
509 (l < topMargin ? topMargin : bottomMargin + 1)); | |
510 int numRows = bottom - l - 1; | |
511 char[] discardedChars = charArray[screenBase + l]; | |
512 int[] discardedAttributes = charAttributes[screenBase + l]; | |
513 | |
514 if (numRows > 0) { | |
515 System.arraycopy(charArray, screenBase + l + 1, | |
516 charArray, screenBase + l, numRows); | |
517 System.arraycopy(charAttributes, screenBase + l + 1, | |
518 charAttributes, screenBase + l, numRows); | |
519 } | |
520 | |
521 int newBottomRow = screenBase + bottom - 1; | |
522 charArray[newBottomRow] = discardedChars; | |
523 charAttributes[newBottomRow] = discardedAttributes; | |
524 Arrays.fill(charArray[newBottomRow], ' '); | |
525 Arrays.fill(charAttributes[newBottomRow], 0); | |
526 markLine(l, bottom - l); | |
527 } | |
528 | |
529 /** | |
530 * Delete a rectangular portion of the screen. | |
531 * You need to call redraw() to update the screen. | |
532 * @param c x-coordinate (column) | |
533 * @param l y-coordinate (row) | |
534 * @param w with of the area in characters | |
535 * @param h height of the area in characters | |
536 * @param curAttr attribute to fill | |
537 * @see #deleteChar | |
538 * @see #deleteLine | |
539 * @see #redraw | |
540 */ | |
541 public void deleteArea(int c, int l, int w, int h, int curAttr) { | |
542 int endColumn = c + w; | |
543 int targetRow = screenBase + l; | |
544 | |
545 for (int i = 0; i < h && l + i < height; i++) { | |
546 Arrays.fill(charAttributes[targetRow], c, endColumn, curAttr); | |
547 Arrays.fill(charArray[targetRow], c, endColumn, ' '); | |
548 targetRow++; | |
549 } | |
550 | |
551 markLine(l, h); | |
552 } | |
553 | |
554 /** | |
555 * Delete a rectangular portion of the screen. | |
556 * You need to call redraw() to update the screen. | |
557 * @param c x-coordinate (column) | |
558 * @param l y-coordinate (row) | |
559 * @param w with of the area in characters | |
560 * @param h height of the area in characters | |
561 * @see #deleteChar | |
562 * @see #deleteLine | |
563 * @see #redraw | |
564 */ | |
565 public void deleteArea(int c, int l, int w, int h) { | |
566 deleteArea(c, l, w, h, 0); | |
567 } | |
568 | |
569 /** | |
570 * Sets whether the cursor is visible or not. | |
571 * @param doshow | |
572 */ | |
573 public void showCursor(boolean doshow) { | |
574 showcursor = doshow; | |
575 } | |
576 | |
577 /** | |
578 * Check whether the cursor is currently visible. | |
579 * @return visibility | |
580 */ | |
581 public boolean isCursorVisible() { | |
582 return showcursor; | |
583 } | |
584 | |
585 /** | |
586 * Puts the cursor at the specified position. | |
587 * @param c column | |
588 * @param l line | |
589 */ | |
590 public void setCursorPosition(int c, int l) { | |
125
6eab98e58bed
add more 5250 config items
Carl Byington <carl@five-ten-sg.com>
parents:
123
diff
changeset
|
591 cursorX = (c > width-1) ? width-1 : c; |
6eab98e58bed
add more 5250 config items
Carl Byington <carl@five-ten-sg.com>
parents:
123
diff
changeset
|
592 cursorY = (l > height-1) ? height-1 : l; |
0 | 593 } |
594 | |
595 /** | |
596 * Get the current column of the cursor position. | |
597 */ | |
598 public int getCursorColumn() { | |
599 return cursorX; | |
600 } | |
601 | |
602 /** | |
603 * Get the current line of the cursor position. | |
604 */ | |
605 public int getCursorRow() { | |
606 return cursorY; | |
607 } | |
608 | |
609 /** | |
610 * Set the current window base. This allows to view the scrollback buffer. | |
611 * @param line the line where the screen window starts | |
612 * @see #setBufferSize | |
613 * @see #getBufferSize | |
614 */ | |
615 public void setWindowBase(int line) { | |
616 if (line > screenBase) | |
617 line = screenBase; | |
618 else if (line < 0) line = 0; | |
619 | |
620 windowBase = line; | |
621 update[0] = true; | |
622 redraw(); | |
623 } | |
624 | |
625 /** | |
626 * Get the current window base. | |
627 * @see #setWindowBase | |
628 */ | |
629 public int getWindowBase() { | |
630 return windowBase; | |
631 } | |
632 | |
633 /** | |
634 * Set the scroll margins simultaneously. If they're out of bounds, trim them. | |
635 * @param l1 line that is the top | |
636 * @param l2 line that is the bottom | |
637 */ | |
638 public void setMargins(int l1, int l2) { | |
639 if (l1 > l2) | |
640 return; | |
641 | |
642 if (l1 < 0) | |
643 l1 = 0; | |
644 | |
645 if (l2 >= height) | |
646 l2 = height - 1; | |
647 | |
648 topMargin = l1; | |
649 bottomMargin = l2; | |
650 } | |
651 | |
652 /** | |
653 * Set the top scroll margin for the screen. If the current bottom margin | |
654 * is smaller it will become the top margin and the line will become the | |
655 * bottom margin. | |
656 * @param l line that is the margin | |
657 */ | |
658 public void setTopMargin(int l) { | |
659 if (l > bottomMargin) { | |
660 topMargin = bottomMargin; | |
661 bottomMargin = l; | |
662 } | |
663 else | |
664 topMargin = l; | |
665 | |
666 if (topMargin < 0) topMargin = 0; | |
667 | |
668 if (bottomMargin >= height) bottomMargin = height - 1; | |
669 } | |
670 | |
671 /** | |
672 * Get the top scroll margin. | |
673 */ | |
674 public int getTopMargin() { | |
675 return topMargin; | |
676 } | |
677 | |
678 /** | |
679 * Set the bottom scroll margin for the screen. If the current top margin | |
680 * is bigger it will become the bottom margin and the line will become the | |
681 * top margin. | |
682 * @param l line that is the margin | |
683 */ | |
684 public void setBottomMargin(int l) { | |
685 if (l < topMargin) { | |
686 bottomMargin = topMargin; | |
687 topMargin = l; | |
688 } | |
689 else | |
690 bottomMargin = l; | |
691 | |
692 if (topMargin < 0) topMargin = 0; | |
693 | |
694 if (bottomMargin >= height) bottomMargin = height - 1; | |
695 } | |
696 | |
697 /** | |
698 * Get the bottom scroll margin. | |
699 */ | |
700 public int getBottomMargin() { | |
701 return bottomMargin; | |
702 } | |
703 | |
704 /** | |
705 * Set scrollback buffer size. | |
706 * @param amount new size of the buffer | |
707 */ | |
708 public void setBufferSize(int amount) { | |
709 if (amount < height) amount = height; | |
710 | |
711 if (amount < maxBufSize) { | |
712 char cbuf[][] = new char[amount][width]; | |
713 int abuf[][] = new int[amount][width]; | |
714 int copyStart = bufSize - amount < 0 ? 0 : bufSize - amount; | |
715 int copyCount = bufSize - amount < 0 ? bufSize : amount; | |
716 | |
717 if (charArray != null) | |
718 System.arraycopy(charArray, copyStart, cbuf, 0, copyCount); | |
719 | |
720 if (charAttributes != null) | |
721 System.arraycopy(charAttributes, copyStart, abuf, 0, copyCount); | |
722 | |
723 charArray = cbuf; | |
724 charAttributes = abuf; | |
725 bufSize = copyCount; | |
726 screenBase = bufSize - height; | |
727 windowBase = screenBase; | |
728 } | |
729 | |
730 maxBufSize = amount; | |
731 update[0] = true; | |
732 redraw(); | |
733 } | |
734 | |
735 /** | |
736 * Retrieve current scrollback buffer size. | |
737 * @see #setBufferSize | |
738 */ | |
739 public int getBufferSize() { | |
740 return bufSize; | |
741 } | |
742 | |
743 /** | |
744 * Retrieve maximum buffer Size. | |
745 * @see #getBufferSize | |
746 */ | |
747 public int getMaxBufferSize() { | |
748 return maxBufSize; | |
749 } | |
750 | |
751 /** | |
752 * Change the size of the screen. This will include adjustment of the | |
753 * scrollback buffer. | |
754 * @param w of the screen | |
755 * @param h of the screen | |
756 */ | |
757 public void setScreenSize(int w, int h, boolean broadcast) { | |
758 char cbuf[][]; | |
759 int abuf[][]; | |
760 int maxSize = bufSize; | |
761 | |
762 if (w < 1 || h < 1) return; | |
763 | |
764 if (debug > 0) | |
765 System.err.println("VDU: screen size [" + w + "," + h + "]"); | |
766 | |
767 if (h > maxBufSize) | |
768 maxBufSize = h; | |
769 | |
770 if (h > bufSize) { | |
771 bufSize = h; | |
772 screenBase = 0; | |
773 windowBase = 0; | |
774 } | |
775 | |
776 if (windowBase + h >= bufSize) | |
777 windowBase = bufSize - h; | |
778 | |
779 if (screenBase + h >= bufSize) | |
780 screenBase = bufSize - h; | |
781 | |
782 cbuf = new char[bufSize][w]; | |
783 abuf = new int[bufSize][w]; | |
784 | |
785 for (int i = 0; i < bufSize; i++) { | |
786 Arrays.fill(cbuf[i], ' '); | |
787 } | |
788 | |
789 if (bufSize < maxSize) | |
790 maxSize = bufSize; | |
791 | |
792 int rowLength; | |
793 | |
794 if (charArray != null && charAttributes != null) { | |
795 for (int i = 0; i < maxSize && charArray[i] != null; i++) { | |
796 rowLength = charArray[i].length; | |
797 System.arraycopy(charArray[i], 0, cbuf[i], 0, | |
798 w < rowLength ? w : rowLength); | |
799 System.arraycopy(charAttributes[i], 0, abuf[i], 0, | |
800 w < rowLength ? w : rowLength); | |
801 } | |
802 } | |
803 | |
804 int C = getCursorColumn(); | |
805 | |
806 if (C < 0) | |
807 C = 0; | |
808 else if (C >= width) | |
809 C = width - 1; | |
810 | |
811 int R = getCursorRow(); | |
812 | |
813 if (R < 0) | |
814 R = 0; | |
815 else if (R >= height) | |
816 R = height - 1; | |
817 | |
818 setCursorPosition(C, R); | |
819 charArray = cbuf; | |
820 charAttributes = abuf; | |
821 width = w; | |
822 height = h; | |
823 topMargin = 0; | |
824 bottomMargin = h - 1; | |
825 update = new boolean[h + 1]; | |
826 update[0] = true; | |
827 /* FIXME: ??? | |
828 if(resizeStrategy == RESIZE_FONT) | |
829 setBounds(getBounds()); | |
830 */ | |
831 } | |
832 | |
833 /** | |
834 * Get amount of rows on the screen. | |
835 */ | |
836 public int getRows() { | |
837 return height; | |
838 } | |
839 | |
840 /** | |
841 * Get amount of columns on the screen. | |
842 */ | |
843 public int getColumns() { | |
844 return width; | |
845 } | |
846 | |
847 /** | |
848 * Mark lines to be updated with redraw(). | |
849 * @param l starting line | |
850 * @param n amount of lines to be updated | |
851 * @see #redraw | |
852 */ | |
853 public void markLine(int l, int n) { | |
854 for (int i = 0; (i < n) && (l + i < height); i++) | |
855 update[l + i + 1] = true; | |
856 } | |
857 | |
858 // private static int checkBounds(int value, int lower, int upper) { | |
859 // if (value < lower) | |
860 // return lower; | |
861 // else if (value > upper) | |
862 // return upper; | |
863 // else | |
864 // return value; | |
865 // } | |
866 | |
867 public void setDisplay(VDUDisplay display) { | |
868 this.display = display; | |
869 } | |
870 | |
871 /** | |
872 * Trigger a redraw on the display. | |
873 */ | |
874 protected void redraw() { | |
875 if (display != null) | |
876 display.redraw(); | |
877 } | |
878 } |