comparison app/src/main/java/de/mud/terminal/VDUBuffer.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/de/mud/terminal/VDUBuffer.java@071eccdff8ea
children
comparison
equal deleted inserted replaced
437:208b31032318 438:d29cce60f393
1 /*
2 * This file is part of "JTA - Telnet/SSH for the JAVA(tm) platform".
3 *
4 * (c) Matthias L. Jugel, Marcus Meißner 1996-2005. All Rights Reserved.
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
40 /** a generic display that should redraw on demand */
41 protected VDUDisplay display;
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 */
102 public final static int COLOR = 0x7fffe0; /* 0000 0000 0111 1111 1111 1111 1110 0000 */
103 /** foreground color mask */
104 public final static int COLOR_FG = 0x003fe0; /* 0000 0000 0000 0000 0011 1111 1110 0000 */
105 /** background color mask */
106 public final static int COLOR_BG = 0x7fc000; /* 0000 0000 0111 1111 1100 0000 0000 0000 */
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) {
161 int ll = screenBase + l;
162
163 if ((ll >= bufSize) || (c >= width)) return; // ignore characters outside our buffer
164
165 charArray[ll][c] = ch;
166 charAttributes[ll][c] = attributes;
167
168 if (l < height)
169 update[l + 1] = true;
170 }
171
172 /**
173 * Get the character at the specified position.
174 * @param c x-coordinate (column)
175 * @param l y-coordinate (line)
176 * @see #putChar
177 */
178 public char getChar(int c, int l) {
179 return charArray[screenBase + l][c];
180 }
181
182 /**
183 * Get the attributes for the specified position.
184 * @param c x-coordinate (column)
185 * @param l y-coordinate (line)
186 * @see #putChar
187 */
188 public int getAttributes(int c, int l) {
189 return charAttributes[screenBase + l][c];
190 }
191
192 /**
193 * Insert a character at a specific position on the screen.
194 * All character right to from this position will be moved one to the right.
195 * You need to call redraw() to update the screen.
196 * @param c x-coordinate (column)
197 * @param l y-coordinate (line)
198 * @param ch the character to insert
199 * @param attributes the character attributes
200 * @see #BOLD
201 * @see #UNDERLINE
202 * @see #INVERT
203 * @see #INVISIBLE
204 * @see #NORMAL
205 * @see #LOW
206 * @see #putChar
207 * @see #deleteChar
208 * @see #redraw
209 */
210 public void insertChar(int c, int l, char ch, int attributes) {
211 System.arraycopy(charArray[screenBase + l], c,
212 charArray[screenBase + l], c + 1, width - c - 1);
213 System.arraycopy(charAttributes[screenBase + l], c,
214 charAttributes[screenBase + l], c + 1, width - c - 1);
215 putChar(c, l, ch, attributes);
216 }
217
218 /**
219 * Delete a character at a given position on the screen.
220 * All characters right to the position will be moved one to the left.
221 * You need to call redraw() to update the screen.
222 * @param c x-coordinate (column)
223 * @param l y-coordinate (line)
224 * @see #putChar
225 * @see #insertChar
226 * @see #redraw
227 */
228 public void deleteChar(int c, int l) {
229 if (c < width - 1) {
230 System.arraycopy(charArray[screenBase + l], c + 1,
231 charArray[screenBase + l], c, width - c - 1);
232 System.arraycopy(charAttributes[screenBase + l], c + 1,
233 charAttributes[screenBase + l], c, width - c - 1);
234 }
235
236 putChar(width - 1, l, (char) 0);
237 }
238
239 /**
240 * Put a String at a specific position. Any characters previously on that
241 * position will be overwritten. You need to call redraw() for screen update.
242 * @param c x-coordinate (column)
243 * @param l y-coordinate (line)
244 * @param s the string to be shown on the screen
245 * @see #BOLD
246 * @see #UNDERLINE
247 * @see #INVERT
248 * @see #INVISIBLE
249 * @see #NORMAL
250 * @see #LOW
251 * @see #putChar
252 * @see #insertLine
253 * @see #deleteLine
254 * @see #redraw
255 */
256 public void putString(int c, int l, String s) {
257 putString(c, l, s, NORMAL);
258 }
259
260 /**
261 * Put a String at a specific position giving all characters the same
262 * attributes. Any characters previously on that position will be
263 * overwritten. You need to call redraw() to update the screen.
264 * @param c x-coordinate (column)
265 * @param l y-coordinate (line)
266 * @param s the string to be shown on the screen
267 * @param attributes character attributes
268 * @see #BOLD
269 * @see #UNDERLINE
270 * @see #INVERT
271 * @see #INVISIBLE
272 * @see #NORMAL
273 * @see #LOW
274 * @see #putChar
275 * @see #insertLine
276 * @see #deleteLine
277 * @see #redraw
278 */
279 public void putString(int c, int l, String s, int attributes) {
280 for (int i = 0; i < s.length() && c + i < width; i++)
281 putChar(c + i, l, s.charAt(i), attributes);
282 }
283
284 /**
285 * Insert a blank line at a specific position.
286 * The current line and all previous lines are scrolled one line up. The
287 * top line is lost. You need to call redraw() to update the screen.
288 * @param l the y-coordinate to insert the line
289 * @see #deleteLine
290 * @see #redraw
291 */
292 public void insertLine(int l) {
293 insertLine(l, 1, SCROLL_UP);
294 }
295
296 /**
297 * Insert blank lines at a specific position.
298 * You need to call redraw() to update the screen
299 * @param l the y-coordinate to insert the line
300 * @param n amount of lines to be inserted
301 * @see #deleteLine
302 * @see #redraw
303 */
304 public void insertLine(int l, int n) {
305 insertLine(l, n, SCROLL_UP);
306 }
307
308 /**
309 * Insert a blank line at a specific position. Scroll text according to
310 * the argument.
311 * You need to call redraw() to update the screen
312 * @param l the y-coordinate to insert the line
313 * @param scrollDown scroll down
314 * @see #deleteLine
315 * @see #SCROLL_UP
316 * @see #SCROLL_DOWN
317 * @see #redraw
318 */
319 public void insertLine(int l, boolean scrollDown) {
320 insertLine(l, 1, scrollDown);
321 }
322
323 /**
324 * Insert blank lines at a specific position.
325 * The current line and all previous lines are scrolled one line up. The
326 * top line is lost. You need to call redraw() to update the screen.
327 * @param l the y-coordinate to insert the line
328 * @param n number of lines to be inserted
329 * @param scrollDown scroll down
330 * @see #deleteLine
331 * @see #SCROLL_UP
332 * @see #SCROLL_DOWN
333 * @see #redraw
334 */
335
336 public synchronized void insertLine(int l, int n, boolean scrollDown) {
337 char cbuf[][] = null;
338 int abuf[][] = null;
339 int offset = 0;
340 int oldBase = screenBase;
341 int newScreenBase = screenBase;
342 int newWindowBase = windowBase;
343 int newBufSize = bufSize;
344
345 if (l > bottomMargin) /* We do not scroll below bottom margin (below the scrolling region). */
346 return;
347
348 int top = (l < topMargin ?
349 0 : (l > bottomMargin ?
350 (bottomMargin + 1 < height ?
351 bottomMargin + 1 : height - 1) : topMargin));
352 int bottom = (l > bottomMargin ?
353 height - 1 : (l < topMargin ?
354 (topMargin > 0 ?
355 topMargin - 1 : 0) : bottomMargin));
356
357 // System.out.println("l is "+l+", top is "+top+", bottom is "+bottom+", bottomargin is "+bottomMargin+", topMargin is "+topMargin);
358 if (scrollDown) {
359 if (n > (bottom - top)) n = (bottom - top);
360
361 int size = bottom - l - (n - 1);
362
363 if (size < 0) size = 0;
364
365 cbuf = new char[size][];
366 abuf = new int[size][];
367 System.arraycopy(charArray, oldBase + l, cbuf, 0, bottom - l - (n - 1));
368 System.arraycopy(charAttributes, oldBase + l,
369 abuf, 0, bottom - l - (n - 1));
370 System.arraycopy(cbuf, 0, charArray, oldBase + l + n,
371 bottom - l - (n - 1));
372 System.arraycopy(abuf, 0, charAttributes, oldBase + l + n,
373 bottom - l - (n - 1));
374 cbuf = charArray;
375 abuf = charAttributes;
376 }
377 else {
378 try {
379 if (n > (bottom - top) + 1) n = (bottom - top) + 1;
380
381 if (bufSize < maxBufSize) {
382 if (bufSize + n > maxBufSize) {
383 offset = n - (maxBufSize - bufSize);
384 scrollMarker += offset;
385 newBufSize = maxBufSize;
386 newScreenBase = maxBufSize - height - 1;
387 newWindowBase = screenBase;
388 }
389 else {
390 scrollMarker += n;
391 newScreenBase += n;
392 newWindowBase += n;
393 newBufSize += n;
394 }
395
396 cbuf = new char[newBufSize][];
397 abuf = new int[newBufSize][];
398 }
399 else {
400 offset = n;
401 cbuf = charArray;
402 abuf = charAttributes;
403 }
404
405 // copy anything from the top of the buffer (+offset) to the new top
406 // up to the screenBase.
407 if (oldBase > 0) {
408 System.arraycopy(charArray, offset,
409 cbuf, 0,
410 oldBase - offset);
411 System.arraycopy(charAttributes, offset,
412 abuf, 0,
413 oldBase - offset);
414 }
415
416 // copy anything from the top of the screen (screenBase) up to the
417 // topMargin to the new screen
418 if (top > 0) {
419 System.arraycopy(charArray, oldBase,
420 cbuf, newScreenBase,
421 top);
422 System.arraycopy(charAttributes, oldBase,
423 abuf, newScreenBase,
424 top);
425 }
426
427 // copy anything from the topMargin up to the amount of lines inserted
428 // to the gap left over between scrollback buffer and screenBase
429 if (oldBase >= 0) {
430 System.arraycopy(charArray, oldBase + top,
431 cbuf, oldBase - offset,
432 n);
433 System.arraycopy(charAttributes, oldBase + top,
434 abuf, oldBase - offset,
435 n);
436 }
437
438 // copy anything from topMargin + n up to the line linserted to the
439 // topMargin
440 System.arraycopy(charArray, oldBase + top + n,
441 cbuf, newScreenBase + top,
442 l - top - (n - 1));
443 System.arraycopy(charAttributes, oldBase + top + n,
444 abuf, newScreenBase + top,
445 l - top - (n - 1));
446
447 //
448 // copy the all lines next to the inserted to the new buffer
449 if (l < height - 1) {
450 System.arraycopy(charArray, oldBase + l + 1,
451 cbuf, newScreenBase + l + 1,
452 (height - 1) - l);
453 System.arraycopy(charAttributes, oldBase + l + 1,
454 abuf, newScreenBase + l + 1,
455 (height - 1) - l);
456 }
457 }
458 catch (ArrayIndexOutOfBoundsException e) {
459 // this should not happen anymore, but I will leave the code
460 // here in case something happens anyway. That code above is
461 // so complex I always have a hard time understanding what
462 // I did, even though there are comments
463 System.err.println("*** Error while scrolling up:");
464 System.err.println("--- BEGIN STACK TRACE ---");
465 e.printStackTrace();
466 System.err.println("--- END STACK TRACE ---");
467 System.err.println("bufSize=" + bufSize + ", maxBufSize=" + maxBufSize);
468 System.err.println("top=" + top + ", bottom=" + bottom);
469 System.err.println("n=" + n + ", l=" + l);
470 System.err.println("screenBase=" + screenBase + ", windowBase=" + windowBase);
471 System.err.println("newScreenBase=" + newScreenBase + ", newWindowBase=" + newWindowBase);
472 System.err.println("oldBase=" + oldBase);
473 System.err.println("size.width=" + width + ", size.height=" + height);
474 System.err.println("abuf.length=" + abuf.length + ", cbuf.length=" + cbuf.length);
475 System.err.println("*** done dumping debug information");
476 }
477 }
478
479 // this is a little helper to mark the scrolling
480 scrollMarker -= n;
481
482 for (int i = 0; i < n; i++) {
483 cbuf[(newScreenBase + l) + (scrollDown ? i : -i)] = new char[width];
484 Arrays.fill(cbuf[(newScreenBase + l) + (scrollDown ? i : -i)], ' ');
485 abuf[(newScreenBase + l) + (scrollDown ? i : -i)] = new int[width];
486 }
487
488 charArray = cbuf;
489 charAttributes = abuf;
490 screenBase = newScreenBase;
491 windowBase = newWindowBase;
492 bufSize = newBufSize;
493
494 if (scrollDown)
495 markLine(l, bottom - l + 1);
496 else
497 markLine(top, l - top + 1);
498
499 display.updateScrollBar();
500 }
501
502 /**
503 * Delete a line at a specific position. Subsequent lines will be scrolled
504 * up to fill the space and a blank line is inserted at the end of the
505 * screen.
506 * @param l the y-coordinate to insert the line
507 * @see #deleteLine
508 */
509 public void deleteLine(int l) {
510 int bottom = (l > bottomMargin ? height - 1 :
511 (l < topMargin ? topMargin : bottomMargin + 1));
512 int numRows = bottom - l - 1;
513 char[] discardedChars = charArray[screenBase + l];
514 int[] discardedAttributes = charAttributes[screenBase + l];
515
516 if (numRows > 0) {
517 System.arraycopy(charArray, screenBase + l + 1,
518 charArray, screenBase + l, numRows);
519 System.arraycopy(charAttributes, screenBase + l + 1,
520 charAttributes, screenBase + l, numRows);
521 }
522
523 int newBottomRow = screenBase + bottom - 1;
524 charArray[newBottomRow] = discardedChars;
525 charAttributes[newBottomRow] = discardedAttributes;
526 Arrays.fill(charArray[newBottomRow], ' ');
527 Arrays.fill(charAttributes[newBottomRow], 0);
528 markLine(l, bottom - l);
529 }
530
531 /**
532 * Delete a rectangular portion of the screen.
533 * You need to call redraw() to update the screen.
534 * @param c x-coordinate (column)
535 * @param l y-coordinate (row)
536 * @param w with of the area in characters
537 * @param h height of the area in characters
538 * @param curAttr attribute to fill
539 * @see #deleteChar
540 * @see #deleteLine
541 * @see #redraw
542 */
543 public void deleteArea(int c, int l, int w, int h, int curAttr) {
544 int endColumn = c + w;
545 int targetRow = screenBase + l;
546
547 for (int i = 0; i < h && l + i < height; i++) {
548 Arrays.fill(charAttributes[targetRow], c, endColumn, curAttr);
549 Arrays.fill(charArray[targetRow], c, endColumn, ' ');
550 targetRow++;
551 }
552
553 markLine(l, h);
554 }
555
556 /**
557 * Delete a rectangular portion of the screen.
558 * You need to call redraw() to update the screen.
559 * @param c x-coordinate (column)
560 * @param l y-coordinate (row)
561 * @param w with of the area in characters
562 * @param h height of the area in characters
563 * @see #deleteChar
564 * @see #deleteLine
565 * @see #redraw
566 */
567 public void deleteArea(int c, int l, int w, int h) {
568 deleteArea(c, l, w, h, 0);
569 }
570
571 /**
572 * Sets whether the cursor is visible or not.
573 * @param doshow
574 */
575 public void showCursor(boolean doshow) {
576 showcursor = doshow;
577 }
578
579 /**
580 * Check whether the cursor is currently visible.
581 * @return visibility
582 */
583 public boolean isCursorVisible() {
584 return showcursor;
585 }
586
587 /**
588 * Puts the cursor at the specified position.
589 * @param c column
590 * @param l line
591 */
592 public void setCursorPosition(int c, int l) {
593 cursorX = (c > width - 1) ? width - 1 : c;
594 cursorY = (l > height - 1) ? height - 1 : l;
595 }
596
597 /**
598 * Get the current column of the cursor position.
599 */
600 public int getCursorColumn() {
601 return cursorX;
602 }
603
604 /**
605 * Get the current line of the cursor position.
606 */
607 public int getCursorRow() {
608 return cursorY;
609 }
610
611 /**
612 * Set the current window base. This allows to view the scrollback buffer.
613 * @param line the line where the screen window starts
614 * @see #setBufferSize
615 * @see #getBufferSize
616 */
617 public void setWindowBase(int line) {
618 if (line > screenBase)
619 line = screenBase;
620 else if (line < 0) line = 0;
621
622 windowBase = line;
623 update[0] = true;
624 redraw();
625 }
626
627 /**
628 * Get the current window base.
629 * @see #setWindowBase
630 */
631 public int getWindowBase() {
632 return windowBase;
633 }
634
635 /**
636 * Set the scroll margins simultaneously. If they're out of bounds, trim them.
637 * @param l1 line that is the top
638 * @param l2 line that is the bottom
639 */
640 public void setMargins(int l1, int l2) {
641 if (l1 > l2)
642 return;
643
644 if (l1 < 0)
645 l1 = 0;
646
647 if (l2 >= height)
648 l2 = height - 1;
649
650 topMargin = l1;
651 bottomMargin = l2;
652 }
653
654 /**
655 * Set the top scroll margin for the screen. If the current bottom margin
656 * is smaller it will become the top margin and the line will become the
657 * bottom margin.
658 * @param l line that is the margin
659 */
660 public void setTopMargin(int l) {
661 if (l > bottomMargin) {
662 topMargin = bottomMargin;
663 bottomMargin = l;
664 }
665 else
666 topMargin = l;
667
668 if (topMargin < 0) topMargin = 0;
669
670 if (bottomMargin >= height) bottomMargin = height - 1;
671 }
672
673 /**
674 * Get the top scroll margin.
675 */
676 public int getTopMargin() {
677 return topMargin;
678 }
679
680 /**
681 * Set the bottom scroll margin for the screen. If the current top margin
682 * is bigger it will become the bottom margin and the line will become the
683 * top margin.
684 * @param l line that is the margin
685 */
686 public void setBottomMargin(int l) {
687 if (l < topMargin) {
688 bottomMargin = topMargin;
689 topMargin = l;
690 }
691 else
692 bottomMargin = l;
693
694 if (topMargin < 0) topMargin = 0;
695
696 if (bottomMargin >= height) bottomMargin = height - 1;
697 }
698
699 /**
700 * Get the bottom scroll margin.
701 */
702 public int getBottomMargin() {
703 return bottomMargin;
704 }
705
706 /**
707 * Set scrollback buffer size.
708 * @param amount new size of the buffer
709 */
710 public void setBufferSize(int amount) {
711 if (amount < height) amount = height;
712
713 if (amount < maxBufSize) {
714 char cbuf[][] = new char[amount][width];
715 int abuf[][] = new int[amount][width];
716 int copyStart = bufSize - amount < 0 ? 0 : bufSize - amount;
717 int copyCount = bufSize - amount < 0 ? bufSize : amount;
718
719 if (charArray != null)
720 System.arraycopy(charArray, copyStart, cbuf, 0, copyCount);
721
722 if (charAttributes != null)
723 System.arraycopy(charAttributes, copyStart, abuf, 0, copyCount);
724
725 charArray = cbuf;
726 charAttributes = abuf;
727 bufSize = copyCount;
728 screenBase = bufSize - height;
729 windowBase = screenBase;
730 }
731
732 maxBufSize = amount;
733 update[0] = true;
734 redraw();
735 }
736
737 /**
738 * Retrieve current scrollback buffer size.
739 * @see #setBufferSize
740 */
741 public int getBufferSize() {
742 return bufSize;
743 }
744
745 /**
746 * Retrieve maximum buffer Size.
747 * @see #getBufferSize
748 */
749 public int getMaxBufferSize() {
750 return maxBufSize;
751 }
752
753 /**
754 * Change the size of the screen. This will include adjustment of the
755 * scrollback buffer.
756 * @param w of the screen
757 * @param h of the screen
758 */
759 public void setScreenSize(int w, int h, boolean broadcast) {
760 char cbuf[][];
761 int abuf[][];
762 int maxSize = bufSize;
763
764 if (w < 1 || h < 1) return;
765
766 if (debug > 0)
767 System.err.println("VDU: screen size [" + w + "," + h + "]");
768
769 if (h > maxBufSize)
770 maxBufSize = h;
771
772 if (h > bufSize) {
773 bufSize = h;
774 screenBase = 0;
775 windowBase = 0;
776 }
777
778 if (windowBase + h >= bufSize)
779 windowBase = bufSize - h;
780
781 if (screenBase + h >= bufSize)
782 screenBase = bufSize - h;
783
784 cbuf = new char[bufSize][w];
785 abuf = new int[bufSize][w];
786
787 for (int i = 0; i < bufSize; i++) {
788 Arrays.fill(cbuf[i], ' ');
789 }
790
791 if (bufSize < maxSize)
792 maxSize = bufSize;
793
794 int rowLength;
795
796 if (charArray != null && charAttributes != null) {
797 for (int i = 0; i < maxSize && charArray[i] != null; i++) {
798 rowLength = charArray[i].length;
799 System.arraycopy(charArray[i], 0, cbuf[i], 0,
800 w < rowLength ? w : rowLength);
801 System.arraycopy(charAttributes[i], 0, abuf[i], 0,
802 w < rowLength ? w : rowLength);
803 }
804 }
805
806 int C = getCursorColumn();
807
808 if (C < 0)
809 C = 0;
810 else if (C >= width)
811 C = width - 1;
812
813 int R = getCursorRow();
814
815 if (R < 0)
816 R = 0;
817 else if (R >= height)
818 R = height - 1;
819
820 setCursorPosition(C, R);
821 charArray = cbuf;
822 charAttributes = abuf;
823 width = w;
824 height = h;
825 topMargin = 0;
826 bottomMargin = h - 1;
827 update = new boolean[h + 1];
828 update[0] = true;
829 /* FIXME: ???
830 if(resizeStrategy == RESIZE_FONT)
831 setBounds(getBounds());
832 */
833 }
834
835 /**
836 * Get amount of rows on the screen.
837 */
838 public int getRows() {
839 return height;
840 }
841
842 /**
843 * Get amount of columns on the screen.
844 */
845 public int getColumns() {
846 return width;
847 }
848
849 /**
850 * Mark lines to be updated with redraw().
851 * @param l starting line
852 * @param n amount of lines to be updated
853 * @see #redraw
854 */
855 public void markLine(int l, int n) {
856 for (int i = 0; (i < n) && (l + i < height); i++)
857 update[l + i + 1] = true;
858 }
859
860 // private static int checkBounds(int value, int lower, int upper) {
861 // if (value < lower)
862 // return lower;
863 // else if (value > upper)
864 // return upper;
865 // else
866 // return value;
867 // }
868
869 public void setDisplay(VDUDisplay display) {
870 this.display = display;
871 }
872
873 /**
874 * Trigger a redraw on the display.
875 */
876 protected void redraw() {
877 if (display != null)
878 display.redraw();
879 }
880 }