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.380 by sf-exg, Thu Apr 7 12:19:41 2011 UTC vs.
Revision 1.414 by sf-exg, Tue Jan 24 17:05:05 2012 UTC

203 term_start = 0; 203 term_start = 0;
204 204
205 talloc = new rxvt_salloc (ncol * sizeof (text_t)); 205 talloc = new rxvt_salloc (ncol * sizeof (text_t));
206 ralloc = new rxvt_salloc (ncol * sizeof (rend_t)); 206 ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
207 207
208 row_buf = (line_t *)rxvt_calloc (total_rows + nrow, sizeof (line_t)); 208 row_buf = (line_t *)rxvt_calloc (total_rows , sizeof (line_t));
209 drawn_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t)); 209 drawn_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t));
210 swap_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t)); 210 swap_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t));
211 211
212 for (int row = nrow; row--; ) 212 for (int row = nrow; row--; )
213 { 213 {
275 swap_buf [row].clear (); scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE); 275 swap_buf [row].clear (); scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
276 drawn_buf[row].clear (); scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE); 276 drawn_buf[row].clear (); scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
277 } 277 }
278 278
279 line_t *old_buf = row_buf; 279 line_t *old_buf = row_buf;
280 row_buf = (line_t *)rxvt_calloc (total_rows + nrow, sizeof (line_t)); 280 row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
281 281
282 int p = MOD (term_start + prev_nrow, prev_total_rows); // previous row 282 int p = MOD (term_start + prev_nrow, prev_total_rows); // previous row
283 int pend = MOD (term_start + top_row , prev_total_rows); 283 int pend = MOD (term_start + top_row , prev_total_rows);
284 int q = total_rows; // rewrapped row 284 int q = total_rows; // rewrapped row
285 285
455 scr_clear (true); 455 scr_clear (true);
456 scr_refresh (); 456 scr_refresh ();
457} 457}
458 458
459void 459void
460rxvt_term::scr_soft_reset () 460rxvt_term::scr_soft_reset () NOTHROW
461{ 461{
462 /* only affects modes, nothing drastic such as clearing the screen */ 462 /* only affects modes, nothing drastic such as clearing the screen */
463#if ENABLE_OVERLAY 463#if ENABLE_OVERLAY
464 scr_overlay_off (); 464 scr_overlay_off ();
465#endif 465#endif
520 assert (s->cur.row >= 0); 520 assert (s->cur.row >= 0);
521 assert (s->cur.col >= 0); 521 assert (s->cur.col >= 0);
522} 522}
523 523
524void 524void
525rxvt_term::scr_swap_screen () 525rxvt_term::scr_swap_screen () NOTHROW
526{ 526{
527 if (!option (Opt_secondaryScreen)) 527 if (!option (Opt_secondaryScreen))
528 return; 528 return;
529 529
530 for (int i = prev_nrow; i--; ) 530 for (int i = prev_nrow; i--; )
549 return; 549 return;
550 550
551 want_refresh = 1; 551 want_refresh = 1;
552 view_start = 0; 552 view_start = 0;
553 553
554 selection_check (2); /* check for boundary cross */ 554 /* check for boundary cross */
555 row_col_t pos;
556 pos.row = pos.col = 0;
557 if (ROWCOL_IS_BEFORE (selection.beg, pos)
558 && ROWCOL_IS_AFTER (selection.end, pos))
559 CLEAR_SELECTION ();
555 560
556 current_screen = scrn; 561 current_screen = scrn;
557 562
558#if NSCREENS 563#if NSCREENS
559 if (option (Opt_secondaryScreen)) 564 if (option (Opt_secondaryScreen))
638 643
639 if (count > 0 644 if (count > 0
640 && row1 == 0 645 && row1 == 0
641 && (current_screen == PRIMARY || option (Opt_secondaryScroll))) 646 && (current_screen == PRIMARY || option (Opt_secondaryScroll)))
642 { 647 {
648 min_it (count, total_rows - (nrow - (row2 + 1)));
649
643 top_row = max (top_row - count, -saveLines); 650 top_row = max (top_row - count, -saveLines);
644
645 // scroll everything up 'count' lines
646 term_start = (term_start + count) % total_rows;
647 651
648 // sever bottommost line 652 // sever bottommost line
649 { 653 {
650 line_t &l = ROW(row2 - count); 654 line_t &l = ROW(row2);
651 l.is_longer (0); 655 l.is_longer (0);
652 l.touch (); 656 l.touch ();
653 } 657 }
654 658
659 // scroll everything up 'count' lines
660 term_start = (term_start + count) % total_rows;
661
662 // now copy lines below the scroll region bottom to the
663 // bottom of the screen again, so they look as if they
664 // hadn't moved.
665 for (int i = nrow; --i > row2; )
666 {
667 line_t &l1 = ROW(i - count);
668 line_t &l2 = ROW(i);
669
670 ::swap (l1, l2);
671 l2.touch ();
672 }
673
655 // erase newly scrolled-in lines 674 // erase newly scrolled-in lines
656 for (int i = count; i--; ) 675 for (int i = count; i--; )
657 { 676 {
658 line_t &l = ROW(nrow - 1 - i); 677 line_t &l = ROW(row2 - i);
659 678
660 // optimize if already cleared, can be significant on slow machines 679 // optimise if already cleared, can be significant on slow machines
661 // could be rolled into scr_blank_screen_mem 680 // could be rolled into scr_blank_screen_mem
662 if (l.r && l.l < ncol - 1 && !((l.r[l.l + 1] ^ rstyle) & (RS_fgMask | RS_bgMask))) 681 if (l.r && l.l < ncol - 1 && !((l.r[l.l + 1] ^ rstyle) & (RS_fgMask | RS_bgMask)))
663 { 682 {
664 scr_blank_line (l, 0, l.l, rstyle); 683 scr_blank_line (l, 0, l.l, rstyle);
665 l.l = 0; 684 l.l = 0;
667 } 686 }
668 else 687 else
669 scr_blank_screen_mem (l, rstyle); 688 scr_blank_screen_mem (l, rstyle);
670 } 689 }
671 690
672 // now copy lines below the scroll region bottom to the
673 // bottom of the screen again, so they look as if they
674 // hadn't moved.
675 for (int i = nrow; --i > row2; )
676 {
677 line_t &l1 = ROW(i - count);
678 line_t &l2 = ROW(i);
679
680 ::swap (l1, l2);
681 l2.touch ();
682 }
683
684 // move and/or clear selection, if any 691 // move and/or clear selection, if any
685 if (selection.op && current_screen == selection.screen) 692 if (selection.op && current_screen == selection.screen
693 && selection.beg.row <= row2)
686 { 694 {
687 selection.beg.row -= count; 695 selection.beg.row -= count;
688 selection.end.row -= count; 696 selection.end.row -= count;
689 selection.mark.row -= count; 697 selection.mark.row -= count;
690 698
691 if (selection.beg.row < top_row 699 selection_check (0);
692 || selection.end.row < top_row
693 || selection.mark.row < top_row)
694 {
695 CLEAR_ALL_SELECTION ();
696 selection.op = SELECTION_CLEAR;
697 }
698 } 700 }
699 701
700 // finally move the view window, if desired 702 // finally move the view window, if desired
701 if (option (Opt_scrollWithBuffer) 703 if (option (Opt_scrollWithBuffer)
702 && view_start != 0 704 && view_start != 0
732 } 734 }
733 735
734 // use a simple and robust scrolling algorithm, this 736 // use a simple and robust scrolling algorithm, this
735 // part of scr_scroll_text is not time-critical. 737 // part of scr_scroll_text is not time-critical.
736 738
739 // sever line above scroll region
740 if (row1)
741 {
742 line_t &l = ROW(row1 - 1);
743 l.is_longer (0);
744 l.touch ();
745 }
746
737 int rows = row2 - row1 + 1; 747 int rows = row2 - row1 + 1;
738 748
739 min_it (count, rows); 749 min_it (count, rows);
740 750
741 line_t *temp_buf = row_buf + total_rows; 751 line_t *temp_buf = rxvt_temp_buf<line_t> (rows);
742 752
743 for (int row = 0; row < rows; row++) 753 for (int row = 0; row < rows; row++)
744 { 754 {
745 temp_buf [row] = ROW(row1 + (row + count + rows) % rows); 755 temp_buf [row] = ROW(row1 + (row + count + rows) % rows);
746 756
748 scr_blank_screen_mem (temp_buf [row], rstyle); 758 scr_blank_screen_mem (temp_buf [row], rstyle);
749 } 759 }
750 760
751 for (int row = 0; row < rows; row++) 761 for (int row = 0; row < rows; row++)
752 ROW(row1 + row) = temp_buf [row]; 762 ROW(row1 + row) = temp_buf [row];
763
764 // sever bottommost line
765 {
766 line_t &l = ROW(row2);
767 l.is_longer (0);
768 l.touch ();
769 }
753 } 770 }
754 771
755 return count; 772 return count;
756} 773}
757 774
763rxvt_term::scr_add_lines (const wchar_t *str, int len, int minlines) NOTHROW 780rxvt_term::scr_add_lines (const wchar_t *str, int len, int minlines) NOTHROW
764{ 781{
765 if (len <= 0) /* sanity */ 782 if (len <= 0) /* sanity */
766 return; 783 return;
767 784
768 unsigned char checksel; 785 bool checksel;
769 unicode_t c; 786 unicode_t c;
770 int ncol = this->ncol; 787 int ncol = this->ncol;
771 const wchar_t *strend = str + len; 788 const wchar_t *strend = str + len;
772 789
773 want_refresh = 1; 790 want_refresh = 1;
799 816
800 while (str < strend) 817 while (str < strend)
801 { 818 {
802 c = (unicode_t)*str++; // convert to rxvt-unicodes representation 819 c = (unicode_t)*str++; // convert to rxvt-unicodes representation
803 820
804 if (expect_false (c < 0x20)) 821 if (ecb_unlikely (c < 0x20))
805 if (c == C0_LF) 822 if (c == C0_LF)
806 { 823 {
807 max_it (line->l, screen.cur.col); 824 max_it (line->l, screen.cur.col);
808 825
809 screen.flags &= ~Screen_WrapNext; 826 screen.flags &= ~Screen_WrapNext;
828 { 845 {
829 scr_tab (1, true); 846 scr_tab (1, true);
830 continue; 847 continue;
831 } 848 }
832 849
833 if (expect_false ( 850 if (ecb_unlikely (
834 checksel /* see if we're writing within selection */ 851 checksel /* see if we're writing within selection */
835 && !ROWCOL_IS_BEFORE (screen.cur, selection.beg) 852 && !ROWCOL_IS_BEFORE (screen.cur, selection.beg)
836 && ROWCOL_IS_BEFORE (screen.cur, selection.end) 853 && ROWCOL_IS_BEFORE (screen.cur, selection.end)
837 )) 854 ))
838 { 855 {
843 * should be a similar check. 860 * should be a similar check.
844 */ 861 */
845 CLEAR_SELECTION (); 862 CLEAR_SELECTION ();
846 } 863 }
847 864
848 if (expect_false (screen.flags & Screen_WrapNext)) 865 if (ecb_unlikely (screen.flags & Screen_WrapNext))
849 { 866 {
850 scr_do_wrap (); 867 scr_do_wrap ();
851 868
852 line->l = ncol; 869 line->l = ncol;
853 line->is_longer (1); 870 line->is_longer (1);
855 row = screen.cur.row; 872 row = screen.cur.row;
856 line = &ROW(row); /* _must_ refresh */ 873 line = &ROW(row); /* _must_ refresh */
857 } 874 }
858 875
859 // some utf-8 decoders "decode" surrogate characters: let's fix this. 876 // some utf-8 decoders "decode" surrogate characters: let's fix this.
860 if (expect_false (IN_RANGE_INC (c, 0xd800, 0xdfff))) 877 if (ecb_unlikely (IN_RANGE_INC (c, 0xd800, 0xdfff)))
861 c = 0xfffd; 878 c = 0xfffd;
862 879
863 // rely on wcwidth to tell us the character width, do wcwidth before 880 // rely on wcwidth to tell us the character width, do wcwidth before
864 // further replacements, as wcwidth might return -1 for the line 881 // further replacements, as wcwidth might return -1 for the line
865 // drawing characters below as they might be invalid in the current 882 // drawing characters below as they might be invalid in the current
866 // locale. 883 // locale.
867 int width = WCWIDTH (c); 884 int width = WCWIDTH (c);
868 885
869 if (expect_false (charsets [screen.charset] == '0')) // DEC SPECIAL 886 if (ecb_unlikely (charsets [screen.charset] == '0')) // DEC SPECIAL
870 { 887 {
871 // vt100 special graphics and line drawing 888 // vt100 special graphics and line drawing
872 // 5f-7e standard vt100 889 // 5f-7e standard vt100
873 // 40-5e rxvt extension for extra curses acs chars 890 // 40-5e rxvt extension for extra curses acs chars
874 static uint16_t vt100_0[62] = { // 41 .. 7e 891 static uint16_t vt100_0[62] = { // 41 .. 7e
887 c = vt100_0[c - 0x41]; 904 c = vt100_0[c - 0x41];
888 width = 1; // vt100 line drawing characters are always single-width 905 width = 1; // vt100 line drawing characters are always single-width
889 } 906 }
890 } 907 }
891 908
892 if (expect_false (screen.flags & Screen_Insert)) 909 if (ecb_unlikely (screen.flags & Screen_Insert))
893 scr_insdel_chars (width, INSERT); 910 scr_insdel_chars (width, INSERT);
894 911
895 if (width != 0) 912 if (width != 0)
896 { 913 {
897#if !UNICODE_3 914#if !UNICODE_3
905#endif 922#endif
906 923
907 rend_t rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c)); 924 rend_t rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c));
908 925
909 // if the character doesn't fit into the remaining columns... 926 // if the character doesn't fit into the remaining columns...
910 if (expect_false (screen.cur.col > ncol - width && ncol >= width)) 927 if (ecb_unlikely (screen.cur.col > ncol - width && ncol >= width))
911 { 928 {
912 if (screen.flags & Screen_Autowrap) 929 if (screen.flags & Screen_Autowrap)
913 { 930 {
914 // ... artificially enlargen the previous one 931 // ... artificially enlargen the previous one
915 c = NOCHAR; 932 c = NOCHAR;
922 939
923 // nuke the character at this position, if required 940 // nuke the character at this position, if required
924 // due to wonderful coincidences everywhere else in this loop 941 // due to wonderful coincidences everywhere else in this loop
925 // we never have to check for overwriting a wide char itself, 942 // we never have to check for overwriting a wide char itself,
926 // only its tail. 943 // only its tail.
927 if (expect_false (line->t[screen.cur.col] == NOCHAR)) 944 if (ecb_unlikely (line->t[screen.cur.col] == NOCHAR))
928 scr_kill_char (*line, screen.cur.col); 945 scr_kill_char (*line, screen.cur.col);
929 946
930 line->touch (); 947 line->touch ();
931 948
932 do 949 do
933 { 950 {
934 line->t[screen.cur.col] = c; 951 line->t[screen.cur.col] = c;
935 line->r[screen.cur.col] = rend; 952 line->r[screen.cur.col] = rend;
936 953
937 if (expect_true (screen.cur.col < ncol - 1)) 954 if (ecb_likely (screen.cur.col < ncol - 1))
938 screen.cur.col++; 955 screen.cur.col++;
939 else 956 else
940 { 957 {
941 line->l = ncol; 958 line->l = ncol;
942 if (screen.flags & Screen_Autowrap) 959 if (screen.flags & Screen_Autowrap)
945 goto end_of_line; 962 goto end_of_line;
946 } 963 }
947 964
948 c = NOCHAR; 965 c = NOCHAR;
949 } 966 }
950 while (expect_false (--width > 0)); 967 while (ecb_unlikely (--width > 0));
951 968
952 // pad with spaces when overwriting wide character with smaller one 969 // pad with spaces when overwriting wide character with smaller one
953 for (int c = screen.cur.col; expect_false (c < ncol && line->t[c] == NOCHAR); c++) 970 for (int c = screen.cur.col; ecb_unlikely (c < ncol && line->t[c] == NOCHAR); c++)
954 { 971 {
955 line->t[c] = ' '; 972 line->t[c] = ' ';
956 line->r[c] = rend; 973 line->r[c] = rend;
957 } 974 }
958 975
1295 scr_blank_line (line, col, num, rstyle); 1312 scr_blank_line (line, col, num, rstyle);
1296} 1313}
1297 1314
1298/* ------------------------------------------------------------------------- */ 1315/* ------------------------------------------------------------------------- */
1299/* 1316/*
1300 * Erase part of whole of the screen 1317 * Erase part or whole of the screen
1301 * XTERM_SEQ: Clear screen after cursor : ESC [ 0 J 1318 * XTERM_SEQ: Clear screen after cursor : ESC [ 0 J
1302 * XTERM_SEQ: Clear screen before cursor: ESC [ 1 J 1319 * XTERM_SEQ: Clear screen before cursor: ESC [ 1 J
1303 * XTERM_SEQ: Clear whole screen : ESC [ 2 J 1320 * XTERM_SEQ: Clear whole screen : ESC [ 2 J
1304 */ 1321 */
1305void 1322void
1314 ZERO_SCROLLBACK (); 1331 ZERO_SCROLLBACK ();
1315 1332
1316 switch (mode) 1333 switch (mode)
1317 { 1334 {
1318 case 0: /* erase to end of screen */ 1335 case 0: /* erase to end of screen */
1319 selection_check (1);
1320 scr_erase_line (0); 1336 scr_erase_line (0);
1321 row = screen.cur.row + 1; /* possible OOB */ 1337 row = screen.cur.row + 1; /* possible OOB */
1322 num = nrow - row; 1338 num = nrow - row;
1323 break; 1339 break;
1324 case 1: /* erase to beginning of screen */ 1340 case 1: /* erase to beginning of screen */
1325 selection_check (3);
1326 scr_erase_line (1); 1341 scr_erase_line (1);
1327 row = 0; 1342 row = 0;
1328 num = screen.cur.row; 1343 num = screen.cur.row;
1329 break; 1344 break;
1330 case 2: /* erase whole screen */ 1345 case 2: /* erase whole screen */
1331 selection_check (3);
1332 row = 0; 1346 row = 0;
1333 num = nrow; 1347 num = nrow;
1334 break; 1348 break;
1335 default: 1349 default:
1336 return; 1350 return;
1353 { 1367 {
1354 ren = DEFAULT_RSTYLE; 1368 ren = DEFAULT_RSTYLE;
1355 1369
1356 if (mapped) 1370 if (mapped)
1357 XClearArea (dpy, vt, 0, 1371 XClearArea (dpy, vt, 0,
1358 Row2Pixel (row - view_start), (unsigned int)width, 1372 Row2Pixel (row - view_start), (unsigned int)vt_width,
1359 (unsigned int)Height2Pixel (num), False); 1373 (unsigned int)Height2Pixel (num), False);
1360 } 1374 }
1361 else 1375 else
1362 { 1376 {
1363 ren = rstyle & (RS_fgMask | RS_bgMask); 1377 ren = rstyle & (RS_fgMask | RS_bgMask);
1366 { 1380 {
1367 gcvalue.foreground = pix_colors[bgcolor_of (rstyle)]; 1381 gcvalue.foreground = pix_colors[bgcolor_of (rstyle)];
1368 XChangeGC (dpy, gc, GCForeground, &gcvalue); 1382 XChangeGC (dpy, gc, GCForeground, &gcvalue);
1369 XFillRectangle (dpy, vt, gc, 1383 XFillRectangle (dpy, vt, gc,
1370 0, Row2Pixel (row - view_start), 1384 0, Row2Pixel (row - view_start),
1371 (unsigned int)width, 1385 (unsigned int)vt_width,
1372 (unsigned int)Height2Pixel (num)); 1386 (unsigned int)Height2Pixel (num));
1373 gcvalue.foreground = pix_colors[Color_fg]; 1387 gcvalue.foreground = pix_colors[Color_fg];
1374 XChangeGC (dpy, gc, GCForeground, &gcvalue); 1388 XChangeGC (dpy, gc, GCForeground, &gcvalue);
1375 } 1389 }
1376 } 1390 }
1407 1421
1408 want_refresh = 1; 1422 want_refresh = 1;
1409 ZERO_SCROLLBACK (); 1423 ZERO_SCROLLBACK ();
1410 1424
1411 num_scr_allow = 0; 1425 num_scr_allow = 0;
1412 selection_check (3); 1426
1427 row_col_t pos;
1428 pos.row = pos.col = 0;
1429 if (ROWCOL_IS_AFTER (selection.end, pos))
1430 CLEAR_SELECTION ();
1413 1431
1414 fs = SET_FONT (rstyle, FONTSET (rstyle)->find_font ('E')); 1432 fs = SET_FONT (rstyle, FONTSET (rstyle)->find_font ('E'));
1415 for (int row = nrow; row--; ) 1433 for (int row = nrow; row--; )
1416 { 1434 {
1417 line_t &line = ROW(row); 1435 line_t &line = ROW(row);
1858 * Refresh the entire screen 1876 * Refresh the entire screen
1859 */ 1877 */
1860void 1878void
1861rxvt_term::scr_touch (bool refresh) NOTHROW 1879rxvt_term::scr_touch (bool refresh) NOTHROW
1862{ 1880{
1863 scr_expose (0, 0, width, height, refresh); 1881 scr_expose (0, 0, vt_width, vt_height, refresh);
1864} 1882}
1865 1883
1866/* ------------------------------------------------------------------------- */ 1884/* ------------------------------------------------------------------------- */
1867/* 1885/*
1868 * Move the display so that the line represented by scrollbar value Y is at 1886 * Move the display so that the line represented by scrollbar value Y is at
1947 HOOK_INVOKE ((this, HOOK_BELL, DT_END)); 1965 HOOK_INVOKE ((this, HOOK_BELL, DT_END));
1948#endif 1966#endif
1949} 1967}
1950 1968
1951/* ------------------------------------------------------------------------- */ 1969/* ------------------------------------------------------------------------- */
1952/* ARGSUSED */
1953void 1970void
1954rxvt_term::scr_printscreen (int fullhist) NOTHROW 1971rxvt_term::scr_printscreen (int fullhist) NOTHROW
1955{ 1972{
1956#ifdef PRINTPIPE 1973#ifdef PRINTPIPE
1957 int nrows, row_start; 1974 int nrows, row_start;
2031 * A: set up vars 2048 * A: set up vars
2032 */ 2049 */
2033 refresh_count = 0; 2050 refresh_count = 0;
2034 2051
2035 unsigned int old_screen_flags = screen.flags; 2052 unsigned int old_screen_flags = screen.flags;
2036 char have_bg = 0; 2053 bool have_bg = 0;
2037#ifdef HAVE_BG_PIXMAP 2054#ifdef HAVE_BG_PIXMAP
2038 have_bg = bg_pixmap != None; 2055 have_bg = bg_pixmap != None;
2039#endif 2056#endif
2040 ocrow = oldcursor.row; /* is there an old outline cursor on screen? */ 2057 ocrow = oldcursor.row; /* is there an old outline cursor on screen? */
2041 2058
2047 HOOK_INVOKE ((this, HOOK_REFRESH_BEGIN, DT_END)); 2064 HOOK_INVOKE ((this, HOOK_REFRESH_BEGIN, DT_END));
2048#if ENABLE_OVERLAY 2065#if ENABLE_OVERLAY
2049 scr_swap_overlay (); 2066 scr_swap_overlay ();
2050#endif 2067#endif
2051 2068
2052 char showcursor = screen.flags & Screen_VisibleCursor; 2069 bool showcursor = screen.flags & Screen_VisibleCursor;
2053 2070
2054 /* 2071 /*
2055 * C: set the cursor character (s) 2072 * C: set the cursor character (s)
2056 */ 2073 */
2057 { 2074 {
2058 unsigned char setoldcursor; 2075 bool setoldcursor;
2059 2076
2060#ifdef CURSOR_BLINK 2077#ifdef CURSOR_BLINK
2061 if (hidden_cursor) 2078 if (hidden_cursor)
2062 showcursor = 0; 2079 showcursor = 0;
2063#endif 2080#endif
2150 { 2167 {
2151 int16_t nits; 2168 int16_t nits;
2152 int i = num_scr; 2169 int i = num_scr;
2153 int j; 2170 int j;
2154 int len, wlen; 2171 int len, wlen;
2155 dLocal (int, num_scr);
2156 2172
2157 j = nrow; 2173 j = nrow;
2158 wlen = len = -1; 2174 wlen = len = -1;
2159 row = i > 0 ? 0 : j - 1; 2175 row = i > 0 ? 0 : j - 1;
2160 2176
2235 continue; 2251 continue;
2236 2252
2237 // redraw one or more characters 2253 // redraw one or more characters
2238 2254
2239 // seek to the beginning of wide characters 2255 // seek to the beginning of wide characters
2240 while (expect_false (stp[col] == NOCHAR && col > 0)) 2256 while (ecb_unlikely (stp[col] == NOCHAR && col > 0))
2241 --col; 2257 --col;
2242 2258
2243 rend_t rend = srp[col]; /* screen rendition (target rendition) */ 2259 rend_t rend = srp[col]; /* screen rendition (target rendition) */
2244 text_t *text = stp + col; 2260 text_t *text = stp + col;
2245 int count = 1; 2261 int count = 1;
2283 2299
2284 col--; /* went one too far. move back */ 2300 col--; /* went one too far. move back */
2285 count -= i; /* dump any matching trailing chars */ 2301 count -= i; /* dump any matching trailing chars */
2286 2302
2287 // sometimes we optimize away the trailing NOCHAR's, add them back 2303 // sometimes we optimize away the trailing NOCHAR's, add them back
2288 while (expect_false (i && text[count] == NOCHAR)) 2304 while (ecb_unlikely (i && text[count] == NOCHAR))
2289 count++, i--; 2305 count++, i--;
2290 2306
2291 /* 2307 /*
2292 * Determine the attributes for the string 2308 * Determine the attributes for the string
2293 */ 2309 */
2294 int fore = fgcolor_of (rend); // desired foreground 2310 int fore = fgcolor_of (rend); // desired foreground
2295 int back = bgcolor_of (rend); // desired background 2311 int back = bgcolor_of (rend); // desired background
2296 2312
2297 // only do special processing if any attributes are set, which is unlikely 2313 // only do special processing if any attributes are set, which is unlikely
2298 if (expect_false (rend & (RS_baseattrMask | RS_Careful | RS_Sel))) 2314 if (ecb_unlikely (rend & (RS_baseattrMask | RS_Careful | RS_Sel)))
2299 { 2315 {
2300 bool invert = rend & RS_RVid; 2316 bool invert = rend & RS_RVid;
2301 2317
2302#ifndef NO_BOLD_UNDERLINE_REVERSE 2318#ifndef NO_BOLD_UNDERLINE_REVERSE
2303 if (rend & RS_Bold && fore == Color_fg) 2319 if (rend & RS_Bold && fore == Color_fg)
2392 /* 2408 /*
2393 * Actually do the drawing of the string here 2409 * Actually do the drawing of the string here
2394 */ 2410 */
2395 rxvt_font *font = (*fontset[GET_STYLE (rend)])[GET_FONT (rend)]; 2411 rxvt_font *font = (*fontset[GET_STYLE (rend)])[GET_FONT (rend)];
2396 2412
2397 if (expect_true (have_bg && back == Color_bg)) 2413 if (ecb_likely (have_bg && back == Color_bg))
2398 { 2414 {
2399 // this is very ugly, maybe push it into ->draw? 2415 // this is very ugly, maybe push it into ->draw?
2400 2416
2401 for (i = 0; i < count; i++) /* don't draw empty strings */ 2417 for (i = 0; i < count; i++) /* don't draw empty strings */
2402 if (text[i] != ' ') 2418 if (text[i] != ' ')
2409 did_clear: ; 2425 did_clear: ;
2410 } 2426 }
2411 else 2427 else
2412 font->draw (*drawable, xpixel, ypixel, text, count, fore, back); 2428 font->draw (*drawable, xpixel, ypixel, text, count, fore, back);
2413 2429
2414 if (expect_false (rend & RS_Uline && font->descent > 1 && fore != back)) 2430 if (ecb_unlikely (rend & RS_Uline && font->descent > 1 && fore != back))
2415 { 2431 {
2416#if ENABLE_FRILLS 2432#if ENABLE_FRILLS
2417 if (ISSET_PIXCOLOR (Color_underline)) 2433 if (ISSET_PIXCOLOR (Color_underline))
2418 XSetForeground (dpy, gc, pix_colors[Color_underline]); 2434 XSetForeground (dpy, gc, pix_colors[Color_underline]);
2419 else 2435 else
2465 2481
2466 XDrawRectangle (dpy, vt, gc, 2482 XDrawRectangle (dpy, vt, gc,
2467 Col2Pixel (col), 2483 Col2Pixel (col),
2468 Row2Pixel (oldcursor.row), 2484 Row2Pixel (oldcursor.row),
2469 (unsigned int) (Width2Pixel (cursorwidth) - 1), 2485 (unsigned int) (Width2Pixel (cursorwidth) - 1),
2470 (unsigned int) (Height2Pixel (1) - lineSpace - 1)); 2486 (unsigned int) (Height2Pixel (1) - 1));
2471 } 2487 }
2472 } 2488 }
2473 2489
2474 /* 2490 /*
2475 * H: cleanup selection 2491 * H: cleanup selection
2547 { 2563 {
2548 if (transparent) 2564 if (transparent)
2549 XSetWindowBackgroundPixmap (dpy, scrollBar.win, ParentRelative); 2565 XSetWindowBackgroundPixmap (dpy, scrollBar.win, ParentRelative);
2550 else 2566 else
2551 XSetWindowBackground (dpy, scrollBar.win, pix_colors[Color_border]); 2567 XSetWindowBackground (dpy, scrollBar.win, pix_colors[Color_border]);
2552 scrollBar.state = STATE_IDLE; 2568 scrollBar.state = SB_STATE_IDLE;
2553 scrollBar.show (0); 2569 scrollBar.show (0);
2554 } 2570 }
2555 2571
2556 if (refresh) 2572 if (refresh)
2557 { 2573 {
2651 */ 2667 */
2652#if 0 2668#if 0
2653void 2669void
2654rxvt_term::scr_dump (int fd) NOTHROW 2670rxvt_term::scr_dump (int fd) NOTHROW
2655{ 2671{
2656 int row, wrote; 2672 // if this method is needed, it can be implemented by factoring the
2657 unsigned int width, towrite; 2673 // relevant code in scr_printscreen
2658 const char r1[] = "\n";
2659
2660 for (row = saveLines + top_row;
2661 row < saveLines + nrow - 1; row++)
2662 {
2663 width = row_buf[row].l >= 0 ? row_buf[row].l
2664 : ncol;
2665 for (towrite = width; towrite; towrite -= wrote)
2666 {
2667 wrote = write (fd, & (row_buf[row].t[width - towrite]),
2668 towrite);
2669 if (wrote < 0)
2670 return; /* XXX: death, no report */
2671 }
2672 if (row_buf[row].l >= 0)
2673 if (write (fd, r1, 1) <= 0)
2674 return; /* XXX: death, no report */
2675 }
2676} 2674}
2677#endif 2675#endif
2678 2676
2679/* ------------------------------------------------------------------------- * 2677/* ------------------------------------------------------------------------- *
2680 * CHARACTER SELECTION * 2678 * CHARACTER SELECTION *
2681 * ------------------------------------------------------------------------- */ 2679 * ------------------------------------------------------------------------- */
2682void 2680void
2683rxvt_term::selection_check (int check_more) NOTHROW 2681rxvt_term::selection_check (int check_more) NOTHROW
2684{ 2682{
2685 row_col_t pos;
2686
2687 if (!selection.op) 2683 if (!selection.op)
2688 return; 2684 return;
2689 2685
2690 pos.row = pos.col = 0;
2691 if (!IN_RANGE_EXC (selection.beg.row, top_row, nrow) 2686 if (!IN_RANGE_EXC (selection.beg.row, top_row, nrow)
2692 || !IN_RANGE_EXC (selection.mark.row, top_row, nrow) 2687 || !IN_RANGE_EXC (selection.mark.row, top_row, nrow)
2693 || !IN_RANGE_EXC (selection.end.row, top_row, nrow) 2688 || !IN_RANGE_EXC (selection.end.row, top_row, nrow)
2694 || (check_more == 1 2689 || (check_more == 1
2695 && current_screen == selection.screen 2690 && current_screen == selection.screen
2696 && !ROWCOL_IS_BEFORE (screen.cur, selection.beg) 2691 && !ROWCOL_IS_BEFORE (screen.cur, selection.beg)
2697 && ROWCOL_IS_BEFORE (screen.cur, selection.end)) 2692 && ROWCOL_IS_BEFORE (screen.cur, selection.end)))
2698 || (check_more == 2
2699 && ROWCOL_IS_BEFORE (selection.beg, pos)
2700 && ROWCOL_IS_AFTER (selection.end, pos))
2701 || (check_more == 3
2702 && ROWCOL_IS_AFTER (selection.end, pos))
2703 || (check_more == 4 /* screen width change */
2704 && (selection.beg.row != selection.end.row
2705 || selection.end.col > ncol)))
2706 CLEAR_SELECTION (); 2693 CLEAR_ALL_SELECTION ();
2707} 2694}
2708 2695
2709/* ------------------------------------------------------------------------- */ 2696/* ------------------------------------------------------------------------- */
2710/* 2697/*
2711 * Paste a selection direct to the command fd 2698 * Paste a selection direct to the command fd
2717 for (unsigned int i = 0; i < len; i++) 2704 for (unsigned int i = 0; i < len; i++)
2718 if (data[i] == C0_LF) 2705 if (data[i] == C0_LF)
2719 data[i] = C0_CR; 2706 data[i] = C0_CR;
2720 2707
2721 if (priv_modes & PrivMode_BracketPaste) 2708 if (priv_modes & PrivMode_BracketPaste)
2722 tt_printf ("\e[200~"); 2709 tt_printf ("\x1b[200~");
2723 2710
2724 tt_write (data, len); 2711 tt_write (data, len);
2725 2712
2726 if (priv_modes & PrivMode_BracketPaste) 2713 if (priv_modes & PrivMode_BracketPaste)
2727 tt_printf ("\e[201~"); 2714 tt_printf ("\x1b[201~");
2728} 2715}
2729 2716
2730void 2717void
2731rxvt_term::paste (char *data, unsigned int len) NOTHROW 2718rxvt_term::paste (char *data, unsigned int len) NOTHROW
2732{ 2719{
2736 tt_paste (data, len); 2723 tt_paste (data, len);
2737} 2724}
2738 2725
2739/* ------------------------------------------------------------------------- */ 2726/* ------------------------------------------------------------------------- */
2740/* 2727/*
2741 * Request the current selection: 2728 * Request PRIMARY, SECONDARY or CLIPBOARD selection.
2742 * Order: > internal selection if available 2729 * if the requested selection has no owner or is empty CUT_BUFFER0 is used
2743 * > PRIMARY, SECONDARY, CLIPBOARD if ownership is claimed (+) 2730 * as fallback
2744 * > CUT_BUFFER0
2745 * (+) if ownership is claimed but property is empty, rxvt_selection_paste ()
2746 * will auto fallback to CUT_BUFFER0
2747 * EXT: button 2 release 2731 * EXT: button 2 release
2748 */ 2732 */
2749void 2733void
2750rxvt_term::selection_request (Time tm, int selnum) NOTHROW 2734rxvt_term::selection_request (Time tm, int selnum) NOTHROW
2751{ 2735{
3405 * EXT: SelectionRequest 3389 * EXT: SelectionRequest
3406 */ 3390 */
3407void 3391void
3408rxvt_term::selection_send (const XSelectionRequestEvent &rq) NOTHROW 3392rxvt_term::selection_send (const XSelectionRequestEvent &rq) NOTHROW
3409{ 3393{
3394 Atom property = rq.property == None ? rq.target : rq.property;
3410 XSelectionEvent ev; 3395 XSelectionEvent ev;
3411 3396
3412 ev.type = SelectionNotify; 3397 ev.type = SelectionNotify;
3413 ev.property = None; 3398 ev.property = None;
3414 ev.display = rq.display; 3399 ev.display = rq.display;
3429 *target++ = xa[XA_COMPOUND_TEXT]; 3414 *target++ = xa[XA_COMPOUND_TEXT];
3430#if X_HAVE_UTF8_STRING 3415#if X_HAVE_UTF8_STRING
3431 *target++ = xa[XA_UTF8_STRING]; 3416 *target++ = xa[XA_UTF8_STRING];
3432#endif 3417#endif
3433 3418
3434 XChangeProperty (dpy, rq.requestor, rq.property, XA_ATOM, 3419 XChangeProperty (dpy, rq.requestor, property, XA_ATOM,
3435 32, PropModeReplace, 3420 32, PropModeReplace,
3436 (unsigned char *)target_list, target - target_list); 3421 (unsigned char *)target_list, target - target_list);
3437 ev.property = rq.property; 3422 ev.property = property;
3438 } 3423 }
3439#if TODO // TODO 3424#if TODO // TODO
3440 else if (rq.target == xa[XA_MULTIPLE]) 3425 else if (rq.target == xa[XA_MULTIPLE])
3441 { 3426 {
3442 /* TODO: Handle MULTIPLE */ 3427 /* TODO: Handle MULTIPLE */
3443 } 3428 }
3444#endif 3429#endif
3445 else if (rq.target == xa[XA_TIMESTAMP] && rq.selection == XA_PRIMARY && selection.text) 3430 else if (rq.target == xa[XA_TIMESTAMP] && rq.selection == XA_PRIMARY && selection.text)
3446 { 3431 {
3447 XChangeProperty (dpy, rq.requestor, rq.property, rq.target, 3432 XChangeProperty (dpy, rq.requestor, property, rq.target,
3448 32, PropModeReplace, (unsigned char *)&selection_time, 1); 3433 32, PropModeReplace, (unsigned char *)&selection_time, 1);
3449 ev.property = rq.property; 3434 ev.property = property;
3450 } 3435 }
3451 else if (rq.target == xa[XA_TIMESTAMP] && rq.selection == xa[XA_CLIPBOARD] && selection.clip_text) 3436 else if (rq.target == xa[XA_TIMESTAMP] && rq.selection == xa[XA_CLIPBOARD] && selection.clip_text)
3452 { 3437 {
3453 XChangeProperty (dpy, rq.requestor, rq.property, rq.target, 3438 XChangeProperty (dpy, rq.requestor, property, rq.target,
3454 32, PropModeReplace, (unsigned char *)&clipboard_time, 1); 3439 32, PropModeReplace, (unsigned char *)&clipboard_time, 1);
3455 ev.property = rq.property; 3440 ev.property = property;
3456 } 3441 }
3457 else if (rq.target == XA_STRING 3442 else if (rq.target == XA_STRING
3458 || rq.target == xa[XA_TEXT] 3443 || rq.target == xa[XA_TEXT]
3459 || rq.target == xa[XA_COMPOUND_TEXT] 3444 || rq.target == xa[XA_COMPOUND_TEXT]
3460 || rq.target == xa[XA_UTF8_STRING] 3445 || rq.target == xa[XA_UTF8_STRING]
3531 ct.value = (unsigned char *)cl; 3516 ct.value = (unsigned char *)cl;
3532 ct.nitems = selectlen; 3517 ct.nitems = selectlen;
3533 ct.encoding = target; 3518 ct.encoding = target;
3534 } 3519 }
3535 3520
3536 XChangeProperty (dpy, rq.requestor, rq.property, 3521 XChangeProperty (dpy, rq.requestor, property,
3537 ct.encoding, 8, PropModeReplace, 3522 ct.encoding, 8, PropModeReplace,
3538 ct.value, (int)ct.nitems); 3523 ct.value, (int)ct.nitems);
3539 ev.property = rq.property; 3524 ev.property = property;
3540 3525
3541 if (freect) 3526 if (freect)
3542 XFree (ct.value); 3527 XFree (ct.value);
3543 } 3528 }
3544 3529

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines