ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/screen.C
(Generate patch)

Comparing rxvt-unicode/src/screen.C (file contents):
Revision 1.175 by root, Tue Dec 20 19:30:59 2005 UTC vs.
Revision 1.176 by root, Tue Dec 20 20:58:31 2005 UTC

251 if (nrow < prev_nrow) 251 if (nrow < prev_nrow)
252 { 252 {
253 /* delete rows */ 253 /* delete rows */
254 k = min (nsaved, prev_nrow - nrow); 254 k = min (nsaved, prev_nrow - nrow);
255 // k = max (0, - ( (nrow - 1) - r->screen.cur.row)); // mmc's http://maruska.dyndns.org/wiki/scrolling-bug //make configurable? //D TODO 255 // k = max (0, - ( (nrow - 1) - r->screen.cur.row)); // mmc's http://maruska.dyndns.org/wiki/scrolling-bug //make configurable? //D TODO
256 scr_scroll_text (0, (int)prev_nrow - 1, k, 1); 256 scr_scroll_text (0, (int)prev_nrow - 1, k);
257 257
258 for (p = nrow; p < prev_nrow; p++) 258 for (p = nrow; p < prev_nrow; p++)
259 { 259 {
260 lfree (ROW(p)); 260 lfree (ROW(p));
261 lfree (swap_save[p]); 261 lfree (swap_save[p]);
289 drawn[p].clear (); scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE); 289 drawn[p].clear (); scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE);
290 } 290 }
291 291
292 if (k > 0) 292 if (k > 0)
293 { 293 {
294 scr_scroll_text (0, (int)nrow - 1, -k, 1); 294 scr_scroll_text (0, (int)nrow - 1, -k);
295 screen.cur.row += k; 295 screen.cur.row += k;
296 screen.s_cur.row += k; 296 screen.s_cur.row += k;
297 nsaved -= k; 297 nsaved -= k;
298 } 298 }
299 299
538 * XTERM_SEQ: Secondary screen: ESC [ ? 4 7 l 538 * XTERM_SEQ: Secondary screen: ESC [ ? 4 7 l
539 */ 539 */
540int 540int
541rxvt_term::scr_change_screen (int scrn) 541rxvt_term::scr_change_screen (int scrn)
542{ 542{
543 int i;
544#if NSCREENS
545 int offset;
546#endif
547
548 want_refresh = 1; 543 want_refresh = 1;
549
550 view_start = 0; 544 view_start = 0;
551 545
552 if (current_screen == scrn) 546 if (current_screen == scrn)
553 return scrn; 547 return scrn;
554 548
555 selection_check (2); /* check for boundary cross */ 549 selection_check (2); /* check for boundary cross */
556 550
557 i = current_screen; current_screen = scrn; scrn = i; 551 SWAP_IT (scrn, current_screen, int);
558 552
559 SWAP_IT (screen.cur.row, swap.cur.row, int16_t); 553 SWAP_IT (screen.cur.row, swap.cur.row, int16_t);
560 SWAP_IT (screen.cur.col, swap.cur.col, int16_t); 554 SWAP_IT (screen.cur.col, swap.cur.col, int16_t);
561 MAX_IT (screen.cur.row, 0); 555 MAX_IT (screen.cur.row, 0);
562 MIN_IT (screen.cur.row, (int32_t)prev_nrow - 1); 556 MIN_IT (screen.cur.row, (int32_t)prev_nrow - 1);
565 559
566#if NSCREENS 560#if NSCREENS
567 if (options & Opt_secondaryScreen) 561 if (options & Opt_secondaryScreen)
568 { 562 {
569 num_scr = 0; 563 num_scr = 0;
570 offset = saveLines;
571 564
572 for (i = prev_nrow; i--;) 565 for (int i = nrow; i--; )
573 SWAP_IT (ROW(i), swap_save[i], line_t); 566 SWAP_IT (ROW(i), swap_save[i], line_t);
574 567
575 SWAP_IT (screen.charset, swap.charset, int16_t); 568 SWAP_IT (screen.charset, swap.charset, int16_t);
576 SWAP_IT (screen.flags, swap.flags, int); 569 SWAP_IT (screen.flags, swap.flags, int);
577 screen.flags |= Screen_VisibleCursor; 570 screen.flags |= Screen_VisibleCursor;
578 swap.flags |= Screen_VisibleCursor; 571 swap.flags |= Screen_VisibleCursor;
579 } 572 }
580 else 573 else
581#endif 574#endif
582 if (options & Opt_secondaryScroll) 575 if (options & Opt_secondaryScroll)
583 scr_scroll_text (0, prev_nrow - 1, prev_nrow, 0); 576 scr_scroll_text (0, prev_nrow - 1, prev_nrow);
584 577
585 return scrn; 578 return scrn;
586} 579}
587 580
588// clear WrapNext indicator, solidifying position on next line 581// clear WrapNext indicator, solidifying position on next line
595 screen.flags &= ~Screen_WrapNext; 588 screen.flags &= ~Screen_WrapNext;
596 589
597 screen.cur.col = 0; 590 screen.cur.col = 0;
598 591
599 if (screen.cur.row == screen.bscroll) 592 if (screen.cur.row == screen.bscroll)
600 scr_scroll_text (screen.tscroll, screen.bscroll, 1, 0); 593 scr_scroll_text (screen.tscroll, screen.bscroll, 1);
601 else if (screen.cur.row < nrow - 1) 594 else if (screen.cur.row < nrow - 1)
602 screen.cur.row++; 595 screen.cur.row++;
603} 596}
604 597
605/* ------------------------------------------------------------------------- */ 598/* ------------------------------------------------------------------------- */
636/* ------------------------------------------------------------------------- */ 629/* ------------------------------------------------------------------------- */
637/* 630/*
638 * Scroll text between <row1> and <row2> inclusive, by <count> lines 631 * Scroll text between <row1> and <row2> inclusive, by <count> lines
639 * count positive ==> scroll up 632 * count positive ==> scroll up
640 * count negative ==> scroll down 633 * count negative ==> scroll down
641 * spec == 0 for normal routines
642 */ 634 */
643int 635int
644rxvt_term::scr_scroll_text (int row1, int row2, int count, int spec) 636rxvt_term::scr_scroll_text (int row1, int row2, int count)
645{ 637{
646 int i, j;
647
648 if (count == 0 || (row1 > row2)) 638 if (count == 0 || (row1 > row2))
649 return 0; 639 return 0;
650 640
651 want_refresh = 1; 641 want_refresh = 1;
642 num_scr += count;
652 643
653 if (row1 == 0 && count > 0 644 if (row1 == 0 && count > 0
654 && (current_screen == PRIMARY || options & Opt_secondaryScroll)) 645 && (current_screen == PRIMARY || options & Opt_secondaryScroll))
655 { 646 {
656 nsaved = min (nsaved + count, saveLines); 647 nsaved = min (nsaved + count, saveLines);
659 if (selection.op && current_screen == selection.screen) 650 if (selection.op && current_screen == selection.screen)
660 { 651 {
661 selection.beg.row -= count; 652 selection.beg.row -= count;
662 selection.end.row -= count; 653 selection.end.row -= count;
663 selection.mark.row -= count; 654 selection.mark.row -= count;
655
656 selection_check (0);
664 } 657 }
665 658
666 for (int i = count; i--; ) 659 for (int i = count; i--; )
667 scr_blank_screen_mem (ROW(row2 - i), rstyle); 660 scr_blank_screen_mem (ROW(row2 - i), rstyle);
668 661
671 && view_start != saveLines) 664 && view_start != saveLines)
672 scr_page (UP, count); 665 scr_page (UP, count);
673 } 666 }
674 else 667 else
675 { 668 {
676 if (!spec)
677 row1 += saveLines;
678
679 row2 += saveLines;
680
681 if (selection.op && current_screen == selection.screen) 669 if (selection.op && current_screen == selection.screen)
682 { 670 {
683 i = selection.beg.row + saveLines; 671 int i = selection.beg.row;
684 j = selection.end.row + saveLines; 672 int j = selection.end.row;
685 673
686 if ((i < row1 && j > row1) 674 if ((i < row1 && j > row1)
687 || (i < row2 && j > row2) 675 || (i < row2 && j > row2)
688 || (i - count < row1 && i >= row1) 676 || (i - count < row1 && i >= row1)
689 || (i - count > row2 && i <= row2) 677 || (i - count > row2 && i <= row2)
697 { 685 {
698 /* move selected region too */ 686 /* move selected region too */
699 selection.beg.row -= count; 687 selection.beg.row -= count;
700 selection.end.row -= count; 688 selection.end.row -= count;
701 selection.mark.row -= count; 689 selection.mark.row -= count;
690
691 selection_check (0);
702 } 692 }
703 } 693 }
704 694
705 selection_check (0); /* _after_ nsaved update */ 695 // use a simple and robust scrolling algorithm, this
696 // part of scr_scroll_text is not time-critical.
706 697
707 num_scr += count;
708 j = count;
709
710 if (count < 0)
711 count = -count;
712
713 i = row2 - row1 + 1; 698 int rows = row2 - row1 + 1;
714 MIN_IT (count, i);
715 699
716 if (j > 0) 700 for (int row = 0; row < rows; row++)
717 {
718 /* scroll up */
719
720 /* Copy lines that will get clobbered by the rotation */
721 memcpy (buf, save + row1, count * sizeof (line_t));
722
723 /* Rotate lines */
724 i = row2 - row1 - count + 1;
725 memmove (save + row1, save + row1 + count, i * sizeof (line_t));
726
727 j = row2 - count + 1, i = count;
728 } 701 {
729 else /* if (j < 0) */ 702 buf [row] = ROW(row1 + (row + count + rows) % rows);
703
704 if (!IN_RANGE_EXC (row + count, 0, rows))
705 scr_blank_screen_mem (buf [row], rstyle);
730 { 706 }
731 /* scroll down */
732 707
733 /* Copy lines that will get clobbered by the rotation */ 708 for (int row = 0; row < rows; row++)
734 for (i = 0, j = row2; i < count; i++, j--) 709 ROW(row1 + row) = buf [row];
735 buf[i] = save[j];
736
737 /* Rotate lines */
738 for (j = row2, i = j - count; i >= row1; i--, j--)
739 save[j] = save[i];
740
741 j = row1, i = count;
742 count = -count;
743 }
744
745 /* Resurrect lines */
746 memcpy (save + j, buf, i * sizeof (line_t));
747
748 if (!spec) /* line length may not equal ncol */
749 for (; i--; j++)
750 scr_blank_screen_mem (save[j], rstyle);
751 } 710 }
752 711
753 return count; 712 return count;
754} 713}
755 714
778 if ((nlines > 0) 737 if ((nlines > 0)
779 && (screen.tscroll == 0) 738 && (screen.tscroll == 0)
780 && (screen.bscroll == (nrow - 1))) 739 && (screen.bscroll == (nrow - 1)))
781 { 740 {
782 /* _at least_ this many lines need to be scrolled */ 741 /* _at least_ this many lines need to be scrolled */
783 scr_scroll_text (screen.tscroll, screen.bscroll, nlines, 0); 742 scr_scroll_text (screen.tscroll, screen.bscroll, nlines);
784 screen.cur.row -= nlines; 743 screen.cur.row -= nlines;
785 } 744 }
786 } 745 }
787 746
788#ifdef DEBUG_STRICT 747#ifdef DEBUG_STRICT
811 MAX_IT (line->l, screen.cur.col); 770 MAX_IT (line->l, screen.cur.col);
812 771
813 screen.flags &= ~Screen_WrapNext; 772 screen.flags &= ~Screen_WrapNext;
814 773
815 if (screen.cur.row == screen.bscroll) 774 if (screen.cur.row == screen.bscroll)
816 scr_scroll_text (screen.tscroll, screen.bscroll, 1, 0); 775 scr_scroll_text (screen.tscroll, screen.bscroll, 1);
817 else if (screen.cur.row < (nrow - 1)) 776 else if (screen.cur.row < (nrow - 1))
818 row = ++screen.cur.row; 777 row = ++screen.cur.row;
819 778
820 line = &ROW(row); /* _must_ refresh */ 779 line = &ROW(row); /* _must_ refresh */
821 continue; 780 continue;
1234 1193
1235 screen.flags &= ~Screen_WrapNext; 1194 screen.flags &= ~Screen_WrapNext;
1236 1195
1237 if ((screen.cur.row == screen.bscroll && direction == UP) 1196 if ((screen.cur.row == screen.bscroll && direction == UP)
1238 || (screen.cur.row == screen.tscroll && direction == DN)) 1197 || (screen.cur.row == screen.tscroll && direction == DN))
1239 scr_scroll_text (screen.tscroll, screen.bscroll, dirn, 0); 1198 scr_scroll_text (screen.tscroll, screen.bscroll, dirn);
1240 else 1199 else
1241 screen.cur.row += dirn; 1200 screen.cur.row += dirn;
1242 1201
1243 MAX_IT (screen.cur.row, 0); 1202 MAX_IT (screen.cur.row, 0);
1244 MIN_IT (screen.cur.row, (int32_t)nrow - 1); 1203 MIN_IT (screen.cur.row, (int32_t)nrow - 1);
1305 */ 1264 */
1306void 1265void
1307rxvt_term::scr_erase_screen (int mode) 1266rxvt_term::scr_erase_screen (int mode)
1308{ 1267{
1309 int num; 1268 int num;
1310 int32_t row, row_offset; 1269 int32_t row;
1311 rend_t ren; 1270 rend_t ren;
1312 XGCValues gcvalue; 1271 XGCValues gcvalue;
1313 1272
1314 want_refresh = 1; 1273 want_refresh = 1;
1315 ZERO_SCROLLBACK (); 1274 ZERO_SCROLLBACK ();
1316
1317 row_offset = (int32_t)saveLines;
1318 1275
1319 switch (mode) 1276 switch (mode)
1320 { 1277 {
1321 case 0: /* erase to end of screen */ 1278 case 0: /* erase to end of screen */
1322 selection_check (1); 1279 selection_check (1);
1367 XChangeGC (display->display, gc, GCForeground, &gcvalue); 1324 XChangeGC (display->display, gc, GCForeground, &gcvalue);
1368 } 1325 }
1369 1326
1370 for (; num--; row++) 1327 for (; num--; row++)
1371 { 1328 {
1372 scr_blank_screen_mem (save[row + row_offset], rstyle); 1329 scr_blank_screen_mem (ROW (row), rstyle);
1373 save[row + row_offset].l = 0; 1330 ROW (row).l = 0;
1374 scr_blank_line (drawn[row], 0, ncol, ren); 1331 scr_blank_line (drawn[row], 0, ncol, ren);
1375 } 1332 }
1376} 1333}
1377 1334
1378#if ENABLE_FRILLS 1335#if ENABLE_FRILLS
1392 * XTERM_SEQ: Screen Alignment Test: ESC # 8 1349 * XTERM_SEQ: Screen Alignment Test: ESC # 8
1393 */ 1350 */
1394void 1351void
1395rxvt_term::scr_E () 1352rxvt_term::scr_E ()
1396{ 1353{
1397 int i, j, k;
1398 rend_t *r1, fs; 1354 rend_t fs;
1399 1355
1400 want_refresh = 1; 1356 want_refresh = 1;
1401 ZERO_SCROLLBACK (); 1357 ZERO_SCROLLBACK ();
1402 1358
1403 num_scr_allow = 0; 1359 num_scr_allow = 0;
1404 selection_check (3); 1360 selection_check (3);
1405 1361
1406 fs = SET_FONT (rstyle, FONTSET (rstyle)->find_font ('E')); 1362 fs = SET_FONT (rstyle, FONTSET (rstyle)->find_font ('E'));
1407 for (k = saveLines, i = nrow; i--; k++) 1363 for (int row = nrow; row--; )
1408 { 1364 {
1409 line_t &line = save[k]; 1365 line_t &line = ROW(row);
1410 1366
1411 fill_text (line.t, 'E', ncol); 1367 fill_text (line.t, 'E', ncol);
1368 rend_t *r1 = line.r;
1412 1369
1413 for (r1 = line.r, j = ncol; j--; ) 1370 for (int j = ncol; j--; )
1414 *r1++ = fs; 1371 *r1++ = fs;
1415 1372
1416 line.l = ncol; /* make the `E's selectable */ 1373 line.l = ncol; /* make the `E's selectable */
1417 } 1374 }
1418} 1375}
1442 count = end; 1399 count = end;
1443 } 1400 }
1444 1401
1445 scr_do_wrap (); 1402 scr_do_wrap ();
1446 1403
1447 scr_scroll_text (screen.cur.row, screen.bscroll, insdel * count, 0); 1404 scr_scroll_text (screen.cur.row, screen.bscroll, insdel * count);
1448} 1405}
1449 1406
1450/* ------------------------------------------------------------------------- */ 1407/* ------------------------------------------------------------------------- */
1451/* 1408/*
1452 * Insert/Delete <count> characters from the current position 1409 * Insert/Delete <count> characters from the current position
1466 scr_do_wrap (); 1423 scr_do_wrap ();
1467 1424
1468 selection_check (1); 1425 selection_check (1);
1469 MIN_IT (count, (ncol - screen.cur.col)); 1426 MIN_IT (count, (ncol - screen.cur.col));
1470 1427
1471 row = screen.cur.row + saveLines; 1428 row = screen.cur.row;
1472 1429
1473 line_t *line = save + row; 1430 line_t *line = &ROW(row);
1474 1431
1475 switch (insdel) 1432 switch (insdel)
1476 { 1433 {
1477 case INSERT: 1434 case INSERT:
1478 for (col = ncol - 1; (col - count) >= screen.cur.col; col--) 1435 for (col = ncol - 1; (col - count) >= screen.cur.col; col--)
1499 selection.mark.col += count; /* XXX: yes? */ 1456 selection.mark.col += count; /* XXX: yes? */
1500 selection.end.col += count; 1457 selection.end.col += count;
1501 } 1458 }
1502 } 1459 }
1503 1460
1504 scr_blank_line (save[row], screen.cur.col, count, rstyle); 1461 scr_blank_line (*line, screen.cur.col, count, rstyle);
1505 break; 1462 break;
1506 1463
1507 case ERASE: 1464 case ERASE:
1508 screen.cur.col += count; /* don't worry if > ncol */ 1465 screen.cur.col += count; /* don't worry if > ncol */
1509 selection_check (1); 1466 selection_check (1);
1510 screen.cur.col -= count; 1467 screen.cur.col -= count;
1511 scr_blank_line (save[row], screen.cur.col, count, rstyle); 1468 scr_blank_line (*line, screen.cur.col, count, rstyle);
1512 break; 1469 break;
1513 1470
1514 case DELETE: 1471 case DELETE:
1515 tr = line->r[ncol - 1] & (RS_fgMask | RS_bgMask | RS_baseattrMask); 1472 tr = line->r[ncol - 1] & (RS_fgMask | RS_bgMask | RS_baseattrMask);
1516 1473
1523 scr_blank_line (*line, ncol - count, count, tr); 1480 scr_blank_line (*line, ncol - count, count, tr);
1524 1481
1525 if (line->is_longer ()) /* break line continuation */ 1482 if (line->is_longer ()) /* break line continuation */
1526 line->l = ncol; 1483 line->l = ncol;
1527 1484
1528 line->l -= count; 1485 line->l = max (line->l - count, 0);
1529 MAX_IT (line->l, 0);
1530 1486
1531 if (selection.op && current_screen == selection.screen 1487 if (selection.op && current_screen == selection.screen
1532 && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)) 1488 && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur))
1533 { 1489 {
1534 if (selection.end.row != screen.cur.row 1490 if (selection.end.row != screen.cur.row
1941/* ARGSUSED */ 1897/* ARGSUSED */
1942void 1898void
1943rxvt_term::scr_printscreen (int fullhist) 1899rxvt_term::scr_printscreen (int fullhist)
1944{ 1900{
1945#ifdef PRINTPIPE 1901#ifdef PRINTPIPE
1946 int i, r1, nrows, row_offset; 1902 int nrows, row_start;
1947 FILE *fd; 1903 FILE *fd;
1948 1904
1949 if ((fd = popen_printer ()) == NULL) 1905 if ((fd = popen_printer ()) == NULL)
1950 return; 1906 return;
1951 1907
1952 nrows = nrow;
1953 row_offset = saveLines;
1954
1955 if (!fullhist) 1908 if (fullhist)
1956 row_offset -= view_start; 1909 {
1910 nrows = nrow + nsaved;
1911 row_start = -nsaved;
1912 }
1957 else 1913 else
1958 { 1914 {
1959 nrows += nsaved; 1915 nrows = nrow;
1960 row_offset -= nsaved; 1916 row_start = -view_start;
1961 } 1917 }
1962 1918
1963 wctomb (0, 0); 1919 wctomb (0, 0);
1964 1920
1965 for (r1 = 0; r1 < nrows; r1++) 1921 for (int r1 = 0; r1 < nrows; r1++)
1966 { 1922 {
1967 text_t *tp = save[r1 + row_offset].t; 1923 text_t *tp = ROW(r1).t;
1968 int len = save[r1 + row_offset].l; 1924 int len = ROW(r1).l;
1969 1925
1970 for (i = len >= 0 ? len : ncol - 1; i--; ) //TODO//FIXME//LEN 1926 for (int i = len >= 0 ? len : ncol - 1; i--; ) //TODO//FIXME//LEN
1971 { 1927 {
1972 char mb[MB_LEN_MAX]; 1928 char mb[MB_LEN_MAX];
1973 text_t t = *tp++; 1929 text_t t = *tp++;
1974 if (t == NOCHAR) 1930 if (t == NOCHAR)
1975 continue; 1931 continue;
2135 * D: CopyArea pass - very useful for slower links 2091 * D: CopyArea pass - very useful for slower links
2136 * This has been deliberately kept simple. 2092 * This has been deliberately kept simple.
2137 */ 2093 */
2138 i = num_scr; 2094 i = num_scr;
2139 if (!display->is_local 2095 if (!display->is_local
2140 && refresh_type == FAST_REFRESH && num_scr_allow && i 2096 && refresh_type == FAST_REFRESH && num_scr_allow && num_scr
2141 && abs (i) < nrow && !must_clear) 2097 && abs (num_scr) < nrow && !must_clear)
2142 { 2098 {
2143 int16_t nits; 2099 int16_t nits;
2144 int j; 2100 int j;
2145 int len, wlen; 2101 int len, wlen;
2146 2102
2149 row = i > 0 ? 0 : j - 1; 2105 row = i > 0 ? 0 : j - 1;
2150 for (; j-- >= 0; row += (i > 0 ? 1 : -1)) 2106 for (; j-- >= 0; row += (i > 0 ? 1 : -1))
2151 { 2107 {
2152 if (row + i >= 0 && row + i < nrow && row + i != ocrow) 2108 if (row + i >= 0 && row + i < nrow && row + i != ocrow)
2153 { 2109 {
2154 line_t s = save[(row + row_offset) % nlines]; 2110 line_t s = save[(row + row_offset) % total_rows];
2155 line_t d = drawn[row]; 2111 line_t d = drawn[row];
2156 line_t d2 = drawn[row + i]; 2112 line_t d2 = drawn[row + i];
2157 2113
2158 for (nits = 0, col = ncol; col--; ) 2114 for (nits = 0, col = ncol; col--; )
2159 if (s.t[col] != d2.t[col] || s.r[col] != d2.r[col]) 2115 if (s.t[col] != d2.t[col] || s.r[col] != d2.r[col])
3371 for (int end_row = selection.mark.row; end_row < nrow; end_row++) 3327 for (int end_row = selection.mark.row; end_row < nrow; end_row++)
3372 { 3328 {
3373 if (!ROW(end_row).is_longer ()) 3329 if (!ROW(end_row).is_longer ())
3374 { 3330 {
3375 selection.end.row = end_row; 3331 selection.end.row = end_row;
3376 selection.end.col = save[end_row + saveLines].l; 3332 selection.end.col = ROW(end_row).l;
3377 selection_remove_trailing_spaces (); 3333 selection_remove_trailing_spaces ();
3378 break; 3334 break;
3379 } 3335 }
3380 } 3336 }
3381 } 3337 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines