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.177 by root, Tue Dec 20 21:49:55 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 (count > 0
645 && row1 == 0
646 && row2 == nrow - 1
654 && (current_screen == PRIMARY || options & Opt_secondaryScroll)) 647 && (current_screen == PRIMARY || options & Opt_secondaryScroll))
655 { 648 {
656 nsaved = min (nsaved + count, saveLines); 649 nsaved = min (nsaved + count, saveLines);
657 term_start = (term_start + count) % total_rows; 650 term_start = (term_start + count) % total_rows;
658 651
659 if (selection.op && current_screen == selection.screen) 652 if (selection.op && current_screen == selection.screen)
660 { 653 {
661 selection.beg.row -= count; 654 selection.beg.row -= count;
662 selection.end.row -= count; 655 selection.end.row -= count;
663 selection.mark.row -= count; 656 selection.mark.row -= count;
657
658 selection_check (0);
664 } 659 }
665 660
666 for (int i = count; i--; ) 661 for (int i = count; i--; )
667 scr_blank_screen_mem (ROW(row2 - i), rstyle); 662 scr_blank_screen_mem (ROW(row2 - i), rstyle);
668 663
671 && view_start != saveLines) 666 && view_start != saveLines)
672 scr_page (UP, count); 667 scr_page (UP, count);
673 } 668 }
674 else 669 else
675 { 670 {
676 if (!spec)
677 row1 += saveLines;
678
679 row2 += saveLines;
680
681 if (selection.op && current_screen == selection.screen) 671 if (selection.op && current_screen == selection.screen)
682 { 672 {
683 i = selection.beg.row + saveLines; 673 int i = selection.beg.row;
684 j = selection.end.row + saveLines; 674 int j = selection.end.row;
685 675
686 if ((i < row1 && j > row1) 676 if ((i < row1 && j > row1)
687 || (i < row2 && j > row2) 677 || (i < row2 && j > row2)
688 || (i - count < row1 && i >= row1) 678 || (i - count < row1 && i >= row1)
689 || (i - count > row2 && i <= row2) 679 || (i - count > row2 && i <= row2)
697 { 687 {
698 /* move selected region too */ 688 /* move selected region too */
699 selection.beg.row -= count; 689 selection.beg.row -= count;
700 selection.end.row -= count; 690 selection.end.row -= count;
701 selection.mark.row -= count; 691 selection.mark.row -= count;
692
693 selection_check (0);
702 } 694 }
703 } 695 }
704 696
705 selection_check (0); /* _after_ nsaved update */ 697 // use a simple and robust scrolling algorithm, this
698 // part of scr_scroll_text is not time-critical.
706 699
707 num_scr += count;
708 j = count;
709
710 if (count < 0)
711 count = -count;
712
713 i = row2 - row1 + 1; 700 int rows = row2 - row1 + 1;
714 MIN_IT (count, i);
715 701
716 if (j > 0) 702 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 } 703 {
729 else /* if (j < 0) */ 704 buf [row] = ROW(row1 + (row + count + rows) % rows);
705
706 if (!IN_RANGE_EXC (row + count, 0, rows))
707 scr_blank_screen_mem (buf [row], rstyle);
730 { 708 }
731 /* scroll down */
732 709
733 /* Copy lines that will get clobbered by the rotation */ 710 for (int row = 0; row < rows; row++)
734 for (i = 0, j = row2; i < count; i++, j--) 711 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 } 712 }
752 713
753 return count; 714 return count;
754} 715}
755 716
778 if ((nlines > 0) 739 if ((nlines > 0)
779 && (screen.tscroll == 0) 740 && (screen.tscroll == 0)
780 && (screen.bscroll == (nrow - 1))) 741 && (screen.bscroll == (nrow - 1)))
781 { 742 {
782 /* _at least_ this many lines need to be scrolled */ 743 /* _at least_ this many lines need to be scrolled */
783 scr_scroll_text (screen.tscroll, screen.bscroll, nlines, 0); 744 scr_scroll_text (screen.tscroll, screen.bscroll, nlines);
784 screen.cur.row -= nlines; 745 screen.cur.row -= nlines;
785 } 746 }
786 } 747 }
787 748
788#ifdef DEBUG_STRICT 749#ifdef DEBUG_STRICT
811 MAX_IT (line->l, screen.cur.col); 772 MAX_IT (line->l, screen.cur.col);
812 773
813 screen.flags &= ~Screen_WrapNext; 774 screen.flags &= ~Screen_WrapNext;
814 775
815 if (screen.cur.row == screen.bscroll) 776 if (screen.cur.row == screen.bscroll)
816 scr_scroll_text (screen.tscroll, screen.bscroll, 1, 0); 777 scr_scroll_text (screen.tscroll, screen.bscroll, 1);
817 else if (screen.cur.row < (nrow - 1)) 778 else if (screen.cur.row < (nrow - 1))
818 row = ++screen.cur.row; 779 row = ++screen.cur.row;
819 780
820 line = &ROW(row); /* _must_ refresh */ 781 line = &ROW(row); /* _must_ refresh */
821 continue; 782 continue;
1234 1195
1235 screen.flags &= ~Screen_WrapNext; 1196 screen.flags &= ~Screen_WrapNext;
1236 1197
1237 if ((screen.cur.row == screen.bscroll && direction == UP) 1198 if ((screen.cur.row == screen.bscroll && direction == UP)
1238 || (screen.cur.row == screen.tscroll && direction == DN)) 1199 || (screen.cur.row == screen.tscroll && direction == DN))
1239 scr_scroll_text (screen.tscroll, screen.bscroll, dirn, 0); 1200 scr_scroll_text (screen.tscroll, screen.bscroll, dirn);
1240 else 1201 else
1241 screen.cur.row += dirn; 1202 screen.cur.row += dirn;
1242 1203
1243 MAX_IT (screen.cur.row, 0); 1204 MAX_IT (screen.cur.row, 0);
1244 MIN_IT (screen.cur.row, (int32_t)nrow - 1); 1205 MIN_IT (screen.cur.row, (int32_t)nrow - 1);
1305 */ 1266 */
1306void 1267void
1307rxvt_term::scr_erase_screen (int mode) 1268rxvt_term::scr_erase_screen (int mode)
1308{ 1269{
1309 int num; 1270 int num;
1310 int32_t row, row_offset; 1271 int32_t row;
1311 rend_t ren; 1272 rend_t ren;
1312 XGCValues gcvalue; 1273 XGCValues gcvalue;
1313 1274
1314 want_refresh = 1; 1275 want_refresh = 1;
1315 ZERO_SCROLLBACK (); 1276 ZERO_SCROLLBACK ();
1316
1317 row_offset = (int32_t)saveLines;
1318 1277
1319 switch (mode) 1278 switch (mode)
1320 { 1279 {
1321 case 0: /* erase to end of screen */ 1280 case 0: /* erase to end of screen */
1322 selection_check (1); 1281 selection_check (1);
1367 XChangeGC (display->display, gc, GCForeground, &gcvalue); 1326 XChangeGC (display->display, gc, GCForeground, &gcvalue);
1368 } 1327 }
1369 1328
1370 for (; num--; row++) 1329 for (; num--; row++)
1371 { 1330 {
1372 scr_blank_screen_mem (save[row + row_offset], rstyle); 1331 scr_blank_screen_mem (ROW (row), rstyle);
1373 save[row + row_offset].l = 0; 1332 ROW (row).l = 0;
1374 scr_blank_line (drawn[row], 0, ncol, ren); 1333 scr_blank_line (drawn[row], 0, ncol, ren);
1375 } 1334 }
1376} 1335}
1377 1336
1378#if ENABLE_FRILLS 1337#if ENABLE_FRILLS
1392 * XTERM_SEQ: Screen Alignment Test: ESC # 8 1351 * XTERM_SEQ: Screen Alignment Test: ESC # 8
1393 */ 1352 */
1394void 1353void
1395rxvt_term::scr_E () 1354rxvt_term::scr_E ()
1396{ 1355{
1397 int i, j, k;
1398 rend_t *r1, fs; 1356 rend_t fs;
1399 1357
1400 want_refresh = 1; 1358 want_refresh = 1;
1401 ZERO_SCROLLBACK (); 1359 ZERO_SCROLLBACK ();
1402 1360
1403 num_scr_allow = 0; 1361 num_scr_allow = 0;
1404 selection_check (3); 1362 selection_check (3);
1405 1363
1406 fs = SET_FONT (rstyle, FONTSET (rstyle)->find_font ('E')); 1364 fs = SET_FONT (rstyle, FONTSET (rstyle)->find_font ('E'));
1407 for (k = saveLines, i = nrow; i--; k++) 1365 for (int row = nrow; row--; )
1408 { 1366 {
1409 line_t &line = save[k]; 1367 line_t &line = ROW(row);
1410 1368
1411 fill_text (line.t, 'E', ncol); 1369 fill_text (line.t, 'E', ncol);
1370 rend_t *r1 = line.r;
1412 1371
1413 for (r1 = line.r, j = ncol; j--; ) 1372 for (int j = ncol; j--; )
1414 *r1++ = fs; 1373 *r1++ = fs;
1415 1374
1416 line.l = ncol; /* make the `E's selectable */ 1375 line.l = ncol; /* make the `E's selectable */
1417 } 1376 }
1418} 1377}
1442 count = end; 1401 count = end;
1443 } 1402 }
1444 1403
1445 scr_do_wrap (); 1404 scr_do_wrap ();
1446 1405
1447 scr_scroll_text (screen.cur.row, screen.bscroll, insdel * count, 0); 1406 scr_scroll_text (screen.cur.row, screen.bscroll, insdel * count);
1448} 1407}
1449 1408
1450/* ------------------------------------------------------------------------- */ 1409/* ------------------------------------------------------------------------- */
1451/* 1410/*
1452 * Insert/Delete <count> characters from the current position 1411 * Insert/Delete <count> characters from the current position
1466 scr_do_wrap (); 1425 scr_do_wrap ();
1467 1426
1468 selection_check (1); 1427 selection_check (1);
1469 MIN_IT (count, (ncol - screen.cur.col)); 1428 MIN_IT (count, (ncol - screen.cur.col));
1470 1429
1471 row = screen.cur.row + saveLines; 1430 row = screen.cur.row;
1472 1431
1473 line_t *line = save + row; 1432 line_t *line = &ROW(row);
1474 1433
1475 switch (insdel) 1434 switch (insdel)
1476 { 1435 {
1477 case INSERT: 1436 case INSERT:
1478 for (col = ncol - 1; (col - count) >= screen.cur.col; col--) 1437 for (col = ncol - 1; (col - count) >= screen.cur.col; col--)
1499 selection.mark.col += count; /* XXX: yes? */ 1458 selection.mark.col += count; /* XXX: yes? */
1500 selection.end.col += count; 1459 selection.end.col += count;
1501 } 1460 }
1502 } 1461 }
1503 1462
1504 scr_blank_line (save[row], screen.cur.col, count, rstyle); 1463 scr_blank_line (*line, screen.cur.col, count, rstyle);
1505 break; 1464 break;
1506 1465
1507 case ERASE: 1466 case ERASE:
1508 screen.cur.col += count; /* don't worry if > ncol */ 1467 screen.cur.col += count; /* don't worry if > ncol */
1509 selection_check (1); 1468 selection_check (1);
1510 screen.cur.col -= count; 1469 screen.cur.col -= count;
1511 scr_blank_line (save[row], screen.cur.col, count, rstyle); 1470 scr_blank_line (*line, screen.cur.col, count, rstyle);
1512 break; 1471 break;
1513 1472
1514 case DELETE: 1473 case DELETE:
1515 tr = line->r[ncol - 1] & (RS_fgMask | RS_bgMask | RS_baseattrMask); 1474 tr = line->r[ncol - 1] & (RS_fgMask | RS_bgMask | RS_baseattrMask);
1516 1475
1523 scr_blank_line (*line, ncol - count, count, tr); 1482 scr_blank_line (*line, ncol - count, count, tr);
1524 1483
1525 if (line->is_longer ()) /* break line continuation */ 1484 if (line->is_longer ()) /* break line continuation */
1526 line->l = ncol; 1485 line->l = ncol;
1527 1486
1528 line->l -= count; 1487 line->l = max (line->l - count, 0);
1529 MAX_IT (line->l, 0);
1530 1488
1531 if (selection.op && current_screen == selection.screen 1489 if (selection.op && current_screen == selection.screen
1532 && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)) 1490 && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur))
1533 { 1491 {
1534 if (selection.end.row != screen.cur.row 1492 if (selection.end.row != screen.cur.row
1941/* ARGSUSED */ 1899/* ARGSUSED */
1942void 1900void
1943rxvt_term::scr_printscreen (int fullhist) 1901rxvt_term::scr_printscreen (int fullhist)
1944{ 1902{
1945#ifdef PRINTPIPE 1903#ifdef PRINTPIPE
1946 int i, r1, nrows, row_offset; 1904 int nrows, row_start;
1947 FILE *fd; 1905 FILE *fd;
1948 1906
1949 if ((fd = popen_printer ()) == NULL) 1907 if ((fd = popen_printer ()) == NULL)
1950 return; 1908 return;
1951 1909
1952 nrows = nrow;
1953 row_offset = saveLines;
1954
1955 if (!fullhist) 1910 if (fullhist)
1956 row_offset -= view_start; 1911 {
1912 nrows = nrow + nsaved;
1913 row_start = -nsaved;
1914 }
1957 else 1915 else
1958 { 1916 {
1959 nrows += nsaved; 1917 nrows = nrow;
1960 row_offset -= nsaved; 1918 row_start = -view_start;
1961 } 1919 }
1962 1920
1963 wctomb (0, 0); 1921 wctomb (0, 0);
1964 1922
1965 for (r1 = 0; r1 < nrows; r1++) 1923 for (int r1 = 0; r1 < nrows; r1++)
1966 { 1924 {
1967 text_t *tp = save[r1 + row_offset].t; 1925 text_t *tp = ROW(r1).t;
1968 int len = save[r1 + row_offset].l; 1926 int len = ROW(r1).l;
1969 1927
1970 for (i = len >= 0 ? len : ncol - 1; i--; ) //TODO//FIXME//LEN 1928 for (int i = len >= 0 ? len : ncol - 1; i--; ) //TODO//FIXME//LEN
1971 { 1929 {
1972 char mb[MB_LEN_MAX]; 1930 char mb[MB_LEN_MAX];
1973 text_t t = *tp++; 1931 text_t t = *tp++;
1974 if (t == NOCHAR) 1932 if (t == NOCHAR)
1975 continue; 1933 continue;
2135 * D: CopyArea pass - very useful for slower links 2093 * D: CopyArea pass - very useful for slower links
2136 * This has been deliberately kept simple. 2094 * This has been deliberately kept simple.
2137 */ 2095 */
2138 i = num_scr; 2096 i = num_scr;
2139 if (!display->is_local 2097 if (!display->is_local
2140 && refresh_type == FAST_REFRESH && num_scr_allow && i 2098 && refresh_type == FAST_REFRESH && num_scr_allow && num_scr
2141 && abs (i) < nrow && !must_clear) 2099 && abs (num_scr) < nrow && !must_clear)
2142 { 2100 {
2143 int16_t nits; 2101 int16_t nits;
2144 int j; 2102 int j;
2145 int len, wlen; 2103 int len, wlen;
2146 2104
2149 row = i > 0 ? 0 : j - 1; 2107 row = i > 0 ? 0 : j - 1;
2150 for (; j-- >= 0; row += (i > 0 ? 1 : -1)) 2108 for (; j-- >= 0; row += (i > 0 ? 1 : -1))
2151 { 2109 {
2152 if (row + i >= 0 && row + i < nrow && row + i != ocrow) 2110 if (row + i >= 0 && row + i < nrow && row + i != ocrow)
2153 { 2111 {
2154 line_t s = save[(row + row_offset) % nlines]; 2112 line_t s = save[(row + row_offset) % total_rows];
2155 line_t d = drawn[row]; 2113 line_t d = drawn[row];
2156 line_t d2 = drawn[row + i]; 2114 line_t d2 = drawn[row + i];
2157 2115
2158 for (nits = 0, col = ncol; col--; ) 2116 for (nits = 0, col = ncol; col--; )
2159 if (s.t[col] != d2.t[col] || s.r[col] != d2.r[col]) 2117 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++) 3329 for (int end_row = selection.mark.row; end_row < nrow; end_row++)
3372 { 3330 {
3373 if (!ROW(end_row).is_longer ()) 3331 if (!ROW(end_row).is_longer ())
3374 { 3332 {
3375 selection.end.row = end_row; 3333 selection.end.row = end_row;
3376 selection.end.col = save[end_row + saveLines].l; 3334 selection.end.col = ROW(end_row).l;
3377 selection_remove_trailing_spaces (); 3335 selection_remove_trailing_spaces ();
3378 break; 3336 break;
3379 } 3337 }
3380 } 3338 }
3381 } 3339 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines