--- rxvt-unicode/src/screen.C 2007/08/13 22:41:34 1.274 +++ rxvt-unicode/src/screen.C 2008/07/15 16:41:22 1.308 @@ -3,7 +3,7 @@ *---------------------------------------------------------------------------* * * Copyright (c) 1997-2001 Geoff Wing - * Copyright (c) 2003-2006 Marc Lehmann + * Copyright (c) 2003-2007 Marc Lehmann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +32,7 @@ #include "salloc.C" // HACK, should be a seperate compile! -inline void fill_text (text_t *start, text_t value, int len) +static inline void fill_text (text_t *start, text_t value, int len) { while (len--) *start++ = value; @@ -85,30 +85,14 @@ ROW_AND_COL_IN_ROW_AT_OR_BEFORE ((X).row, (X).col, (Y).row, (Y).col) /* - * CLEAR_ROWS : clear rows starting from row * CLEAR_CHARS: clear chars starting from pixel position - * ERASE_ROWS : set rows starting from row to the foreground colour */ -#define drawBuffer vt - -#define CLEAR_ROWS(row, num) \ - if (mapped) \ - XClearArea (dpy, drawBuffer, 0, \ - Row2Pixel (row), (unsigned int)width, \ - (unsigned int)Height2Pixel (num), False) - #define CLEAR_CHARS(x, y, num) \ - if (mapped) \ - XClearArea (dpy, drawBuffer, x, y, \ + if (mapped) \ + XClearArea (dpy, vt, x, y, \ (unsigned int)Width2Pixel (num), \ (unsigned int)Height2Pixel (1), False) -#define ERASE_ROWS(row, num) \ - XFillRectangle (dpy, drawBuffer, gc, \ - 0, Row2Pixel (row), \ - (unsigned int)width, \ - (unsigned int)Height2Pixel (num)) - /* ------------------------------------------------------------------------- * * SCREEN `COMMON' ROUTINES * * ------------------------------------------------------------------------- */ @@ -276,7 +260,7 @@ line_t *old_buf = row_buf; row_buf = (line_t *)rxvt_calloc (total_rows + nrow, sizeof (line_t)); - + int p = MOD (term_start + prev_nrow, prev_total_rows); // previous row int pend = MOD (term_start + top_row , prev_total_rows); int q = total_rows; // rewrapped row @@ -330,7 +314,7 @@ // see below for cursor adjustment rationale if (p == ocur.row) screen.cur.row = q - (total_rows - nrow); - + // fill a single destination line while (lofs < llen && qcol < ncol) { @@ -366,7 +350,7 @@ term_start = total_rows - nrow; top_row = q - term_start; - + // make sure all terminal lines exist while (top_row > 0) scr_blank_screen_mem (ROW (--top_row), DEFAULT_RSTYLE); @@ -374,7 +358,7 @@ else { // if no scrollback exists (yet), wing, instead of wrap - + for (int row = min (nrow, prev_nrow); row--; ) { line_t &pline = old_buf [MOD (term_start + row, prev_total_rows)]; @@ -407,7 +391,7 @@ prev_nrow = nrow; prev_ncol = ncol; - tabs = (char *)rxvt_malloc (ncol * sizeof (char)); + tabs = (char *)rxvt_malloc (ncol); for (int col = ncol; --col; ) tabs [col] = col % TABSIZE == 0; @@ -598,14 +582,14 @@ */ void rxvt_term::scr_rendition (int set, int style) NOTHROW - { - if (set) - rstyle |= style; - else if (style == ~RS_None) - rstyle = DEFAULT_RSTYLE; - else - rstyle &= ~style; - } +{ + if (set) + rstyle |= style; + else if (style == ~RS_None) + rstyle = DEFAULT_RSTYLE; + else + rstyle &= ~style; +} /* ------------------------------------------------------------------------- */ /* @@ -666,7 +650,7 @@ ::swap (l1, l2); l2.touch (); } - + // move and/or clear selection, if any if (selection.op && current_screen == selection.screen) { @@ -712,7 +696,7 @@ selection.beg.row -= count; selection.end.row -= count; selection.mark.row -= count; - + selection_check (0); } } @@ -834,7 +818,7 @@ if (screen.flags & Screen_WrapNext) { scr_do_wrap (); - + line->l = ncol; line->is_longer (1); @@ -1013,23 +997,20 @@ void rxvt_term::scr_backspace () NOTHROW { - want_refresh = 1; - if (screen.cur.col == 0) { if (screen.cur.row > 0) { #ifdef TERMCAP_HAS_BW screen.cur.col = ncol - 1; - screen.cur.row--; - return; + --screen.cur.row; + + want_refresh = 1; #endif } } - else if (!(screen.flags & Screen_WrapNext)) + else scr_gotorc (0, -1, RELATIVE); - - screen.flags &= ~Screen_WrapNext; } /* ------------------------------------------------------------------------- */ @@ -1062,7 +1043,7 @@ if (!--count) break; } - else + else ht &= l.t[i] == ' ' && RS_SAME (l.r[i], base_rend); @@ -1188,7 +1169,8 @@ else { if (screen.flags & Screen_Relative) - { /* relative origin mode */ + { + /* relative origin mode */ screen.cur.row = row + screen.tscroll; min_it (screen.cur.row, screen.bscroll); } @@ -1231,6 +1213,7 @@ * XTERM_SEQ: Clear line to right: ESC [ 0 K * XTERM_SEQ: Clear line to left : ESC [ 1 K * XTERM_SEQ: Clear whole line : ESC [ 2 K + * extension: clear to right unless wrapped: ESC [ 3 K */ void rxvt_term::scr_erase_line (int mode) NOTHROW @@ -1249,21 +1232,31 @@ switch (mode) { + case 3: + if (screen.flags & Screen_WrapNext) + return; + + /* fall through */ + case 0: /* erase to end of line */ col = screen.cur.col; num = ncol - col; min_it (line.l, col); + if (ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur) || ROWCOL_IN_ROW_AT_OR_AFTER (selection.end, screen.cur)) CLEAR_SELECTION (); break; + case 1: /* erase to beginning of line */ col = 0; num = screen.cur.col + 1; + if (ROWCOL_IN_ROW_AT_OR_BEFORE (selection.beg, screen.cur) || ROWCOL_IN_ROW_AT_OR_BEFORE (selection.end, screen.cur)) CLEAR_SELECTION (); break; + case 2: /* erase whole line */ col = 0; num = ncol; @@ -1331,19 +1324,28 @@ min_it (num, nrow - row); + /*TODO: the xlceararea/xfillrectangle below don't take scroll offste into account, ask mikachu for details */ if (rstyle & (RS_RVid | RS_Uline)) ren = (rend_t) ~RS_None; else if (GET_BASEBG (rstyle) == Color_bg) { ren = DEFAULT_RSTYLE; - CLEAR_ROWS (row, num); + + if (mapped) + XClearArea (dpy, vt, 0, + Row2Pixel (row), (unsigned int)width, + (unsigned int)Height2Pixel (num), False); } else { ren = rstyle & (RS_fgMask | RS_bgMask); + gcvalue.foreground = pix_colors[bgcolor_of (rstyle)]; XChangeGC (dpy, gc, GCForeground, &gcvalue); - ERASE_ROWS (row, num); + XFillRectangle (dpy, vt, gc, + 0, Row2Pixel (row), + (unsigned int)width, + (unsigned int)Height2Pixel (num)); gcvalue.foreground = pix_colors[Color_fg]; XChangeGC (dpy, gc, GCForeground, &gcvalue); } @@ -1474,7 +1476,8 @@ || (selection.end.col + count >= ncol)) CLEAR_SELECTION (); else - { /* shift selection */ + { + /* shift selection */ selection.beg.col += count; selection.mark.col += count; /* XXX: yes? */ selection.end.col += count; @@ -1623,7 +1626,7 @@ rxvt_term::scr_set_tab (int mode) NOTHROW { if (mode < 0) - memset (tabs, 0, ncol * sizeof (char)); + memset (tabs, 0, ncol); else if (screen.cur.col < ncol) tabs [screen.cur.col] = !!mode; } @@ -1803,7 +1806,7 @@ min_it (rc[i].col, ncol - 1); min_it (rc[i].row, nrow - 1); } - +// TODO: this line somehow causes segfault if scr_expose() is called just after resize for (i = rc[PART_BEG].row; i <= rc[PART_END].row; i++) fill_text (&drawn_buf[i].t[rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1); @@ -1868,10 +1871,11 @@ #ifndef NO_BELL void -rxvt_term::bell_cb (time_watcher &w) +rxvt_term::bell_cb (ev::timer &w, int revents) { rvideo_bell = false; scr_rvideo_mode (rvideo_mode); + refresh_check (); } #endif @@ -1887,16 +1891,14 @@ # endif XMapWindow (dpy, parent[0]); # endif + # if ENABLE_FRILLS if (option (Opt_urgentOnBell)) { - XWMHints *h; - - h = XGetWMHints(dpy, parent[0]); - if (h != NULL) + if (XWMHints *h = XGetWMHints(dpy, parent[0])) { h->flags |= XUrgencyHint; - XSetWMHints(dpy, parent[0], h); + XSetWMHints (dpy, parent[0], h); } } # endif @@ -1905,9 +1907,9 @@ { rvideo_bell = true; scr_rvideo_mode (rvideo_mode); - display->flush (); + flush (); - bell_ev.start (NOW + VISUAL_BELL_DURATION); + bell_ev.start (VISUAL_BELL_DURATION); } else XBell (dpy, 0); @@ -1921,9 +1923,9 @@ { #ifdef PRINTPIPE int nrows, row_start; - FILE *fd; + FILE *fd = popen_printer (); - if ((fd = popen_printer ()) == NULL) + if (!fd) return; if (fullhist) @@ -1998,11 +2000,11 @@ /* * A: set up vars */ - have_bg = 0; refresh_count = 0; + have_bg = 0; #ifdef HAVE_BG_PIXMAP - have_bg |= bgPixmap.pixmap != None; + have_bg = bgPixmap.pixmap != None; #endif ocrow = oldcursor.row; /* is there an old outline cursor on screen? */ @@ -2265,8 +2267,7 @@ bool invert = rend & RS_RVid; #ifndef NO_BOLD_UNDERLINE_REVERSE - if (rend & RS_Bold - && fore == Color_fg) + if (rend & RS_Bold && fore == Color_fg) { if (ISSET_PIXCOLOR (Color_BD)) fore = Color_BD; @@ -2276,8 +2277,7 @@ # endif } - if (rend & RS_Italic - && fore == Color_fg) + if (rend & RS_Italic && fore == Color_fg) { if (ISSET_PIXCOLOR (Color_IT)) fore = Color_IT; @@ -2321,9 +2321,9 @@ #ifdef TEXT_BLINK if (rend & RS_Blink && (back == Color_bg || fore == Color_bg)) { - if (!text_blink_ev.active) + if (!text_blink_ev.is_active ()) { - text_blink_ev.start (NOW + TEXT_BLINK_INTERVAL); + text_blink_ev.again (); hidden_text = 0; } else if (hidden_text) @@ -2381,7 +2381,7 @@ #endif XSetForeground (dpy, gc, pix_colors[fore]); - XDrawLine (dpy, drawBuffer, gc, + XDrawLine (dpy, vt, gc, xpixel, ypixel + font->ascent + 1, xpixel + Width2Pixel (count) - 1, ypixel + font->ascent + 1); } @@ -2429,7 +2429,7 @@ #endif XSetForeground (dpy, gc, pix_colors[ccol1]); - XDrawRectangle (dpy, drawBuffer, gc, + XDrawRectangle (dpy, vt, gc, Col2Pixel (col), Row2Pixel (oldcursor.row), (unsigned int) (Width2Pixel (cursorwidth) - 1), @@ -2477,19 +2477,21 @@ #ifdef HAVE_BG_PIXMAP bgPixmap.apply (); #else + XSetWindowBackground (dpy, parent[0], pix_colors[Color_border]); XClearWindow (dpy, parent[0]); XSetWindowBackground (dpy, vt, pix_colors[Color_bg]); -# if HAVE_SCROLLBARS + if (scrollBar.win) { XSetWindowBackground (dpy, scrollBar.win, pix_colors[Color_border]); - scrollBar.setIdle (); - scrollbar_show (0); + scrollBar.state = STATE_IDLE; + scrollBar.show (0); } -# endif + #endif - + + /* bgPixmap.apply () does not do the following : */ scr_clear (); scr_touch (true); want_refresh = 1; @@ -2591,7 +2593,7 @@ unsigned int width, towrite; char r1[] = "\n"; - for (row = saveLines - nsaved; + for (row = saveLines + top_row; row < saveLines + nrow - 1; row++) { width = row_buf[row].l >= 0 ? row_buf[row].l @@ -2652,7 +2654,13 @@ if (data[i] == C0_LF) data[i] = C0_CR; + if (priv_modes & PrivMode_BracketPaste) + tt_printf ("\e[200~"); + tt_write (data, len); + + if (priv_modes & PrivMode_BracketPaste) + tt_printf ("\e[201~"); } /* ------------------------------------------------------------------------- */ @@ -2737,7 +2745,7 @@ selection_wait = Sel_incr; incr_buf_fill = 0; - incr_ev.start (NOW + 10); + incr_ev.start (10); goto bailout; } @@ -2756,7 +2764,7 @@ incr_buf_size = 0; incr_ev.stop (); } - else + else { if (selection_wait == Sel_normal && (win != display->root || prop != XA_CUT_BUFFER0)) // avoid recursion @@ -2773,7 +2781,7 @@ } else if (selection_wait == Sel_incr) { - incr_ev.start (NOW + 10); + incr_ev.start (10); while (incr_buf_fill + ct.nitems > incr_buf_size) { @@ -2823,7 +2831,7 @@ } void -rxvt_term::incr_cb (time_watcher &w) NOTHROW +rxvt_term::incr_cb (ev::timer &w, int revents) NOTHROW { selection_wait = Sel_none; @@ -2844,7 +2852,7 @@ /* ------------------------------------------------------------------------- */ /* - * Request the current selection: + * Request the current selection: * Order: > internal selection if available * > PRIMARY, SECONDARY, CLIPBOARD if ownership is claimed (+) * > CUT_BUFFER0 @@ -2856,7 +2864,8 @@ rxvt_term::selection_request (Time tm, int selnum) NOTHROW { if (selection.text && selnum == Sel_Primary) - { /* internal selection */ + { + /* internal selection */ char *str = rxvt_wcstombs (selection.text, selection.len); paste (str, strlen (str)); free (str); @@ -3132,9 +3141,10 @@ while (selection.mark.col > 0 && ROW(selection.mark.row).t[selection.mark.col] == NOCHAR) --selection.mark.col; - + if (selection.op) - { /* clear the old selection */ + { + /* clear the old selection */ selection.beg.row = selection.end.row = selection.mark.row; selection.beg.col = selection.end.col = selection.mark.col; } @@ -3333,7 +3343,8 @@ * time of the most recent button3 press */ if (button3 && buttonpress) - { /* button3 press */ + { + /* button3 press */ /* * first determine which edge of the selection we are closest to */ @@ -3361,7 +3372,8 @@ } } else - { /* button1 drag or button3 drag */ + { + /* button1 drag or button3 drag */ if (ROWCOL_IS_AFTER (selection.mark, pos)) { if (selection.mark.row == selection.end.row @@ -3452,7 +3464,8 @@ } if (button3 && buttonpress) - { /* mark may need to be changed */ + { + /* mark may need to be changed */ if (closeto == LEFT) { selection.mark.row = selection.end.row; @@ -3661,22 +3674,6 @@ XSendEvent (dpy, rq.requestor, False, 0L, (XEvent *)&ev); } - -/* ------------------------------------------------------------------------- * - * MOUSE ROUTINES * - * ------------------------------------------------------------------------- */ - -/* - * return col/row values corresponding to x/y pixel values - */ -void -rxvt_term::pixel_position (int *x, int *y) NOTHROW -{ - *x = Pixel2Col (*x); - /* max_it (*x, 0); min_it (*x, (int)ncol - 1); */ - *y = Pixel2Row (*y); - /* max_it (*y, 0); min_it (*y, (int)nrow - 1); */ -} /* ------------------------------------------------------------------------- */ #ifdef USE_XIM