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.182 by root, Wed Dec 21 10:35:47 2005 UTC vs.
Revision 1.202 by root, Sat Dec 31 17:16:17 2005 UTC

46 46
47/* ------------------------------------------------------------------------- * 47/* ------------------------------------------------------------------------- *
48 * GENERAL SCREEN AND SELECTION UPDATE ROUTINES * 48 * GENERAL SCREEN AND SELECTION UPDATE ROUTINES *
49 * ------------------------------------------------------------------------- */ 49 * ------------------------------------------------------------------------- */
50#define ZERO_SCROLLBACK() \ 50#define ZERO_SCROLLBACK() \
51 if (options & Opt_scrollTtyOutput) \ 51 if (OPTION (Opt_scrollTtyOutput)) \
52 view_start = 0 52 view_start = 0
53#define CLEAR_SELECTION() \ 53#define CLEAR_SELECTION() \
54 selection.beg.row = selection.beg.col \ 54 selection.beg.row = selection.beg.col \
55 = selection.end.row = selection.end.col = 0 55 = selection.end.row = selection.end.col = 0
56#define CLEAR_ALL_SELECTION() \ 56#define CLEAR_ALL_SELECTION() \
147} 147}
148 148
149/* ------------------------------------------------------------------------- * 149/* ------------------------------------------------------------------------- *
150 * SCREEN INITIALISATION * 150 * SCREEN INITIALISATION *
151 * ------------------------------------------------------------------------- */ 151 * ------------------------------------------------------------------------- */
152
152void 153void
153rxvt_term::scr_reset () 154rxvt_term::scr_reset ()
154{ 155{
155 unsigned int p, q;
156 int k;
157
158#if ENABLE_OVERLAY 156#if ENABLE_OVERLAY
159 scr_overlay_off (); 157 scr_overlay_off ();
160#endif 158#endif
161 159
162 view_start = 0; 160 view_start = 0;
172 return; 170 return;
173 171
174 // we need at least two lines for wrapping to work correctly 172 // we need at least two lines for wrapping to work correctly
175 if (nrow + saveLines < 2) 173 if (nrow + saveLines < 2)
176 { 174 {
175 //TODO//FIXME
177 saveLines++; 176 saveLines++;
178 prev_nrow--; 177 prev_nrow--;
179 nsaved++; 178 nsaved++;
180 } 179 }
181 180
185 total_rows = nrow + saveLines; 184 total_rows = nrow + saveLines;
186 185
187 screen.tscroll = 0; 186 screen.tscroll = 0;
188 screen.bscroll = nrow - 1; 187 screen.bscroll = nrow - 1;
189 188
190 if (!save) 189 if (!row_buf)
191 { 190 {
192 /* 191 /*
193 * first time called so just malloc everything: don't rely on realloc 192 * first time called so just malloc everything: don't rely on realloc
194 * Note: this is still needed so that all the scrollback lines are NULL 193 * Note: this is still needed so that all the scrollback lines are NULL
195 */ 194 */
197 term_start = 0; 196 term_start = 0;
198 197
199 talloc = new rxvt_salloc (ncol * sizeof (text_t)); 198 talloc = new rxvt_salloc (ncol * sizeof (text_t));
200 ralloc = new rxvt_salloc (ncol * sizeof (rend_t)); 199 ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
201 200
202 save = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
203 buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t)); 201 row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
202 temp_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
204 drawn = (line_t *)rxvt_calloc (nrow, sizeof (line_t)); 203 drawn_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t));
205 swap_save = (line_t *)rxvt_calloc (nrow, sizeof (line_t)); 204 swap_buf = (line_t *)rxvt_calloc (nrow , sizeof (line_t));
206 205
207 for (p = nrow; p--; ) 206 for (int row = nrow; row--; )
208 { 207 {
209 scr_blank_screen_mem (ROW(p), DEFAULT_RSTYLE); 208 scr_blank_screen_mem (ROW (row), DEFAULT_RSTYLE);
210 scr_blank_screen_mem (swap_save[p], DEFAULT_RSTYLE); 209 scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
211 scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE); 210 scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
212 } 211 }
213 212
214 memset (charsets, 'B', sizeof (charsets)); 213 memset (charsets, 'B', sizeof (charsets));
215 rstyle = DEFAULT_RSTYLE; 214 rstyle = DEFAULT_RSTYLE;
216 screen.flags = Screen_DefaultFlags; 215 screen.flags = Screen_DefaultFlags;
240 { 239 {
241 /* 240 /*
242 * add or delete rows as appropriate 241 * add or delete rows as appropriate
243 */ 242 */
244 243
245 rxvt_salloc *old_ta; 244 rxvt_salloc *old_ta = talloc; talloc = new rxvt_salloc (ncol * sizeof (text_t));
246 rxvt_salloc *old_ra; 245 rxvt_salloc *old_ra = ralloc; ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
247 246
247#if 0
248 if (nrow < prev_nrow) 248 if (nrow < prev_nrow)
249 { 249 {
250 /* delete rows */
251 k = min (nsaved, prev_nrow - nrow);
252 // k = max (0, - ( (nrow - 1) - r->screen.cur.row)); // mmc's http://maruska.dyndns.org/wiki/scrolling-bug //make configurable? //D TODO
253 scr_scroll_text (0, (int)prev_nrow - 1, k);
254
255 for (p = nrow; p < prev_nrow; p++) 250 for (int row = nrow; row < prev_nrow; row++)
256 { 251 {
257 lfree (ROW(p));
258 lfree (swap_save[p]); 252 lfree (swap_buf [row]);
259 lfree (drawn[p]); 253 lfree (drawn_buf[row]);
260 } 254 }
255 }
256#endif
261 257
262 /* we have fewer rows so fix up cursor position */ 258 drawn_buf = (line_t *)rxvt_realloc (drawn_buf, nrow * sizeof (line_t));
263 MIN_IT (screen.cur.row, (int32_t)nrow - 1); 259 temp_buf = (line_t *)rxvt_realloc (temp_buf , nrow * sizeof (line_t));
260 swap_buf = (line_t *)rxvt_realloc (swap_buf , nrow * sizeof (line_t));
264 261
265 scr_reset_realloc (); /* realloc _last_ */ 262 for (int row = min (nrow, prev_nrow); row--; )
263 {
264 lresize (drawn_buf[row]);
265 lresize (swap_buf [row]);
266 }
267
268 for (int row = prev_nrow; row < nrow; row++)
269 {
270 swap_buf [row].clear (); scr_blank_screen_mem (swap_buf [row], DEFAULT_RSTYLE);
271 drawn_buf[row].clear (); scr_blank_screen_mem (drawn_buf[row], DEFAULT_RSTYLE);
272 }
273
274 line_t *old_buf = row_buf; row_buf = (line_t *)rxvt_calloc (total_rows, sizeof (line_t));
266 } 275
267 else if (nrow > prev_nrow) 276 int p = MOD (term_start + prev_nrow, prev_total_rows); // previous row
277 int pend = MOD (term_start - nsaved , prev_total_rows);
278 int q = total_rows; // rewrapped row
279
280 if (nsaved)
281 {
282 // re-wrap lines, this is rather ugly, possibly because I am too dumb
283 // to come up with a lean and mean algorithm.
284
285 row_col_t ocur = screen.cur;
286 ocur.row = MOD (term_start + ocur.row, prev_total_rows);
287
268 { 288 do
269 /* add rows */
270 scr_reset_realloc (); /* realloc _first_ */
271
272 int ocol = ncol;
273 ncol = prev_ncol; // save b/c scr_blank_screen_mem uses this
274
275 k = min (nsaved, nrow - prev_nrow);
276
277 for (p = prev_total_rows; p < total_rows; p++)
278 save[p].clear ();
279
280 for (p = prev_total_rows; p < total_rows - k; p++)
281 scr_blank_screen_mem (save[p], DEFAULT_RSTYLE);
282
283 for (p = prev_nrow; p < nrow; p++)
284 { 289 {
285 swap_save[p].clear (); scr_blank_screen_mem (swap_save[p], DEFAULT_RSTYLE); 290 p = MOD (p - 1, prev_total_rows);
286 drawn[p].clear (); scr_blank_screen_mem (drawn[p], DEFAULT_RSTYLE);
287 }
288
289 if (k > 0)
290 {
291 scr_scroll_text (0, (int)nrow - 1, -k);
292 screen.cur.row += k;
293 screen.s_cur.row += k;
294 nsaved -= k;
295 }
296
297#ifdef DEBUG_STRICT 291#ifdef DEBUG_STRICT
298 assert (screen.cur.row < nrow); 292 assert (old_buf [MOD (p, prev_total_rows)].t);
299#else /* drive with your eyes closed */
300 MIN_IT (screen.cur.row, nrow - 1);
301#endif 293#endif
302 ncol = ocol; // save b/c scr_blank_screen_mem uses this
303 }
304 294
305 /* resize columns */
306 if (ncol != prev_ncol)
307 {
308 old_ta = talloc; talloc = new rxvt_salloc (ncol * sizeof (text_t));
309 old_ra = ralloc; ralloc = new rxvt_salloc (ncol * sizeof (rend_t));
310
311 for (p = total_rows; p--; )
312 lresize (save[p]);
313
314 for (p = nrow; p--; )
315 {
316 lresize (drawn[p]);
317 lresize (swap_save[p]);
318 }
319
320 MIN_IT (screen.cur.col, (int16_t)ncol - 1);
321
322 delete old_ta;
323 delete old_ra;
324 }
325
326#if 0
327 // re-wrap lines, this is rather ugly, possibly because I am too dumb
328 // to come up with a lean and mean algorithm.
329 rxvt_salloc *ta = new rxvt_salloc (ncol * sizeof (text_t));
330 rxvt_salloc *ra = new rxvt_salloc (ncol * sizeof (rend_t));
331
332 text_t **tp = (text_t **)rxvt_calloc (total_rows, sizeof (text_t *));
333 rend_t **rp = (rend_t **)rxvt_calloc (total_rows, sizeof (rend_t *));
334 tlen_t *tl = (tlen_t *) rxvt_calloc (total_rows, sizeof (tlen_t));
335
336 for (p = 0; p < prev_total_rows; p++) printf ("P %p %d\n", save[p].t, save[p].l);//D
337
338 p = prev_total_rows;
339 q = total_rows;
340
341 while (p > 0 && q > 0)
342 {
343 --p;
344
345 printf ("pq %d:%d\n", p, q);
346 if (save[p].t)
347 {
348 int llen = save[p].l; 295 int plines = 1;
296 int llen = old_buf [MOD (p, prev_total_rows)].l;
349 297
350 assert (llen >= 0); 298 while (p != pend && old_buf [MOD (p - 1, prev_total_rows)].is_longer ())
351
352 while (p && save[p - 1].l < 0)
353 { 299 {
300 p = MOD (p - 1, prev_total_rows);
301
354 --p; 302 plines++;
355 llen += prev_ncol; 303 llen += prev_ncol;
356 } 304 }
357 305
358 int qlines = llen / ncol + 1; 306 int qlines = max (0, (llen - 1) / ncol) + 1;
307
308 // drop partial lines completely
309 if (q < qlines)
310 break;
311
312 q -= qlines;
313
359 int lofs = 0; 314 int lofs = 0;
315 line_t *qline;
360 316
361 q -= qlines; 317 // re-assemble the full line by destination lines
362
363 int qrow = q;
364
365 printf ("QL %d llen %d\n", qlines, llen);//D
366 for (; qlines--; qrow++) 318 for (int qrow = q; qlines--; qrow++)
367 { 319 {
320 qline = row_buf + qrow;
321 lalloc (*qline);
322 qline->set_is_longer ();
323
368 if (qrow >= 0) 324 int qcol = 0;
325
326 // fill a single destination line
327 while (lofs < llen && qcol < ncol)
369 { 328 {
370 tp [qrow] = (text_t *)ta->alloc ();
371 rp [qrow] = (rend_t *)ra->alloc ();
372 tl [qrow] = LINE_CONT1;
373
374 int qcol = 0;
375
376 for (;;)
377 {
378 int prow = lofs / prev_ncol + p; 329 int prow = lofs / prev_ncol;
379 int pcol = lofs % prev_ncol; 330 int pcol = lofs % prev_ncol;
380 331
332 prow = MOD (p + prow, prev_total_rows);
333
334 // we only adjust the cursor _row_ and put it into
335 // the topmost line of "long line" it was in, as
336 // this seems to upset applications/shells/readline
337 // least.
338 if (prow == ocur.row)
339 screen.cur.row = q - (total_rows - nrow);
340
341 line_t &pline = old_buf [prow];
342
381 int len = min (min (prev_ncol - pcol, ncol - qcol), llen - lofs); 343 int len = min (min (prev_ncol - pcol, ncol - qcol), llen - lofs);
382 344
383 printf ("q %d lofs %d>%d len %d pq %d:%d p %d:%d q :%d\n", q, llen, lofs, len, prev_ncol, ncol, prow, pcol, qcol);
384
385 if (len <= 0)
386 {
387 tl [qrow] = qcol;
388
389 TODO
390 scr_blank_line (tp [qrow] + qcol, rp [qrow] + qcol,
391 ncol - qcol, DEFAULT_RSTYLE);
392
393 break;
394 }
395
396 assert (lofs < 1000); 345 assert (len);
346 assert (pline.t);
397 347
398 memcpy (tp [qrow] + qcol, save[prow].t + pcol, len * sizeof (text_t)); 348 memcpy (qline->t + qcol, pline.t + pcol, len * sizeof (text_t));
399 memcpy (rp [qrow] + qcol, save[prow].r + pcol, len * sizeof (rend_t)); 349 memcpy (qline->r + qcol, pline.r + pcol, len * sizeof (rend_t));
400 350
401 lofs += len; 351 lofs += len;
402 qcol += len; 352 qcol += len;
403
404 if (qcol == ncol)
405 break;
406 }
407 } 353 }
408 else
409 lofs += ncol;
410 } 354 }
355
356 qline->l = llen ? MOD (llen - 1, ncol) + 1 : 0;
357#ifdef DEBUG_STRICT //TODO//FIXME//TEMPORARY
358 if (qline->l < 0)
359 {
360 fprintf (stderr, "ERROR, PLEASE REPORT to rxvt-unicode@plan9.de: qline->l %d = llen %d < ncol %d ? %d : MOD %d\n", qline->l,llen,ncol,llen,MOD (llen - 1, ncol) + 1);//D
361 qline->l = 0;
362 }
363#endif
364 scr_blank_line (*qline, qline->l, ncol - qline->l, DEFAULT_RSTYLE);
411 } 365 }
366 while (p != pend && q > 0);
367
368 term_start = total_rows - nrow;
369 nsaved = term_start - q;
370
371 // make sure all terminal lines exist
372 while (nsaved < 0)
373 scr_blank_screen_mem (ROW (-++nsaved), DEFAULT_RSTYLE);
374
375 }
376 else
412 } 377 {
378 // if no scrollback exists (yet), wing, instead of wrap
379
380 for (int row = min (nrow, prev_nrow); row--; )
381 {
382 line_t &pline = old_buf [MOD (term_start + row, prev_total_rows)];
383 line_t &qline = row_buf [row];
413 384
414 free (screen.text); screen.text = tp; 385 qline = pline;
415 free (screen.rend); screen.rend = rp; 386 lresize (qline);
416 free (screen.tlen); screen.tlen = tl; 387 }
417 388
418 for (p = 0; p < total_rows; p++) printf ("P %p %d\n", save[p].t, save[p].l);//D 389 for (int row = prev_nrow; row < nrow; row++)
390 {
391 row_buf [row].clear (); scr_blank_screen_mem (row_buf [row], DEFAULT_RSTYLE);
392 }
393
394 term_start = 0;
395 }
396
397#ifdef DEBUG_STRICT //TODO: remove
398 for (int i = -nsaved; i < nrow; i++)
399 assert (ROW (i).t);
419#endif 400#endif
401
402 free (old_buf);
403 delete old_ta;
404 delete old_ra;
405
406 clamp_it (screen.cur.row, 0, nrow - 1);
407 clamp_it (screen.cur.col, 0, ncol - 1);
420 408
421 if (tabs) 409 if (tabs)
422 free (tabs); 410 free (tabs);
423 } 411 }
424 412
425 prev_nrow = nrow; 413 prev_nrow = nrow;
426 prev_ncol = ncol; 414 prev_ncol = ncol;
427 415
428 tabs = (char *)rxvt_malloc (ncol * sizeof (char)); 416 tabs = (char *)rxvt_malloc (ncol * sizeof (char));
429 417
430 for (p = 0; p < ncol; p++) 418 for (int col = ncol; col--; )
431 tabs[p] = (p % TABSIZE == 0) ? 1 : 0; 419 tabs [col] = col % TABSIZE == 0;
432 420
433 tt_winch (); 421 tt_winch ();
434}
435
436void
437rxvt_term::scr_reset_realloc ()
438{
439 swap_save = (line_t *) rxvt_realloc (swap_save , nrow * sizeof (line_t));
440 drawn = (line_t *) rxvt_realloc (drawn , nrow * sizeof (line_t));
441 buf = (line_t *) rxvt_realloc (buf , nrow * sizeof (line_t));
442 save = (line_t *) rxvt_realloc (save , total_rows * sizeof (line_t));
443} 422}
444 423
445/* ------------------------------------------------------------------------- */ 424/* ------------------------------------------------------------------------- */
446/* 425/*
447 * Free everything. That way malloc debugging can find leakage. 426 * Free everything. That way malloc debugging can find leakage.
450rxvt_term::scr_release () 429rxvt_term::scr_release ()
451{ 430{
452 delete talloc; talloc = 0; 431 delete talloc; talloc = 0;
453 delete ralloc; ralloc = 0; 432 delete ralloc; ralloc = 0;
454 433
455 free (save); 434 free (row_buf);
456 free (swap_save); 435 free (swap_buf);
457 free (drawn); 436 free (drawn_buf);
458 free (buf); 437 free (temp_buf);
459 free (tabs); 438 free (tabs);
439
440 row_buf = 0; // signal that we freed all the arrays
460} 441}
461 442
462/* ------------------------------------------------------------------------- */ 443/* ------------------------------------------------------------------------- */
463/* 444/*
464 * Hard reset 445 * Hard reset
515 set_font_style (); 496 set_font_style ();
516 break; 497 break;
517 } 498 }
518 499
519 /* boundary check in case screen size changed between SAVE and RESTORE */ 500 /* boundary check in case screen size changed between SAVE and RESTORE */
520 MIN_IT (s->cur.row, nrow - 1); 501 min_it (s->cur.row, nrow - 1);
521 MIN_IT (s->cur.col, ncol - 1); 502 min_it (s->cur.col, ncol - 1);
522#ifdef DEBUG_STRICT 503#ifdef DEBUG_STRICT
523 assert (s->cur.row >= 0); 504 assert (s->cur.row >= 0);
524 assert (s->cur.col >= 0); 505 assert (s->cur.col >= 0);
525#else /* drive with your eyes closed */
526 MAX_IT (s->cur.row, 0);
527 MAX_IT (s->cur.col, 0);
528#endif 506#endif
529} 507}
530 508
531/* ------------------------------------------------------------------------- */ 509/* ------------------------------------------------------------------------- */
532/* 510/*
552 530
553 screen.cur.row = clamp (screen.cur.row, 0, prev_nrow - 1); 531 screen.cur.row = clamp (screen.cur.row, 0, prev_nrow - 1);
554 screen.cur.col = clamp (screen.cur.col, 0, prev_ncol - 1); 532 screen.cur.col = clamp (screen.cur.col, 0, prev_ncol - 1);
555 533
556#if NSCREENS 534#if NSCREENS
557 if (options & Opt_secondaryScreen) 535 if (OPTION (Opt_secondaryScreen))
558 { 536 {
559 num_scr = 0; 537 num_scr = 0;
560 538
561 for (int i = nrow; i--; ) 539 for (int i = prev_nrow; i--; )
562 ::swap (ROW(i), swap_save[i]); 540 ::swap (ROW(i), swap_buf [i]);
563 541
564 ::swap (screen.charset, swap.charset); 542 ::swap (screen.charset, swap.charset);
565 ::swap (screen.flags, swap.flags); 543 ::swap (screen.flags, swap.flags);
566 screen.flags |= Screen_VisibleCursor; 544 screen.flags |= Screen_VisibleCursor;
567 swap.flags |= Screen_VisibleCursor; 545 swap.flags |= Screen_VisibleCursor;
568 } 546 }
569 else 547 else
570#endif 548#endif
571 if (options & Opt_secondaryScroll) 549 if (OPTION (Opt_secondaryScroll))
572 scr_scroll_text (0, prev_nrow - 1, prev_nrow); 550 scr_scroll_text (0, prev_nrow - 1, prev_nrow);
573 551
574 return scrn; 552 return scrn;
575} 553}
576 554
638 num_scr += count; 616 num_scr += count;
639 617
640 if (count > 0 618 if (count > 0
641 && row1 == 0 619 && row1 == 0
642 && row2 == nrow - 1 620 && row2 == nrow - 1
643 && (current_screen == PRIMARY || options & Opt_secondaryScroll)) 621 && (current_screen == PRIMARY || OPTION (Opt_secondaryScroll)))
644 { 622 {
645 nsaved = min (nsaved + count, saveLines); 623 nsaved = min (nsaved + count, saveLines);
646 term_start = (term_start + count) % total_rows; 624 term_start = (term_start + count) % total_rows;
647 625
648 if (selection.op && current_screen == selection.screen) 626 if (selection.op && current_screen == selection.screen)
649 { 627 {
650 selection.beg.row -= count; 628 selection.beg.row -= count;
651 selection.end.row -= count; 629 selection.end.row -= count;
652 selection.mark.row -= count; 630 selection.mark.row -= count;
653 631
654 selection_check (0); 632 if (selection.beg.row < -nsaved
633 || selection.end.row < -nsaved
634 || selection.mark.row < -nsaved)
635 {
636 CLEAR_ALL_SELECTION ();
637 selection.op = SELECTION_CLEAR;
638 }
655 } 639 }
656 640
657 for (int i = count; i--; ) 641 for (int i = count; i--; )
642 {
643 ROW(row2 - i).l = 0;
658 scr_blank_screen_mem (ROW(row2 - i), rstyle); 644 scr_blank_screen_mem (ROW(row2 - i), rstyle);
645 }
659 646
660 if ((options & Opt_scrollWithBuffer) 647 if (OPTION (Opt_scrollWithBuffer)
661 && view_start != 0 648 && view_start != 0
662 && view_start != saveLines) 649 && view_start != saveLines)
663 scr_page (UP, count); 650 scr_page (UP, count);
664 } 651 }
665 else 652 else
666 { 653 {
667 if (selection.op && current_screen == selection.screen) 654 if (selection.op && current_screen == selection.screen)
668 { 655 {
669 int i = selection.beg.row; 656 if ((selection.beg.row < row1 && selection.end.row > row1)
670 int j = selection.end.row; 657 || (selection.beg.row < row2 && selection.end.row > row2)
671
672 if ((i < row1 && j > row1)
673 || (i < row2 && j > row2)
674 || (i - count < row1 && i >= row1) 658 || (selection.beg.row - count < row1 && selection.beg.row >= row1)
675 || (i - count > row2 && i <= row2) 659 || (selection.beg.row - count > row2 && selection.beg.row <= row2)
676 || (j - count < row1 && j >= row1) 660 || (selection.end.row - count < row1 && selection.end.row >= row1)
677 || (j - count > row2 && j <= row2)) 661 || (selection.end.row - count > row2 && selection.end.row <= row2))
678 { 662 {
679 CLEAR_ALL_SELECTION (); 663 CLEAR_ALL_SELECTION ();
680 selection.op = SELECTION_CLEAR; /* XXX: too aggressive? */ 664 selection.op = SELECTION_CLEAR;
681 } 665 }
682 else if (j >= row1 && j <= row2) 666 else if (selection.end.row >= row1 && selection.end.row <= row2)
683 { 667 {
684 /* move selected region too */ 668 /* move selected region too */
685 selection.beg.row -= count; 669 selection.beg.row -= count;
686 selection.end.row -= count; 670 selection.end.row -= count;
687 selection.mark.row -= count; 671 selection.mark.row -= count;
693 // use a simple and robust scrolling algorithm, this 677 // use a simple and robust scrolling algorithm, this
694 // part of scr_scroll_text is not time-critical. 678 // part of scr_scroll_text is not time-critical.
695 679
696 int rows = row2 - row1 + 1; 680 int rows = row2 - row1 + 1;
697 681
682 min_it (count, rows);
683
698 for (int row = 0; row < rows; row++) 684 for (int row = 0; row < rows; row++)
699 { 685 {
700 buf [row] = ROW(row1 + (row + count + rows) % rows); 686 temp_buf [row] = ROW(row1 + (row + count + rows) % rows);
701 687
702 if (!IN_RANGE_EXC (row + count, 0, rows)) 688 if (!IN_RANGE_EXC (row + count, 0, rows))
703 scr_blank_screen_mem (buf [row], rstyle); 689 scr_blank_screen_mem (temp_buf [row], rstyle);
704 } 690 }
705 691
706 for (int row = 0; row < rows; row++) 692 for (int row = 0; row < rows; row++)
707 ROW(row1 + row) = buf [row]; 693 ROW(row1 + row) = temp_buf [row];
708 } 694 }
709 695
710 return count; 696 return count;
711} 697}
712 698
720 if (len <= 0) /* sanity */ 706 if (len <= 0) /* sanity */
721 return; 707 return;
722 708
723 unsigned char checksel; 709 unsigned char checksel;
724 unicode_t c; 710 unicode_t c;
725 int row, last_col; 711 int last_col;
726 const unicode_t *strend = str + len; 712 const unicode_t *strend = str + len;
727 713
728 want_refresh = 1; 714 want_refresh = 1;
729 ZERO_SCROLLBACK (); 715 ZERO_SCROLLBACK ();
730 last_col = ncol; 716 last_col = ncol;
731 717
732 if (nlines > 0) 718 if (nlines > 0)
733 { 719 {
734 nlines += screen.cur.row - screen.bscroll; 720 nlines += screen.cur.row - screen.bscroll;
735 if ((nlines > 0) 721 if (nlines > 0
736 && (screen.tscroll == 0) 722 && screen.tscroll == 0
737 && (screen.bscroll == (nrow - 1))) 723 && screen.bscroll == (nrow - 1))
738 { 724 {
739 /* _at least_ this many lines need to be scrolled */ 725 /* _at least_ this many lines need to be scrolled */
740 scr_scroll_text (screen.tscroll, screen.bscroll, nlines); 726 scr_scroll_text (screen.tscroll, screen.bscroll, nlines);
741 screen.cur.row -= nlines; 727 screen.cur.row -= nlines;
742 } 728 }
743 } 729 }
744 730
745#ifdef DEBUG_STRICT 731#ifdef DEBUG_STRICT
746 assert (screen.cur.col < last_col); 732 assert (screen.cur.col < last_col);
747 assert ((screen.cur.row < nrow) 733 assert (screen.cur.row < nrow
748 && (screen.cur.row >= - (int32_t)nsaved)); 734 && screen.cur.row >= -nsaved);
749#else /* drive with your eyes closed */
750 MIN_IT (screen.cur.col, last_col - 1);
751 MIN_IT (screen.cur.row, (int32_t)nrow - 1);
752 MAX_IT (screen.cur.row, - (int32_t)nsaved);
753#endif 735#endif
754 row = screen.cur.row; 736 int row = screen.cur.row;
755 737
756 checksel = selection.op && current_screen == selection.screen ? 1 : 0; 738 checksel = selection.op && current_screen == selection.screen ? 1 : 0;
757 739
758 line_t *line = &ROW(row); 740 line_t *line = &ROW(row);
759 741
761 { 743 {
762 c = *str++; 744 c = *str++;
763 745
764 if (c < 0x20) 746 if (c < 0x20)
765 if (c == C0_LF) 747 if (c == C0_LF)
766 { 748 {
767 if (!line->is_longer ()) /* XXX: think about this */ 749 if (!line->is_longer ()) /* XXX: think about this */
768 MAX_IT (line->l, screen.cur.col); 750 max_it (line->l, screen.cur.col);
769 751
770 screen.flags &= ~Screen_WrapNext; 752 screen.flags &= ~Screen_WrapNext;
771 753
772 if (screen.cur.row == screen.bscroll) 754 if (screen.cur.row == screen.bscroll)
773 scr_scroll_text (screen.tscroll, screen.bscroll, 1); 755 scr_scroll_text (screen.tscroll, screen.bscroll, 1);
778 continue; 760 continue;
779 } 761 }
780 else if (c == C0_CR) 762 else if (c == C0_CR)
781 { 763 {
782 if (!line->is_longer ()) /* XXX: think about this */ 764 if (!line->is_longer ()) /* XXX: think about this */
783 MAX_IT (line->l, screen.cur.col); 765 max_it (line->l, screen.cur.col);
784 766
785 screen.flags &= ~Screen_WrapNext; 767 screen.flags &= ~Screen_WrapNext;
786 screen.cur.col = 0; 768 screen.cur.col = 0;
787 continue; 769 continue;
788 } 770 }
964#endif 946#endif
965 } 947 }
966 } 948 }
967 949
968 if (!line->is_longer ()) /* XXX: think about this */ 950 if (!line->is_longer ()) /* XXX: think about this */
969 MAX_IT (line->l, screen.cur.col); 951 max_it (line->l, screen.cur.col);
970 952
971#ifdef DEBUG_STRICT 953#ifdef DEBUG_STRICT
972 assert (screen.cur.row >= 0); 954 assert (screen.cur.row >= 0);
973#else /* drive with your eyes closed */
974 MAX_IT (screen.cur.row, 0);
975#endif 955#endif
976} 956}
977 957
978/* ------------------------------------------------------------------------- */ 958/* ------------------------------------------------------------------------- */
979/* 959/*
1018 998
1019 if (count == 0) 999 if (count == 0)
1020 return; 1000 return;
1021 else if (count > 0) 1001 else if (count > 0)
1022 { 1002 {
1023 int row = screen.cur.row;
1024
1025 line_t &l = ROW(row); 1003 line_t &l = ROW(screen.cur.row);
1026 rend_t base_rend = l.r[i]; 1004 rend_t base_rend = l.r[i];
1027 ht &= l.t[i] == ' '; 1005 ht &= l.t[i] == ' ';
1028 1006
1029 for (; ++i < ncol; ) 1007 for (; ++i < ncol; )
1030 if (tabs[i]) 1008 if (tabs[i])
1040 if (count) 1018 if (count)
1041 x = ncol - 1; 1019 x = ncol - 1;
1042 1020
1043 // store horizontal tab commands as characters inside the text 1021 // store horizontal tab commands as characters inside the text
1044 // buffer so they can be selected and pasted. 1022 // buffer so they can be selected and pasted.
1045 if (ht && options & Opt_pastableTabs) 1023 if (ht && OPTION (Opt_pastableTabs))
1046 { 1024 {
1047 base_rend = SET_FONT (base_rend, 0); 1025 base_rend = SET_FONT (base_rend, 0);
1048 1026
1049 if (!l.is_longer ()) /* XXX: think about this */ 1027 if (!l.is_longer ()) /* XXX: think about this */
1050 MAX_IT (l.l, x); 1028 max_it (l.l, x);
1051 1029
1052 i = screen.cur.col; 1030 i = screen.cur.col;
1053 1031
1054 l.t[i] = '\t'; 1032 l.t[i] = '\t';
1055 l.r[i] = base_rend; 1033 l.r[i] = base_rend;
1105 */ 1083 */
1106#if ENABLE_FRILLS 1084#if ENABLE_FRILLS
1107void 1085void
1108rxvt_term::scr_forwardindex () 1086rxvt_term::scr_forwardindex ()
1109{ 1087{
1110 int row;
1111
1112 if (screen.cur.col < ncol - 1) 1088 if (screen.cur.col < ncol - 1)
1113 scr_gotorc (0, 1, R_RELATIVE | C_RELATIVE); 1089 scr_gotorc (0, 1, R_RELATIVE | C_RELATIVE);
1114 else 1090 else
1115 { 1091 {
1116 row = screen.cur.row;
1117
1118 if (ROW(row).is_longer ()) //TODO//FIXME//LEN 1092 if (ROW(screen.cur.row).is_longer ()) //TODO//FIXME//LEN
1119 ROW(row).l = ncol; 1093 ROW(screen.cur.row).l = ncol;
1120 1094
1121 scr_gotorc (0, 0, R_RELATIVE); 1095 scr_gotorc (0, 0, R_RELATIVE);
1122 scr_insdel_chars (1, DELETE); 1096 scr_insdel_chars (1, DELETE);
1123 scr_gotorc (0, ncol - 1, R_RELATIVE); 1097 scr_gotorc (0, ncol - 1, R_RELATIVE);
1124 } 1098 }
1134{ 1108{
1135 want_refresh = 1; 1109 want_refresh = 1;
1136 ZERO_SCROLLBACK (); 1110 ZERO_SCROLLBACK ();
1137 1111
1138 screen.cur.col = relative & C_RELATIVE ? screen.cur.col + col : col; 1112 screen.cur.col = relative & C_RELATIVE ? screen.cur.col + col : col;
1139 MAX_IT (screen.cur.col, 0); 1113 clamp_it (screen.cur.col, 0, ncol - 1);
1140 MIN_IT (screen.cur.col, (int32_t)ncol - 1);
1141 1114
1142 screen.flags &= ~Screen_WrapNext; 1115 screen.flags &= ~Screen_WrapNext;
1143 1116
1144 if (relative & R_RELATIVE) 1117 if (relative & R_RELATIVE)
1145 { 1118 {
1163 else 1136 else
1164 { 1137 {
1165 if (screen.flags & Screen_Relative) 1138 if (screen.flags & Screen_Relative)
1166 { /* relative origin mode */ 1139 { /* relative origin mode */
1167 screen.cur.row = row + screen.tscroll; 1140 screen.cur.row = row + screen.tscroll;
1168 MIN_IT (screen.cur.row, screen.bscroll); 1141 min_it (screen.cur.row, screen.bscroll);
1169 } 1142 }
1170 else 1143 else
1171 screen.cur.row = row; 1144 screen.cur.row = row;
1172 } 1145 }
1173 1146
1174 MAX_IT (screen.cur.row, 0); 1147 clamp_it (screen.cur.row, 0, nrow - 1);
1175 MIN_IT (screen.cur.row, (int32_t)nrow - 1);
1176} 1148}
1177 1149
1178/* ------------------------------------------------------------------------- */ 1150/* ------------------------------------------------------------------------- */
1179/* 1151/*
1180 * direction should be UP or DN 1152 * direction should be UP or DN
1195 || (screen.cur.row == screen.tscroll && direction == DN)) 1167 || (screen.cur.row == screen.tscroll && direction == DN))
1196 scr_scroll_text (screen.tscroll, screen.bscroll, dirn); 1168 scr_scroll_text (screen.tscroll, screen.bscroll, dirn);
1197 else 1169 else
1198 screen.cur.row += dirn; 1170 screen.cur.row += dirn;
1199 1171
1200 MAX_IT (screen.cur.row, 0); 1172 clamp_it (screen.cur.row, 0, nrow - 1);
1201 MIN_IT (screen.cur.row, (int32_t)nrow - 1);
1202 selection_check (0); 1173 selection_check (0);
1203} 1174}
1204 1175
1205/* ------------------------------------------------------------------------- */ 1176/* ------------------------------------------------------------------------- */
1206/* 1177/*
1210 * XTERM_SEQ: Clear whole line : ESC [ 2 K 1181 * XTERM_SEQ: Clear whole line : ESC [ 2 K
1211 */ 1182 */
1212void 1183void
1213rxvt_term::scr_erase_line (int mode) 1184rxvt_term::scr_erase_line (int mode)
1214{ 1185{
1215 unsigned int row, col, num; 1186 unsigned int col, num;
1216 1187
1217 want_refresh = 1; 1188 want_refresh = 1;
1218 ZERO_SCROLLBACK (); 1189 ZERO_SCROLLBACK ();
1219 1190
1220 selection_check (1); 1191 selection_check (1);
1221 1192
1222 row = screen.cur.row; 1193 line_t &line = ROW(screen.cur.row);
1223 1194
1224 switch (mode) 1195 switch (mode)
1225 { 1196 {
1226 case 0: /* erase to end of line */ 1197 case 0: /* erase to end of line */
1227 col = screen.cur.col; 1198 col = screen.cur.col;
1228 num = ncol - col; 1199 num = ncol - col;
1229 MIN_IT (ROW(row).l, (int16_t)col); 1200 min_it (line.l, col);
1230 if (ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur) 1201 if (ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)
1231 || ROWCOL_IN_ROW_AT_OR_AFTER (selection.end, screen.cur)) 1202 || ROWCOL_IN_ROW_AT_OR_AFTER (selection.end, screen.cur))
1232 CLEAR_SELECTION (); 1203 CLEAR_SELECTION ();
1233 break; 1204 break;
1234 case 1: /* erase to beginning of line */ 1205 case 1: /* erase to beginning of line */
1239 CLEAR_SELECTION (); 1210 CLEAR_SELECTION ();
1240 break; 1211 break;
1241 case 2: /* erase whole line */ 1212 case 2: /* erase whole line */
1242 col = 0; 1213 col = 0;
1243 num = ncol; 1214 num = ncol;
1244 ROW(row).l = 0; 1215 line.l = 0;
1245 if (selection.beg.row <= screen.cur.row 1216 if (selection.beg.row <= screen.cur.row
1246 && selection.end.row >= screen.cur.row) 1217 && selection.end.row >= screen.cur.row)
1247 CLEAR_SELECTION (); 1218 CLEAR_SELECTION ();
1248 break; 1219 break;
1249 default: 1220 default:
1250 return; 1221 return;
1251 } 1222 }
1252 1223
1253 scr_blank_line (ROW(row), col, num, rstyle); 1224 scr_blank_line (line, col, num, rstyle);
1254} 1225}
1255 1226
1256/* ------------------------------------------------------------------------- */ 1227/* ------------------------------------------------------------------------- */
1257/* 1228/*
1258 * Erase part of whole of the screen 1229 * Erase part of whole of the screen
1301 CLEAR_SELECTION (); 1272 CLEAR_SELECTION ();
1302 1273
1303 if (row >= nrow) /* Out Of Bounds */ 1274 if (row >= nrow) /* Out Of Bounds */
1304 return; 1275 return;
1305 1276
1306 MIN_IT (num, (nrow - row)); 1277 min_it (num, nrow - row);
1307 1278
1308 if (rstyle & (RS_RVid | RS_Uline)) 1279 if (rstyle & (RS_RVid | RS_Uline))
1309 ren = (rend_t) ~RS_None; 1280 ren = (rend_t) ~RS_None;
1310 else if (GET_BASEBG (rstyle) == Color_bg) 1281 else if (GET_BASEBG (rstyle) == Color_bg)
1311 { 1282 {
1313 CLEAR_ROWS (row, num); 1284 CLEAR_ROWS (row, num);
1314 } 1285 }
1315 else 1286 else
1316 { 1287 {
1317 ren = rstyle & (RS_fgMask | RS_bgMask); 1288 ren = rstyle & (RS_fgMask | RS_bgMask);
1318 gcvalue.foreground = pix_colors[GET_BGCOLOR (rstyle)]; 1289 gcvalue.foreground = pix_colors[bgcolor_of (rstyle)];
1319 XChangeGC (display->display, gc, GCForeground, &gcvalue); 1290 XChangeGC (display->display, gc, GCForeground, &gcvalue);
1320 ERASE_ROWS (row, num); 1291 ERASE_ROWS (row, num);
1321 gcvalue.foreground = pix_colors[Color_fg]; 1292 gcvalue.foreground = pix_colors[Color_fg];
1322 XChangeGC (display->display, gc, GCForeground, &gcvalue); 1293 XChangeGC (display->display, gc, GCForeground, &gcvalue);
1323 } 1294 }
1324 1295
1325 for (; num--; row++) 1296 for (; num--; row++)
1326 { 1297 {
1298 ROW (row).l = 0;
1327 scr_blank_screen_mem (ROW (row), rstyle); 1299 scr_blank_screen_mem (ROW (row), rstyle);
1328 ROW (row).l = 0;
1329 scr_blank_line (drawn[row], 0, ncol, ren); 1300 scr_blank_line (drawn_buf [row], 0, ncol, ren);
1330 } 1301 }
1331} 1302}
1332 1303
1333#if ENABLE_FRILLS 1304#if ENABLE_FRILLS
1334void 1305void
1419 return; 1390 return;
1420 1391
1421 scr_do_wrap (); 1392 scr_do_wrap ();
1422 1393
1423 selection_check (1); 1394 selection_check (1);
1424 MIN_IT (count, (ncol - screen.cur.col)); 1395 min_it (count, ncol - screen.cur.col);
1425 1396
1426 row = screen.cur.row; 1397 row = screen.cur.row;
1427 1398
1428 line_t *line = &ROW(row); 1399 line_t *line = &ROW(row);
1429 1400
1437 } 1408 }
1438 1409
1439 if (!line->is_longer ()) 1410 if (!line->is_longer ())
1440 { 1411 {
1441 line->l += count; 1412 line->l += count;
1442 MIN_IT (line->l, ncol); 1413 min_it (line->l, ncol);
1443 } 1414 }
1444 1415
1445 if (selection.op && current_screen == selection.screen 1416 if (selection.op && current_screen == selection.screen
1446 && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur)) 1417 && ROWCOL_IN_ROW_AT_OR_AFTER (selection.beg, screen.cur))
1447 { 1418 {
1508 * XTERM_SEQ: Set region <top> - <bot> inclusive: ESC [ <top> ; <bot> r 1479 * XTERM_SEQ: Set region <top> - <bot> inclusive: ESC [ <top> ; <bot> r
1509 */ 1480 */
1510void 1481void
1511rxvt_term::scr_scroll_region (int top, int bot) 1482rxvt_term::scr_scroll_region (int top, int bot)
1512{ 1483{
1513 MAX_IT (top, 0); 1484 max_it (top, 0);
1514 MIN_IT (bot, (int)nrow - 1); 1485 min_it (bot, nrow - 1);
1515 1486
1516 if (top > bot) 1487 if (top > bot)
1517 return; 1488 return;
1518 1489
1519 screen.tscroll = top; 1490 screen.tscroll = top;
1622 ::swap (pix_colors[Color_fg], pix_colors[Color_bg]); 1593 ::swap (pix_colors[Color_fg], pix_colors[Color_bg]);
1623#if XPM_BACKGROUND 1594#if XPM_BACKGROUND
1624 if (bgPixmap.pixmap == None) 1595 if (bgPixmap.pixmap == None)
1625#endif 1596#endif
1626#if TRANSPARENT 1597#if TRANSPARENT
1627 if (! (options & Opt_transparent) || am_transparent == 0) 1598 if (! OPTION (Opt_transparent) || am_transparent == 0)
1628#endif 1599#endif
1629 XSetWindowBackground (display->display, vt, 1600 XSetWindowBackground (display->display, vt,
1630 pix_colors[Color_bg]); 1601 pix_colors[Color_bg]);
1631 1602
1632 gcvalue.foreground = pix_colors[Color_fg]; 1603 gcvalue.foreground = pix_colors[Color_fg];
1723 bool found = false; 1694 bool found = false;
1724 1695
1725 for (int i = 0; i < nrow; i++) 1696 for (int i = 0; i < nrow; i++)
1726 { 1697 {
1727 int col = 0; 1698 int col = 0;
1728 rend_t *drp = drawn[i].r; 1699 rend_t *drp = drawn_buf[i].r;
1729 1700
1730 for (; col < ncol; col++, drp++) 1701 for (; col < ncol; col++, drp++)
1731 if ((*drp & mask) == value) 1702 if ((*drp & mask) == value)
1732 { 1703 {
1733 found = true; 1704 found = true;
1751rxvt_term::scr_expose (int x, int y, int ewidth, int eheight, bool refresh) 1722rxvt_term::scr_expose (int x, int y, int ewidth, int eheight, bool refresh)
1752{ 1723{
1753 int i; 1724 int i;
1754 row_col_t rc[RC_COUNT]; 1725 row_col_t rc[RC_COUNT];
1755 1726
1756 if (!drawn) /* sanity check */ 1727 if (!drawn_buf) /* sanity check */
1757 return; 1728 return;
1758 1729
1759#ifndef NO_SLOW_LINK_SUPPORT 1730#ifndef NO_SLOW_LINK_SUPPORT
1760 if (refresh_type == FAST_REFRESH && !display->is_local) 1731 if (refresh_type == FAST_REFRESH && !display->is_local)
1761 { 1732 {
1762 y = 0; 1733 y = 0;
1763 eheight = height; 1734 eheight = height;
1764 } 1735 }
1765#endif
1766
1767#ifdef DEBUG_STRICT
1768 x = max (x, 0);
1769 x = min (x, (int)width);
1770 y = max (y, 0);
1771 y = min (y, (int)height);
1772#endif 1736#endif
1773 1737
1774 /* round down */ 1738 /* round down */
1775 rc[PART_BEG].col = Pixel2Col (x); 1739 rc[PART_BEG].col = Pixel2Col (x);
1776 rc[PART_BEG].row = Pixel2Row (y); 1740 rc[PART_BEG].row = Pixel2Row (y);
1779 rc[PART_END].row = Pixel2Row (y + eheight + fheight - 1); 1743 rc[PART_END].row = Pixel2Row (y + eheight + fheight - 1);
1780 1744
1781 /* sanity checks */ 1745 /* sanity checks */
1782 for (i = PART_BEG; i < RC_COUNT; i++) 1746 for (i = PART_BEG; i < RC_COUNT; i++)
1783 { 1747 {
1784 MIN_IT (rc[i].col, ncol - 1); 1748 min_it (rc[i].col, ncol - 1);
1785 MIN_IT (rc[i].row, nrow - 1); 1749 min_it (rc[i].row, nrow - 1);
1786 } 1750 }
1787 1751
1788 for (i = rc[PART_BEG].row; i <= rc[PART_END].row; i++) 1752 for (i = rc[PART_BEG].row; i <= rc[PART_END].row; i++)
1789 fill_text (&drawn[i].t[rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1); 1753 fill_text (&drawn_buf[i].t[rc[PART_BEG].col], 0, rc[PART_END].col - rc[PART_BEG].col + 1);
1790 1754
1791 if (refresh) 1755 if (refresh)
1792 scr_refresh (SLOW_REFRESH); 1756 scr_refresh (SLOW_REFRESH);
1793} 1757}
1794 1758
1872{ 1836{
1873#ifndef NO_BELL 1837#ifndef NO_BELL
1874 1838
1875# ifndef NO_MAPALERT 1839# ifndef NO_MAPALERT
1876# ifdef MAPALERT_OPTION 1840# ifdef MAPALERT_OPTION
1877 if (options & Opt_mapAlert) 1841 if (OPTION (Opt_mapAlert))
1878# endif 1842# endif
1879 XMapWindow (display->display, parent[0]); 1843 XMapWindow (display->display, parent[0]);
1880# endif 1844# endif
1881 1845
1882 if (options & Opt_visualBell) 1846 if (OPTION (Opt_visualBell))
1883 { 1847 {
1884 scr_rvideo_mode (!rvideo); /* refresh also done */ 1848 scr_rvideo_mode (!rvideo); /* refresh also done */
1885 rxvt_usleep (VISUAL_BELL_DURATION); 1849 rxvt_usleep (VISUAL_BELL_DURATION);
1886 scr_rvideo_mode (!rvideo); /* refresh also done */ 1850 scr_rvideo_mode (!rvideo); /* refresh also done */
1887 } 1851 }
1978 1942
1979#if XPM_BACKGROUND 1943#if XPM_BACKGROUND
1980 must_clear |= bgPixmap.pixmap != None; 1944 must_clear |= bgPixmap.pixmap != None;
1981#endif 1945#endif
1982#if TRANSPARENT 1946#if TRANSPARENT
1983 must_clear |= (options & Opt_transparent) && am_transparent; 1947 must_clear |= OPTION (Opt_transparent) && am_transparent;
1984#endif 1948#endif
1985 ocrow = oldcursor.row; /* is there an old outline cursor on screen? */ 1949 ocrow = oldcursor.row; /* is there an old outline cursor on screen? */
1986 1950
1987 /* 1951 /*
1988 * B: reverse any characters which are selected 1952 * B: reverse any characters which are selected
2012 1976
2013 crp = &ROW(screen.cur.row).r[col]; 1977 crp = &ROW(screen.cur.row).r[col];
2014 1978
2015 if (showcursor && focus) 1979 if (showcursor && focus)
2016 { 1980 {
2017 if (options & Opt_cursorUnderline) 1981 if (OPTION (Opt_cursorUnderline))
2018 *crp ^= RS_Uline; 1982 *crp ^= RS_Uline;
2019 else 1983 else
2020 { 1984 {
2021 *crp ^= RS_RVid; 1985 *crp ^= RS_RVid;
2022 1986
2024 cc1 = *crp & (RS_fgMask | RS_bgMask); 1988 cc1 = *crp & (RS_fgMask | RS_bgMask);
2025 if (ISSET_PIXCOLOR (Color_cursor)) 1989 if (ISSET_PIXCOLOR (Color_cursor))
2026 ccol1 = Color_cursor; 1990 ccol1 = Color_cursor;
2027 else 1991 else
2028#ifdef CURSOR_COLOR_IS_RENDITION_COLOR 1992#ifdef CURSOR_COLOR_IS_RENDITION_COLOR
2029 ccol1 = GET_FGCOLOR (rstyle); 1993 ccol1 = fgcolor_of (rstyle);
2030#else 1994#else
2031 ccol1 = Color_fg; 1995 ccol1 = Color_fg;
2032#endif 1996#endif
2033 if (ISSET_PIXCOLOR (Color_cursor2)) 1997 if (ISSET_PIXCOLOR (Color_cursor2))
2034 ccol2 = Color_cursor2; 1998 ccol2 = Color_cursor2;
2035 else 1999 else
2036#ifdef CURSOR_COLOR_IS_RENDITION_COLOR 2000#ifdef CURSOR_COLOR_IS_RENDITION_COLOR
2037 ccol2 = GET_BGCOLOR (rstyle); 2001 ccol2 = bgcolor_of (rstyle);
2038#else 2002#else
2039 ccol2 = Color_bg; 2003 ccol2 = Color_bg;
2040#endif 2004#endif
2041 *crp = SET_FGCOLOR (*crp, ccol1); 2005 *crp = SET_FGCOLOR (*crp, ccol1);
2042 *crp = SET_BGCOLOR (*crp, ccol2); 2006 *crp = SET_BGCOLOR (*crp, ccol2);
2052 if (screen.cur.row + view_start != ocrow 2016 if (screen.cur.row + view_start != ocrow
2053 || screen.cur.col != oldcursor.col) 2017 || screen.cur.col != oldcursor.col)
2054 { 2018 {
2055 if (ocrow < nrow 2019 if (ocrow < nrow
2056 && oldcursor.col < ncol) 2020 && oldcursor.col < ncol)
2057 drawn[ocrow].r[oldcursor.col] ^= (RS_RVid | RS_Uline); 2021 drawn_buf[ocrow].r[oldcursor.col] ^= (RS_RVid | RS_Uline);
2058 2022
2059 if (focus || !showcursor) 2023 if (focus || !showcursor)
2060 oldcursor.row = -1; 2024 oldcursor.row = -1;
2061 else 2025 else
2062 setoldcursor = 1; 2026 setoldcursor = 1;
2101 for (; j-- >= 0; row += (i > 0 ? 1 : -1)) 2065 for (; j-- >= 0; row += (i > 0 ? 1 : -1))
2102 { 2066 {
2103 if (row + i >= 0 && row + i < nrow && row + i != ocrow) 2067 if (row + i >= 0 && row + i < nrow && row + i != ocrow)
2104 { 2068 {
2105 line_t s = ROW(row - view_start); 2069 line_t s = ROW(row - view_start);
2106 line_t d = drawn[row]; 2070 line_t d = drawn_buf[row];
2107 line_t d2 = drawn[row + i]; 2071 line_t d2 = drawn_buf[row + i];
2108 2072
2109 for (nits = 0, col = ncol; col--; ) 2073 for (nits = 0, col = ncol; col--; )
2110 if (s.t[col] != d2.t[col] || s.r[col] != d2.r[col]) 2074 if (s.t[col] != d2.t[col] || s.r[col] != d2.r[col])
2111 nits--; 2075 nits--;
2112 else if (s.t[col] != d.t[col] || s.r[col] != d.r[col]) 2076 else if (s.t[col] != d.t[col] || s.r[col] != d.r[col])
2150 */ 2114 */
2151 for (row = 0; row < nrow; row++) 2115 for (row = 0; row < nrow; row++)
2152 { 2116 {
2153 text_t *stp = ROW(row - view_start).t; 2117 text_t *stp = ROW(row - view_start).t;
2154 rend_t *srp = ROW(row - view_start).r; 2118 rend_t *srp = ROW(row - view_start).r;
2155 text_t *dtp = drawn[row].t; 2119 text_t *dtp = drawn_buf[row].t;
2156 rend_t *drp = drawn[row].r; 2120 rend_t *drp = drawn_buf[row].r;
2157 2121
2158 /* 2122 /*
2159 * E2: OK, now the real pass 2123 * E2: OK, now the real pass
2160 */ 2124 */
2161 int ypixel = (int)Row2Pixel (row); 2125 int ypixel = (int)Row2Pixel (row);
2223 count++, i--; 2187 count++, i--;
2224 2188
2225 /* 2189 /*
2226 * Determine the attributes for the string 2190 * Determine the attributes for the string
2227 */ 2191 */
2228 int fore = GET_FGCOLOR (rend); // desired foreground 2192 int fore = fgcolor_of (rend); // desired foreground
2229 int back = GET_BGCOLOR (rend); // desired background 2193 int back = bgcolor_of (rend); // desired background
2230 2194
2231 // only do special processing if any attributes are set, which is rare 2195 // only do special processing if any attributes are set, which is unlikely
2232 if (rend & (RS_Bold | RS_Italic | RS_Uline | RS_RVid | RS_Blink | RS_Careful)) 2196 if (rend & (RS_Bold | RS_Italic | RS_Uline | RS_RVid | RS_Blink | RS_Careful))
2233 { 2197 {
2234#if ENABLE_STYLES 2198#if ENABLE_STYLES
2235 // force redraw after "careful" characters to avoid pixel droppings 2199 // force redraw after "careful" characters to avoid pixel droppings
2236 if (srp[col] & RS_Careful && col < ncol - 1 && 0) 2200 if (srp[col] & RS_Careful && col < ncol - 1 && 0)
2355 */ 2319 */
2356 if (showcursor) 2320 if (showcursor)
2357 { 2321 {
2358 if (focus) 2322 if (focus)
2359 { 2323 {
2360 if (options & Opt_cursorUnderline) 2324 if (OPTION (Opt_cursorUnderline))
2361 *crp ^= RS_Uline; 2325 *crp ^= RS_Uline;
2362 else 2326 else
2363 { 2327 {
2364 *crp ^= RS_RVid; 2328 *crp ^= RS_RVid;
2365#ifndef NO_CURSORCOLOR 2329#ifndef NO_CURSORCOLOR
2374 2338
2375 while (col && ROW(screen.cur.row).t[col] == NOCHAR) 2339 while (col && ROW(screen.cur.row).t[col] == NOCHAR)
2376 col--; 2340 col--;
2377 2341
2378 while (col + cursorwidth < ncol 2342 while (col + cursorwidth < ncol
2379 && drawn[oldcursor.row].t[col + cursorwidth] == NOCHAR) 2343 && drawn_buf[oldcursor.row].t[col + cursorwidth] == NOCHAR)
2380 cursorwidth++; 2344 cursorwidth++;
2381 2345
2382#ifndef NO_CURSORCOLOR 2346#ifndef NO_CURSORCOLOR
2383 if (ISSET_PIXCOLOR (Color_cursor)) 2347 if (ISSET_PIXCOLOR (Color_cursor))
2384 XSetForeground (display->display, gc, pix_colors[Color_cursor]); 2348 XSetForeground (display->display, gc, pix_colors[Color_cursor]);
2416 2380
2417void 2381void
2418rxvt_term::scr_remap_chars () 2382rxvt_term::scr_remap_chars ()
2419{ 2383{
2420 for (int i = total_rows; i--; ) 2384 for (int i = total_rows; i--; )
2421 scr_remap_chars (save[i]); 2385 scr_remap_chars (row_buf [i]);
2422 2386
2423 for (int i = nrow; i--; ) 2387 for (int i = nrow; i--; )
2424 { 2388 {
2425 scr_remap_chars (drawn[i]); 2389 scr_remap_chars (drawn_buf [i]);
2426 scr_remap_chars (swap_save[i]); 2390 scr_remap_chars (swap_buf [i]);
2427 } 2391 }
2428} 2392}
2429 2393
2430void 2394void
2431rxvt_term::scr_recolour () 2395rxvt_term::scr_recolour ()
2484 2448
2485#if ENABLE_FRILLS 2449#if ENABLE_FRILLS
2486 if (selection.rect) 2450 if (selection.rect)
2487 { 2451 {
2488 for (row = max (selection.beg.row, -view_start); row <= min (selection.end.row, view_end); row++) 2452 for (row = max (selection.beg.row, -view_start); row <= min (selection.end.row, view_end); row++)
2453 {
2454 text_t *stp = ROW(row).t;
2455 rend_t *srp = ROW(row).r;
2456
2489 for (rend_t *srp = ROW(row).r, col = selection.beg.col; col < selection.end.col; col++) 2457 for (col = selection.beg.col; col < selection.end.col; col++)
2490 srp[col] ^= RS_RVid; 2458 srp[col] ^= RS_RVid;
2459
2460 while (col-- > selection.beg.col && (stp[col] == NOCHAR || unicode::is_space (stp[col])))
2461 srp[col] ^= RS_RVid | RS_Uline;
2462 }
2491 } 2463 }
2492 else 2464 else
2493#endif 2465#endif
2494 { 2466 {
2495 if (selection.beg.row >= -view_start) 2467 if (selection.beg.row >= -view_start)
2498 row = selection.beg.row; 2470 row = selection.beg.row;
2499 } 2471 }
2500 else 2472 else
2501 { 2473 {
2502 col = 0; 2474 col = 0;
2503 row = view_start; 2475 row = -view_start;
2504 } 2476 }
2505 2477
2506 for (; row < min (selection.end.row, view_end); row++, col = 0) 2478 for (; row < min (selection.end.row, view_end); row++, col = 0)
2507 for (rend_t *srp = ROW(row).r; col < ncol; col++) 2479 for (rend_t *srp = ROW(row).r; col < ncol; col++)
2508 srp[col] ^= RS_RVid; 2480 srp[col] ^= RS_RVid;
2528 char r1[] = "\n"; 2500 char r1[] = "\n";
2529 2501
2530 for (row = saveLines - nsaved; 2502 for (row = saveLines - nsaved;
2531 row < saveLines + nrow - 1; row++) 2503 row < saveLines + nrow - 1; row++)
2532 { 2504 {
2533 width = save[row].l >= 0 ? save[row].l 2505 width = row_buf[row].l >= 0 ? row_buf[row].l
2534 : ncol; 2506 : ncol;
2535 for (towrite = width; towrite; towrite -= wrote) 2507 for (towrite = width; towrite; towrite -= wrote)
2536 { 2508 {
2537 wrote = write (fd, & (save[row].t[width - towrite]), 2509 wrote = write (fd, & (row_buf[row].t[width - towrite]),
2538 towrite); 2510 towrite);
2539 if (wrote < 0) 2511 if (wrote < 0)
2540 return; /* XXX: death, no report */ 2512 return; /* XXX: death, no report */
2541 } 2513 }
2542 if (save[row].l >= 0) 2514 if (row_buf[row].l >= 0)
2543 if (write (fd, r1, 1) <= 0) 2515 if (write (fd, r1, 1) <= 0)
2544 return; /* XXX: death, no report */ 2516 return; /* XXX: death, no report */
2545 } 2517 }
2546} 2518}
2547#endif 2519#endif
2922#endif 2894#endif
2923 end_col = ROW(row).is_longer () ? ncol : ROW(row).l; //TODO//FIXME//LEN 2895 end_col = ROW(row).is_longer () ? ncol : ROW(row).l; //TODO//FIXME//LEN
2924 2896
2925 col = max (col, 0); 2897 col = max (col, 0);
2926 2898
2927 if (row == selection.end.row || selection.rect) 2899 if (row == selection.end.row
2900#if ENABLE_FRILLS
2901 || selection.rect
2902#endif
2903 )
2928 end_col = min (end_col, selection.end.col); 2904 min_it (end_col, selection.end.col);
2929 2905
2930 t = ROW(row).t + col; 2906 t = ROW(row).t + col;
2931 for (; col < end_col; col++) 2907 for (; col < end_col; col++)
2932 { 2908 {
2933 if (*t == NOCHAR) 2909 if (*t == NOCHAR)
2951#endif 2927#endif
2952 else 2928 else
2953 new_selection_text[ofs++] = *t++; 2929 new_selection_text[ofs++] = *t++;
2954 } 2930 }
2955 2931
2932#if ENABLE_FRILLS
2933 if (selection.rect)
2934 {
2935 while (ofs
2936 && new_selection_text[ofs - 1] != C0_LF
2937 && unicode::is_space (new_selection_text[ofs - 1]))
2938 --ofs;
2939
2940 new_selection_text[ofs++] = C0_LF;
2941 }
2942 else
2943#endif
2956 if (!ROW(row).is_longer () && row != selection.end.row) 2944 if (!ROW(row).is_longer () && row != selection.end.row)
2957 new_selection_text[ofs++] = C0_LF; 2945 new_selection_text[ofs++] = C0_LF;
2958 } 2946 }
2959 2947
2960 if (end_col != selection.end.col) 2948 if (end_col != selection.end.col)
2961 new_selection_text[ofs++] = C0_LF; 2949 new_selection_text[ofs++] = C0_LF;
2962 2950
3313 selection_delimit_word (DN, &selection.end, &selection.end); 3301 selection_delimit_word (DN, &selection.end, &selection.end);
3314 } 3302 }
3315 else if (selection.clicks == 3) 3303 else if (selection.clicks == 3)
3316 { 3304 {
3317#if ENABLE_FRILLS 3305#if ENABLE_FRILLS
3318 if (options & Opt_tripleclickwords) 3306 if (OPTION (Opt_tripleclickwords))
3319 { 3307 {
3320 selection_delimit_word (UP, &selection.beg, &selection.beg); 3308 selection_delimit_word (UP, &selection.beg, &selection.beg);
3321 3309
3322 for (int end_row = selection.mark.row; end_row < nrow; end_row++) 3310 for (int end_row = selection.mark.row; end_row < nrow; end_row++)
3323 { 3311 {
3384 { 3372 {
3385 stp = ROW(end_row).t; 3373 stp = ROW(end_row).t;
3386 3374
3387 while (--end_col >= 0) 3375 while (--end_col >= 0)
3388 { 3376 {
3389 if (stp[end_col] != ' ' 3377 if (stp[end_col] != NOCHAR
3390 && stp[end_col] != '\t' 3378 && !unicode::is_space (stp[end_col]))
3391 && stp[end_col] != NOCHAR)
3392 break; 3379 break;
3393 } 3380 }
3394 3381
3395 if (end_col >= 0 3382 if (end_col >= 0
3396 || !ROW(end_row - 1).is_longer ()) 3383 || !ROW(end_row - 1).is_longer ())
3572 */ 3559 */
3573void 3560void
3574rxvt_term::pixel_position (int *x, int *y) 3561rxvt_term::pixel_position (int *x, int *y)
3575{ 3562{
3576 *x = Pixel2Col (*x); 3563 *x = Pixel2Col (*x);
3577 /* MAX_IT (*x, 0); MIN_IT (*x, (int)ncol - 1); */ 3564 /* max_it (*x, 0); min_it (*x, (int)ncol - 1); */
3578 *y = Pixel2Row (*y); 3565 *y = Pixel2Row (*y);
3579 /* MAX_IT (*y, 0); MIN_IT (*y, (int)nrow - 1); */ 3566 /* max_it (*y, 0); min_it (*y, (int)nrow - 1); */
3580} 3567}
3581 3568
3582/* ------------------------------------------------------------------------- */ 3569/* ------------------------------------------------------------------------- */
3583#ifdef USE_XIM 3570#ifdef USE_XIM
3584void 3571void
3606 3593
3607 if (x < 0) x = ncol - w; 3594 if (x < 0) x = ncol - w;
3608 if (y < 0) y = nrow - h; 3595 if (y < 0) y = nrow - h;
3609 3596
3610 // make space for border 3597 // make space for border
3611 w += 2; MIN_IT (w, ncol); 3598 w += 2; min_it (w, ncol);
3612 h += 2; MIN_IT (h, nrow); 3599 h += 2; min_it (h, nrow);
3613 3600
3614 x -= 1; MAX_IT (x, 0); 3601 x -= 1; clamp_it (x, 0, ncol - w);
3615 y -= 1; MAX_IT (y, 0); 3602 y -= 1; clamp_it (y, 0, nrow - h);
3616
3617 MIN_IT (x, ncol - w);
3618 MIN_IT (y, nrow - h);
3619 3603
3620 ov_x = x; ov_y = y; 3604 ov_x = x; ov_y = y;
3621 ov_w = w; ov_h = h; 3605 ov_w = w; ov_h = h;
3622 3606
3623 ov_text = new text_t *[h]; 3607 ov_text = new text_t *[h];
3715 for (int y = ov_h; y--; ) 3699 for (int y = ov_h; y--; )
3716 { 3700 {
3717 text_t *t1 = ov_text[y]; 3701 text_t *t1 = ov_text[y];
3718 rend_t *r1 = ov_rend[y]; 3702 rend_t *r1 = ov_rend[y];
3719 3703
3720 text_t *t2 = ROW(y - view_start).t + ov_x; 3704 text_t *t2 = ROW(y + ov_y - view_start).t + ov_x;
3721 rend_t *r2 = ROW(y - view_start).r + ov_x; 3705 rend_t *r2 = ROW(y + ov_y - view_start).r + ov_x;
3722 3706
3723 for (int x = ov_w; x--; ) 3707 for (int x = ov_w; x--; )
3724 { 3708 {
3725 text_t t = *t1; *t1++ = *t2; *t2++ = t; 3709 text_t t = *t1; *t1++ = *t2; *t2++ = t;
3726 rend_t r = *r1; *r1++ = *r2; *r2++ = SET_FONT (r, FONTSET (r)->find_font (t)); 3710 rend_t r = *r1; *r1++ = *r2; *r2++ = SET_FONT (r, FONTSET (r)->find_font (t));

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines