2
* $Xorg: screen.c,v 1.3 2000/08/17 19:55:09 cpqbld Exp $
6
* Copyright 1999-2000,2002 by Thomas E. Dickey
10
* Permission is hereby granted, free of charge, to any person obtaining a
11
* copy of this software and associated documentation files (the
12
* "Software"), to deal in the Software without restriction, including
13
* without limitation the rights to use, copy, modify, merge, publish,
14
* distribute, sublicense, and/or sell copies of the Software, and to
15
* permit persons to whom the Software is furnished to do so, subject to
16
* the following conditions:
18
* The above copyright notice and this permission notice shall be included
19
* in all copies or substantial portions of the Software.
21
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24
* IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
25
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
* Except as contained in this notice, the name(s) of the above copyright
30
* holders shall not be used in advertising or otherwise to promote the
31
* sale, use or other dealings in this Software without prior written
35
* Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
39
* Permission to use, copy, modify, and distribute this software and its
40
* documentation for any purpose and without fee is hereby granted,
41
* provided that the above copyright notice appear in all copies and that
42
* both that copyright notice and this permission notice appear in
43
* supporting documentation, and that the name of Digital Equipment
44
* Corporation not be used in advertising or publicity pertaining to
45
* distribution of the software without specific, written prior permission.
48
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
49
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
50
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
51
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
52
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
53
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
57
/* $XFree86: xc/programs/xterm/screen.c,v 3.60 2002/12/27 21:05:23 dickey Exp $ */
65
#include <xcharmouse.h>
71
* Allocates memory for a 2-dimensional array of chars and returns a pointer
72
* thereto. Each line is formed from a set of char arrays, with an index
73
* (i.e., the ScrnBuf type). The first pointer in the index is reserved for
74
* per-line flags, and does not point to data.
76
* After the per-line flags, we have a series of pointers to char arrays: The
77
* first one is the actual character array, the second one is the attributes,
78
* the third is the foreground and background colors, and the fourth denotes
81
* We store it all as pointers, because of alignment considerations, together
82
* with the intention of being able to change the total number of pointers per
83
* row according to whether the user wants color or not.
86
Allocate(int nrow, int ncol, Char ** addr)
91
size_t entries = MAX_PTRS * nrow;
92
size_t length = BUF_PTRS * nrow * ncol;
94
if ((base = (ScrnBuf) calloc(entries, sizeof(char *))) == 0)
95
SysError(ERROR_SCALLOC);
97
if ((tmp = (Char *) calloc(length, sizeof(Char))) == 0)
98
SysError(ERROR_SCALLOC2);
101
for (i = k = 0; i < nrow; i++) {
102
base[k] = 0; /* per-line flags */
104
for (j = BUF_HEAD; j < MAX_PTRS; j++) {
114
* This is called when the screen is resized.
115
* Returns the number of lines the text was moved down (neg for up).
116
* (Return value only necessary with SouthWestGravity.)
119
Reallocate(ScrnBuf * sbuf,
128
int i, j, k, minrows;
131
int move_down = 0, move_up = 0;
132
size_t entries = MAX_PTRS * nrow;
133
size_t length = BUF_PTRS * nrow * ncol;
135
if (sbuf == NULL || *sbuf == NULL) {
142
* Special case if oldcol == ncol - straight forward realloc and
143
* update of the additional lines in sbuf
145
* FIXME: this is a good idea, but doesn't seem to be implemented.
150
* realloc sbuf, the pointers to all the lines.
151
* If the screen shrinks, remove lines off the top of the buffer
152
* if resizeGravity resource says to do so.
155
&& term->misc.resizeGravity == SouthWestGravity) {
156
/* Remove lines off the top of the buffer if necessary. */
157
move_up = (oldrow - nrow)
158
- (term->screen.max_row - term->screen.cur_row);
161
/* Overlapping memmove here! */
162
memmove(*sbuf, *sbuf + (move_up * MAX_PTRS),
163
MAX_PTRS * (oldrow - move_up) * sizeof((*sbuf)[0]));
165
*sbuf = (ScrnBuf) realloc((char *) (*sbuf), entries * sizeof(char *));
167
SysError(ERROR_RESIZE);
171
* create the new buffer space and copy old buffer contents there
174
if ((tmp = (Char *) calloc(length, sizeof(Char))) == 0)
175
SysError(ERROR_SREALLOC);
177
minrows = (oldrow < nrow) ? oldrow : nrow;
178
mincols = (oldcol < ncol) ? oldcol : ncol;
180
&& term->misc.resizeGravity == SouthWestGravity) {
181
/* move data down to bottom of expanded screen */
182
move_down = Min(nrow - oldrow, term->screen.savedlines);
183
tmp += (ncol * move_down * BUF_PTRS);
186
for (i = k = 0; i < minrows; i++) {
188
for (j = BUF_HEAD; j < MAX_PTRS; j++) {
189
memcpy(tmp, base[k++], mincols);
195
* update the pointers in sbuf
197
for (i = k = 0, tmp = *sbufaddr; i < nrow; i++) {
198
for (j = 0; j < BUF_HEAD; j++)
200
for (j = BUF_HEAD; j < MAX_PTRS; j++) {
206
/* Now free the old buffer */
209
return move_down ? move_down : -move_up; /* convert to rows */
212
int last_written_row = -1;
213
int last_written_col = -1;
216
* Writes str into buf at screen's current row and column. Characters are set
220
ScreenWrite(TScreen * screen,
221
PAIRED_CHARS(Char * str, Char * str2),
224
int len) /* length of string */
237
int length = len; /* workaround for compiler bug? */
239
int avail = screen->max_col - screen->cur_col + 1;
243
Char starcol, starcol2;
244
Char *comb1l = 0, *comb1h = 0, *comb2l = 0, *comb2h = 0;
248
int real_width = visual_width(PAIRED_CHARS(str, str2), length);
250
int real_width = length;
258
col = SCRN_BUF_CHARS(screen, screen->cur_row) + screen->cur_col;
259
attrs = SCRN_BUF_ATTRS(screen, screen->cur_row) + screen->cur_col;
261
if_OPT_WIDE_CHARS(screen, {
262
comb1l = SCRN_BUF_COM1L(screen, screen->cur_row) + screen->cur_col;
263
comb1h = SCRN_BUF_COM1H(screen, screen->cur_row) + screen->cur_col;
264
comb2l = SCRN_BUF_COM2L(screen, screen->cur_row) + screen->cur_col;
265
comb2h = SCRN_BUF_COM2H(screen, screen->cur_row) + screen->cur_col;
268
if_OPT_EXT_COLORS(screen, {
269
fbf = SCRN_BUF_FGRND(screen, screen->cur_row) + screen->cur_col;
270
fbb = SCRN_BUF_BGRND(screen, screen->cur_row) + screen->cur_col;
272
if_OPT_ISO_TRADITIONAL_COLORS(screen, {
273
fb = SCRN_BUF_COLOR(screen, screen->cur_row) + screen->cur_col;
276
cb = SCRN_BUF_CSETS(screen, screen->cur_row) + screen->cur_col;
279
wrappedbit = ScrnTstWrapped(screen, screen->cur_row);
283
starcol2 = col[length - 1];
286
/* write blanks if we're writing invisible text */
287
if (flags & INVISIBLE) {
288
memset(col, ' ', length);
290
memcpy(col, str, length); /* This can stand for the present. If it
291
is wrong, we will scribble over it */
295
if_OPT_WIDE_CHARS(screen, {
299
if (real_width != length) {
301
wc = SCRN_BUF_WIDEC(screen, screen->cur_row);
302
wc += screen->cur_col;
303
if (screen->cur_col && starcol == HIDDEN_LO && *wc == HIDDEN_HI
304
&& iswide(c[-1] | (wc[-1] << 8))) {
308
/* if we are overwriting the right hand half of a
309
wide character, make the other half vanish */
337
&& c[-1] == HIDDEN_LO
338
&& wc[-1] == HIDDEN_HI) {
342
/* if we are overwriting the left hand half of a
343
wide character, make the other half vanish */
348
if ((wc = SCRN_BUF_WIDEC(screen, screen->cur_row)) != 0) {
349
wc += screen->cur_col;
350
if (screen->cur_col && starcol == HIDDEN_LO && *wc == HIDDEN_HI
351
&& iswide(col[-1] | (wc[-1] << 8))) {
355
/* if we are overwriting the right hand half of a
356
wide character, make the other half vanish */
357
if (col[length] == HIDDEN_LO && wc[length] == HIDDEN_HI &&
358
iswide(starcol2 | (wc[length - 1] << 8))) {
359
col[length] = ERROR_1;
360
wc[length] = ERROR_2;
362
/* if we are overwriting the left hand half of a
363
wide character, make the other half vanish */
364
if ((flags & INVISIBLE) || (str2 == 0))
365
memset(wc, 0, length);
367
memcpy(wc, str2, length);
374
memset(attrs, flags, real_width);
376
if_OPT_WIDE_CHARS(screen, {
377
memset(comb1l, 0, real_width);
378
memset(comb2l, 0, real_width);
379
memset(comb1h, 0, real_width);
380
memset(comb2h, 0, real_width);
382
if_OPT_EXT_COLORS(screen, {
383
memset(fbf, cur_fg_bg >> 8, real_width);
384
memset(fbb, cur_fg_bg & 0xff, real_width);
386
if_OPT_ISO_TRADITIONAL_COLORS(screen, {
387
memset(fb, cur_fg_bg, real_width);
390
memset(cb, curXtermChrSet(screen->cur_row), real_width);
394
ScrnSetWrapped(screen, screen->cur_row);
396
ScrnClrWrapped(screen, screen->cur_row);
398
last_written_col = screen->cur_col + real_width - 1;
399
last_written_row = screen->cur_row;
401
if_OPT_XMC_GLITCH(screen, {
407
* Saves pointers to the n lines beginning at sb + where, and clears the lines
410
ScrnClearLines(TScreen * screen, ScrnBuf sb, int where, int n, int size)
413
size_t len = ScrnPointers(screen, n);
414
int last = (n * MAX_PTRS);
416
/* save n lines at where */
417
memcpy((char *) screen->save_ptr,
418
(char *) &sb[MAX_PTRS * where],
421
/* clear contents of old rows */
422
if (TERM_COLOR_FLAGS) {
423
int flags = TERM_COLOR_FLAGS;
424
for (i = 0; i < last; i += MAX_PTRS) {
425
for (j = 0; j < MAX_PTRS; j++) {
427
screen->save_ptr[i + j] = 0;
428
else if (j == OFF_ATTRS)
429
memset(screen->save_ptr[i + j], flags, size);
432
else if (j == OFF_FGRND)
433
memset(screen->save_ptr[i + j], term->sgr_foreground, size);
434
else if (j == OFF_BGRND)
435
memset(screen->save_ptr[i + j], term->cur_background, size);
437
else if (j == OFF_COLOR)
438
memset(screen->save_ptr[i + j], xtermColorPair(), size);
442
bzero(screen->save_ptr[i + j], size);
446
for (i = 0; i < last; i += MAX_PTRS) {
447
for (j = 0; j < BUF_HEAD; j++)
448
screen->save_ptr[i + j] = 0;
449
for (j = BUF_HEAD; j < MAX_PTRS; j++)
450
bzero(screen->save_ptr[i + j], size);
456
ScrnPointers(TScreen * screen, size_t len)
458
len *= (MAX_PTRS * sizeof(Char *));
460
if (len > screen->save_len) {
461
if (screen->save_len)
462
screen->save_ptr = (Char **) realloc(screen->save_ptr, len);
464
screen->save_ptr = (Char **) malloc(len);
465
screen->save_len = len;
466
if (screen->save_ptr == 0)
467
SysError(ERROR_SAVE_PTR);
473
* Inserts n blank lines at sb + where, treating last as a bottom margin.
474
* Size is the size of each entry in sb.
475
* Requires: 0 <= where < where + n <= last
478
ScrnInsertLine(TScreen * screen, ScrnBuf sb, int last, int where, int n, int size)
480
size_t len = ScrnPointers(screen, n);
482
/* save n lines at bottom */
483
ScrnClearLines(screen, sb, (last -= n - 1), n, size);
486
* WARNING, overlapping copy operation. Move down lines (pointers).
488
* +----|---------|--------+
490
* is copied in the array to:
492
* +--------|---------|----+
494
memmove((char *) &sb[MAX_PTRS * (where + n)],
495
(char *) &sb[MAX_PTRS * where],
496
MAX_PTRS * sizeof(char *) * (last - where));
498
/* reuse storage for new lines at where */
499
memcpy((char *) &sb[MAX_PTRS * where],
500
(char *) screen->save_ptr,
505
* Deletes n lines at sb + where, treating last as a bottom margin.
506
* Size is the size of each entry in sb.
507
* Requires 0 <= where < where + n < = last
510
ScrnDeleteLine(TScreen * screen, ScrnBuf sb, int last, int where, int n, int size)
512
ScrnClearLines(screen, sb, where, n, size);
515
memmove((char *) &sb[MAX_PTRS * where],
516
(char *) &sb[MAX_PTRS * (where + n)],
517
MAX_PTRS * sizeof(char *) * ((last -= n - 1) - where));
519
/* reuse storage for new bottom lines */
520
memcpy((char *) &sb[MAX_PTRS * last],
521
(char *) screen->save_ptr,
522
MAX_PTRS * sizeof(char *) * n);
526
* Inserts n blanks in screen at current row, col. Size is the size of each
530
ScrnInsertChar(TScreen * screen, int n)
532
ScrnBuf sb = screen->visbuf;
533
int size = screen->max_col + 1;
534
int row = screen->cur_row;
535
int col = screen->cur_col;
537
Char *ptr = BUF_CHARS(sb, row);
538
Char *attrs = BUF_ATTRS(sb, row);
539
int wrappedbit = ScrnTstWrapped(screen, row);
540
int flags = CHARDRAWN | TERM_COLOR_FLAGS;
543
if (size - (col + n) <= 0) {
544
if ((n = size - col) <= 0) {
548
nbytes = (size - (col + n));
550
ScrnClrWrapped(screen, row); /* make sure the bit isn't moved */
551
for (i = size - 1; i >= col + n; i--) {
552
ptr[i] = ptr[j = i - n];
556
for (i = col; i < col + n; i++)
558
for (i = col; i < col + n; i++)
560
if_OPT_EXT_COLORS(screen, {
561
ptr = BUF_FGRND(sb, row);
562
memmove(ptr + col + n, ptr + col, nbytes);
563
memset(ptr + col, term->sgr_foreground, n);
564
ptr = BUF_BGRND(sb, row);
565
memmove(ptr + col + n, ptr + col, nbytes);
566
memset(ptr + col, term->cur_background, n);
568
if_OPT_ISO_TRADITIONAL_COLORS(screen, {
569
ptr = BUF_COLOR(sb, row);
570
memmove(ptr + col + n, ptr + col, nbytes);
571
memset(ptr + col, xtermColorPair(), n);
574
ptr = BUF_CSETS(sb, row);
575
memmove(ptr + col + n, ptr + col, nbytes);
576
memset(ptr + col, curXtermChrSet(row), n);
578
if_OPT_WIDE_CHARS(screen, {
579
ptr = BUF_WIDEC(sb, row);
580
memmove(ptr + col + n, ptr + col, nbytes);
581
memset(ptr + col, 0, n);
583
ptr = BUF_COM1L(sb, row);
584
memmove(ptr + col + n, ptr + col, nbytes);
585
memset(ptr + col, 0, n);
587
ptr = BUF_COM1H(sb, row);
588
memmove(ptr + col + n, ptr + col, nbytes);
589
memset(ptr + col, 0, n);
591
ptr = BUF_COM2L(sb, row);
592
memmove(ptr + col + n, ptr + col, nbytes);
593
memset(ptr + col, 0, n);
595
ptr = BUF_COM2H(sb, row);
596
memmove(ptr + col + n, ptr + col, nbytes);
597
memset(ptr + col, 0, n);
601
ScrnSetWrapped(screen, row);
603
ScrnClrWrapped(screen, row);
607
* Deletes n characters at current row, col.
610
ScrnDeleteChar(TScreen * screen, int n)
612
ScrnBuf sb = screen->visbuf;
613
int size = screen->max_col + 1;
614
int row = screen->cur_row;
615
int col = screen->cur_col;
616
Char *ptr = BUF_CHARS(sb, row);
617
Char *attrs = BUF_ATTRS(sb, row);
620
if (size - (col + n) <= 0) {
621
if ((n = size - col) <= 0) {
625
nbytes = (size - (col + n));
627
memmove(ptr + col, ptr + col + n, nbytes);
628
memmove(attrs + col, attrs + col + n, nbytes);
629
bzero(ptr + size - n, n);
630
memset(attrs + size - n, TERM_COLOR_FLAGS, n);
632
if_OPT_EXT_COLORS(screen, {
633
ptr = BUF_FGRND(sb, row);
634
memmove(ptr + col, ptr + col + n, nbytes);
635
memset(ptr + size - n, term->sgr_foreground, n);
636
ptr = BUF_BGRND(sb, row);
637
memmove(ptr + col, ptr + col + n, nbytes);
638
memset(ptr + size - n, term->cur_background, n);
640
if_OPT_ISO_TRADITIONAL_COLORS(screen, {
641
ptr = BUF_COLOR(sb, row);
642
memmove(ptr + col, ptr + col + n, nbytes);
643
memset(ptr + size - n, xtermColorPair(), n);
646
ptr = BUF_CSETS(sb, row);
647
memmove(ptr + col, ptr + col + n, nbytes);
648
memset(ptr + size - n, curXtermChrSet(row), n);
650
if_OPT_WIDE_CHARS(screen, {
651
ptr = BUF_WIDEC(sb, row);
652
memmove(ptr + col, ptr + col + n, nbytes);
653
memset(ptr + size - n, 0, n);
655
ptr = BUF_COM1L(sb, row);
656
memmove(ptr + col, ptr + col + n, nbytes);
657
memset(ptr + size - n, 0, n);
659
ptr = BUF_COM1H(sb, row);
660
memmove(ptr + col, ptr + col + n, nbytes);
661
memset(ptr + size - n, 0, n);
663
ptr = BUF_COM2L(sb, row);
664
memmove(ptr + col, ptr + col + n, nbytes);
665
memset(ptr + size - n, 0, n);
667
ptr = BUF_COM2H(sb, row);
668
memmove(ptr + col, ptr + col + n, nbytes);
669
memset(ptr + size - n, 0, n);
671
ScrnClrWrapped(screen, row);
675
* Repaints the area enclosed by the parameters.
676
* Requires: (toprow, leftcol), (toprow + nrows, leftcol + ncols) are
677
* coordinates of characters in screen;
678
* nrows and ncols positive.
679
* all dimensions are based on single-characters.
682
ScrnRefresh(TScreen * screen,
687
Bool force) /* ... leading/trailing spaces */
689
int y = toprow * FontHeight(screen) + screen->border;
691
int topline = screen->topline;
692
int maxrow = toprow + nrows - 1;
693
int scrollamt = screen->scroll_amt;
694
int max = screen->max_row;
697
static char first_time = 1;
699
static int recurse = 0;
701
TRACE(("ScrnRefresh (%d,%d) - (%d,%d)%s\n",
704
force ? " force" : ""));
706
if (screen->cursor_col >= leftcol
707
&& screen->cursor_col <= (leftcol + ncols - 1)
708
&& screen->cursor_row >= toprow + topline
709
&& screen->cursor_row <= maxrow + topline)
710
screen->cursor_state = OFF;
712
for (row = toprow; row <= maxrow; y += FontHeight(screen), row++) {
717
#define ColorOf(col) ((fbf[col] << 8) | fbb[col])
720
#define ColorOf(col) (fb[col])
729
#define WIDEC_PTR(cell) widec ? &widec[cell] : 0
735
int maxcol = leftcol + ncols - 1;
740
int fg_bg = 0, fg = 0, bg = 0;
745
if (row < screen->top_marg || row > screen->bot_marg)
748
lastind = row - scrollamt;
750
TRACE(("ScrnRefresh row=%d lastind=%d/%d\n", row, lastind, max));
751
if (lastind < 0 || lastind > max)
754
chars = SCRN_BUF_CHARS(screen, lastind + topline);
755
attrs = SCRN_BUF_ATTRS(screen, lastind + topline);
758
cb = SCRN_BUF_CSETS(screen, lastind + topline);
761
if_OPT_WIDE_CHARS(screen, {
762
widec = SCRN_BUF_WIDEC(screen, lastind + topline);
765
if_OPT_WIDE_CHARS(screen, {
766
/* This fixes an infinite recursion bug, that leads
767
to display anomalies. It seems to be related to
768
problems with the selection. */
770
/* adjust to redraw all of a widechar if we just wanted
771
to draw the right hand half */
772
if (iswide(chars[leftcol - 1] | (widec[leftcol - 1] << 8)) &&
773
(chars[leftcol] | (widec[leftcol] << 8)) == HIDDEN_CHAR) {
779
fprintf(stderr, "This should not happen. Why is it so?\n");
783
if (row < screen->startHRow || row > screen->endHRow ||
784
(row == screen->startHRow && maxcol < screen->startHCol) ||
785
(row == screen->endHRow && col >= screen->endHCol)) {
788
* Temporarily change dimensions to double-sized characters so
789
* we can reuse the recursion on this function.
791
if (CSET_DOUBLE(*cb)) {
796
/* row does not intersect selection; don't hilite */
798
while (col <= maxcol && (attrs[col] & ~BOLD) == 0 &&
799
(chars[col] & ~040) == 0)
802
while (col <= maxcol && (attrs[maxcol] & ~BOLD) == 0 &&
803
(chars[maxcol] & ~040) == 0)
807
if (CSET_DOUBLE(*cb)) {
814
/* row intersects selection; split into pieces of single type */
815
if (row == screen->startHRow && col < screen->startHCol) {
817
ScrnRefresh(screen, row, col, 1, screen->startHCol - col,
819
col = screen->startHCol;
821
if (row == screen->endHRow && maxcol >= screen->endHCol) {
823
ScrnRefresh(screen, row, screen->endHCol, 1,
824
maxcol - screen->endHCol + 1, force);
825
maxcol = screen->endHCol - 1;
829
* If we're highlighting because the user is doing cut/paste,
830
* trim the trailing blanks from the highlighted region so we're
831
* showing the actual extent of the text that'll be cut. If
832
* we're selecting a blank line, we'll highlight one column
835
* We don't do this if the mouse-hilite mode is set because that
836
* would be too confusing.
838
* The default if the highlightSelection resource isn't set will
839
* highlight the whole width of the terminal, which is easy to
840
* see, but harder to use (because trailing blanks aren't as
843
if (screen->highlight_selection
844
&& screen->send_mouse_pos != VT200_HIGHLIGHT_MOUSE) {
845
hi_col = screen->max_col;
846
while (hi_col > 0 && !(attrs[hi_col] & CHARDRAWN))
850
/* remaining piece should be hilited */
858
* Go back to double-sized character dimensions if the line has
859
* double-width characters. Note that 'hi_col' is already in the
863
if (CSET_DOUBLE(*cb)) {
873
wideness = iswide(chars[col] | (widec[col] << 8));
877
if_OPT_EXT_COLORS(screen, {
878
fbf = SCRN_BUF_FGRND(screen, lastind + topline);
879
fbb = SCRN_BUF_BGRND(screen, lastind + topline);
880
fg_bg = ColorOf(col);
881
/* this combines them, then splits them again. but
882
extract_fg does more, so seems reasonable */
883
fg = extract_fg(fg_bg, flags);
884
bg = extract_bg(fg_bg, flags);
886
if_OPT_ISO_TRADITIONAL_COLORS(screen, {
887
fb = SCRN_BUF_COLOR(screen, lastind + topline);
888
fg_bg = ColorOf(col);
889
fg = extract_fg(fg_bg, flags);
890
bg = extract_bg(fg_bg, flags);
893
gc = updatedXtermGC(screen, flags, fg_bg, hilite);
894
gc_changes |= (flags & (FG_COLOR | BG_COLOR));
896
x = CurCursorX(screen, row + topline, col);
899
for (; col <= maxcol; col++) {
900
if ((attrs[col] != flags)
901
|| (hilite && (col > hi_col))
903
|| ((flags & FG_COLOR)
904
&& (extract_fg(ColorOf(col), attrs[col]) != fg))
905
|| ((flags & BG_COLOR)
906
&& (extract_bg(ColorOf(col), attrs[col]) != bg))
910
&& ((iswide(chars[col] | (widec[col] << 8))) != wideness)
911
&& !((chars[col] | (widec[col] << 8)) == HIDDEN_CHAR))
917
TRACE(("ScrnRefresh looping drawXtermText %d..%d:%s\n",
919
visibleChars(PAIRED_CHARS(&chars[lastind],
924
checkVeryBoldColors(test, fg);
926
x = drawXtermText(screen, test, gc, x, y,
928
PAIRED_CHARS(&chars[lastind], WIDEC_PTR(lastind)),
931
if_OPT_WIDE_CHARS(screen, {
933
Char *comb1l = BUF_COM1L(screen->visbuf, row + topline);
934
Char *comb2l = BUF_COM2L(screen->visbuf, row + topline);
935
Char *comb1h = BUF_COM1H(screen->visbuf, row + topline);
936
Char *comb2h = BUF_COM2H(screen->visbuf, row + topline);
937
for (i = lastind; i < col; i++) {
938
int my_x = CurCursorX(screen, row + topline, i);
939
int base = chars[i] | (widec[i] << 8);
940
int comb1 = comb1l[i] | (comb1h[i] << 8);
941
int comb2 = comb2l[i] | (comb2h[i] << 8);
944
my_x = CurCursorX(screen, row + topline, i - 1);
947
drawXtermText(screen, test, gc, my_x, y, cs,
948
PAIRED_CHARS(comb1l + i, comb1h + i),
953
drawXtermText(screen, test, gc, my_x, y, cs,
954
PAIRED_CHARS(comb2l + i, comb2h + i),
960
resetXtermGC(screen, flags, hilite);
964
if (hilite && (col > hi_col))
968
if_OPT_EXT_COLORS(screen, {
969
fg_bg = ColorOf(col);
970
fg = extract_fg(fg_bg, flags);
971
bg = extract_bg(fg_bg, flags);
973
if_OPT_ISO_TRADITIONAL_COLORS(screen, {
974
fg_bg = ColorOf(col);
975
fg = extract_fg(fg_bg, flags);
976
bg = extract_bg(fg_bg, flags);
983
wideness = iswide(chars[col] | (widec[col] << 8));
986
gc = updatedXtermGC(screen, flags, fg_bg, hilite);
987
gc_changes |= (flags & (FG_COLOR | BG_COLOR));
990
if (chars[col] == 0) {
992
if (widec == 0 || widec[col] == 0)
998
TRACE(("ScrnRefresh calling drawXtermText %d..%d:%s\n",
1000
visibleChars(PAIRED_CHARS(&chars[lastind], WIDEC_PTR(lastind)),
1004
checkVeryBoldColors(test, fg);
1006
drawXtermText(screen, test, gc, x, y,
1008
PAIRED_CHARS(&chars[lastind], WIDEC_PTR(lastind)),
1011
if_OPT_WIDE_CHARS(screen, {
1013
Char *comb1l = BUF_COM1L(screen->visbuf, row + topline);
1014
Char *comb2l = BUF_COM2L(screen->visbuf, row + topline);
1015
Char *comb1h = BUF_COM1H(screen->visbuf, row + topline);
1016
Char *comb2h = BUF_COM2H(screen->visbuf, row + topline);
1017
for (i = lastind; i < col; i++) {
1018
int my_x = CurCursorX(screen, row + topline, i);
1019
int base = chars[i] | (widec[i] << 8);
1020
int comb1 = comb1l[i] | (comb1h[i] << 8);
1021
int comb2 = comb2l[i] | (comb2h[i] << 8);
1024
my_x = CurCursorX(screen, row + topline, i - 1);
1027
drawXtermText(screen, test, gc, my_x, y, cs,
1028
PAIRED_CHARS(comb1l + i, comb1h + i),
1033
drawXtermText(screen, test, gc, my_x, y, cs,
1034
PAIRED_CHARS(comb2l + i, comb2h + i),
1040
resetXtermGC(screen, flags, hilite);
1044
* If we're in color mode, reset the various GC's to the current
1045
* screen foreground and background so that other functions (e.g.,
1046
* ClearRight) will get the correct colors.
1048
if_OPT_ISO_COLORS(screen, {
1049
if (gc_changes & FG_COLOR)
1050
SGR_Foreground(term->cur_foreground);
1051
if (gc_changes & BG_COLOR)
1052
SGR_Background(term->cur_background);
1055
#if defined(__CYGWIN__) && defined(TIOCSWINSZ)
1056
if (first_time == 1) {
1062
ws.ws_xpixel = term->core.width;
1063
ws.ws_ypixel = term->core.height;
1064
ioctl(screen->respond, TIOCSWINSZ, (char *) &ws);
1071
* Sets the rows first though last of the buffer of screen to spaces.
1072
* Requires first <= last; first, last are rows of screen->buf.
1075
ClearBufRows(TScreen * screen,
1079
ScrnBuf buf = screen->visbuf;
1080
int len = screen->max_col + 1;
1082
int flags = TERM_COLOR_FLAGS;
1084
TRACE(("ClearBufRows %d..%d\n", first, last));
1085
for (row = first; row <= last; row++) {
1086
ScrnClrWrapped(screen, row);
1087
bzero(BUF_CHARS(buf, row), len);
1088
memset(BUF_ATTRS(buf, row), flags, len);
1089
if_OPT_EXT_COLORS(screen, {
1090
memset(BUF_FGRND(buf, row), term->sgr_foreground, len);
1091
memset(BUF_BGRND(buf, row), term->cur_background, len);
1093
if_OPT_ISO_TRADITIONAL_COLORS(screen, {
1094
memset(BUF_COLOR(buf, row), xtermColorPair(), len);
1097
memset(BUF_CSETS(buf, row), 0, len);
1099
if_OPT_WIDE_CHARS(screen, {
1100
memset(BUF_WIDEC(buf, row), 0, len);
1101
memset(BUF_COM1L(buf, row), 0, len);
1102
memset(BUF_COM1H(buf, row), 0, len);
1103
memset(BUF_COM2L(buf, row), 0, len);
1104
memset(BUF_COM2H(buf, row), 0, len);
1111
1. If new window would have fractional characters, sets window size so as to
1112
discard fractional characters and returns -1.
1113
Minimum screen size is 1 X 1.
1114
Note that this causes another ExposeWindow event.
1115
2. Enlarges screen->buf if necessary. New space is appended to the bottom
1117
3. Reduces screen->buf if necessary. Old space is removed from the bottom
1119
4. Cursor is positioned as closely to its former position as possible
1120
5. Sets screen->max_row and screen->max_col to reflect new size
1121
6. Maintains the inner border (and clears the border on the screen).
1122
7. Clears origin mode and sets scrolling region to be entire screen.
1126
ScreenResize(TScreen * screen,
1133
int border = 2 * screen->border;
1135
#if defined(TIOCSSIZE) && (defined(sun) && !defined(SVR4))
1137
#elif defined(TIOCSWINSZ)
1139
#endif /* sun vs TIOCSWINSZ */
1140
Window tw = VWindow(screen);
1142
TRACE(("ScreenResize %dx%d\n", height, width));
1144
/* clear the right and bottom internal border because of NorthWest
1145
gravity might have left junk on the right and bottom edges */
1146
if (width >= FullWidth(screen)) {
1147
XClearArea(screen->display, tw,
1148
FullWidth(screen), 0, /* right edge */
1149
0, height, /* from top to bottom */
1152
if (height >= FullHeight(screen)) {
1153
XClearArea(screen->display, tw,
1154
0, FullHeight(screen), /* bottom */
1155
width, 0, /* all across the bottom */
1159
/* round so that it is unlikely the screen will change size on */
1160
/* small mouse movements. */
1161
rows = (height + FontHeight(screen) / 2 - border) /
1163
cols = (width + FontWidth(screen) / 2 - border - ScrollbarWidth(screen)) /
1170
/* update buffers if the screen has changed size */
1171
if (screen->max_row != rows - 1 || screen->max_col != cols - 1) {
1172
int savelines = screen->scrollWidget
1173
? screen->savelines : 0;
1174
int delta_rows = rows - (screen->max_row + 1);
1176
TRACE(("...ScreenResize chars %dx%d\n", rows, cols));
1178
if (screen->cursor_state)
1180
if (screen->alternate
1181
&& term->misc.resizeGravity == SouthWestGravity)
1182
/* swap buffer pointers back to make all this hair work */
1183
SwitchBufPtrs(screen);
1185
(void) Reallocate(&screen->altbuf,
1186
&screen->abuf_address,
1189
screen->max_row + 1,
1190
screen->max_col + 1);
1191
move_down_by = Reallocate(&screen->allbuf,
1192
&screen->sbuf_address,
1193
rows + savelines, cols,
1194
screen->max_row + 1 + savelines,
1195
screen->max_col + 1);
1196
screen->visbuf = &screen->allbuf[MAX_PTRS * savelines];
1198
screen->max_row += delta_rows;
1199
screen->max_col = cols - 1;
1201
if (term->misc.resizeGravity == SouthWestGravity) {
1202
screen->savedlines -= move_down_by;
1203
if (screen->savedlines < 0)
1204
screen->savedlines = 0;
1205
if (screen->savedlines > screen->savelines)
1206
screen->savedlines = screen->savelines;
1207
if (screen->topline < -screen->savedlines)
1208
screen->topline = -screen->savedlines;
1209
screen->cur_row += move_down_by;
1210
screen->cursor_row += move_down_by;
1211
ScrollSelection(screen, move_down_by);
1213
if (screen->alternate)
1214
SwitchBufPtrs(screen); /* put the pointers back */
1217
/* adjust scrolling region */
1218
screen->top_marg = 0;
1219
screen->bot_marg = screen->max_row;
1222
if (screen->cur_row > screen->max_row)
1223
screen->cur_row = screen->max_row;
1224
if (screen->cur_col > screen->max_col)
1225
screen->cur_col = screen->max_col;
1227
screen->fullVwin.height = height - border;
1228
screen->fullVwin.width = width - border - screen->fullVwin.sb_info.width;
1230
} else if (FullHeight(screen) == height && FullWidth(screen) == width)
1231
return (0); /* nothing has changed at all */
1233
screen->fullVwin.fullheight = height;
1234
screen->fullVwin.fullwidth = width;
1236
if (screen->scrollWidget)
1237
ResizeScrollBar(screen);
1239
ResizeSelection(screen, rows, cols);
1241
#ifndef NO_ACTIVE_ICON
1242
if (screen->iconVwin.window) {
1243
XWindowChanges changes;
1244
screen->iconVwin.width =
1245
(screen->max_col + 1) * screen->iconVwin.f_width;
1247
screen->iconVwin.height =
1248
(screen->max_row + 1) * screen->iconVwin.f_height;
1250
changes.width = screen->iconVwin.fullwidth =
1251
screen->iconVwin.width + 2 * screen->border;
1253
changes.height = screen->iconVwin.fullheight =
1254
screen->iconVwin.height + 2 * screen->border;
1256
XConfigureWindow(XtDisplay(term), screen->iconVwin.window,
1257
CWWidth | CWHeight, &changes);
1259
#endif /* NO_ACTIVE_ICON */
1261
#if defined(TIOCSSIZE) && (defined(sun) && !defined(SVR4))
1262
/* Set tty's idea of window size */
1265
code = ioctl(screen->respond, TIOCSSIZE, &ts);
1266
TRACE(("return %d from TIOCSSIZE %dx%d\n", code, rows, cols));
1268
if (screen->pid > 1) {
1271
if (ioctl(screen->respond, TIOCGPGRP, &pgrp) != -1)
1272
kill_process_group(pgrp, SIGWINCH);
1274
#endif /* SIGWINCH */
1275
#elif defined(TIOCSWINSZ)
1276
/* Set tty's idea of window size */
1279
ws.ws_xpixel = width;
1280
ws.ws_ypixel = height;
1281
code = ioctl(screen->respond, TIOCSWINSZ, (char *) &ws);
1282
TRACE(("return %d from TIOCSWINSZ %dx%d\n", code, rows, cols));
1283
#ifdef notdef /* change to SIGWINCH if this doesn't work for you */
1284
if (screen->pid > 1) {
1287
if (ioctl(screen->respond, TIOCGPGRP, &pgrp) != -1)
1288
kill_process_group(pgrp, SIGWINCH);
1290
#endif /* SIGWINCH */
1292
TRACE(("ScreenResize cannot do anything to pty\n"));
1293
#endif /* sun vs TIOCSWINSZ */
1298
* Return true if any character cell starting at [row,col], for len-cells is
1302
non_blank_line(ScrnBuf sb,
1308
Char *ptr = BUF_CHARS(sb, row);
1310
for (i = col; i < len; i++) {
1315
if_OPT_WIDE_CHARS((&(term->screen)), {
1316
if ((ptr = BUF_WIDEC(sb, row)) != 0) {
1317
for (i = col; i < len; i++) {