Annotation of src/usr.bin/tmux/screen-write.c, Revision 1.1
1.1 ! nicm 1: /* $OpenBSD$ */
! 2:
! 3: /*
! 4: * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
! 5: *
! 6: * Permission to use, copy, modify, and distribute this software for any
! 7: * purpose with or without fee is hereby granted, provided that the above
! 8: * copyright notice and this permission notice appear in all copies.
! 9: *
! 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
! 15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
! 16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 17: */
! 18:
! 19: #include <sys/types.h>
! 20:
! 21: #include <string.h>
! 22:
! 23: #include "tmux.h"
! 24:
! 25: void screen_write_save(struct screen_write_ctx *);
! 26: void screen_write_overwrite(struct screen_write_ctx *);
! 27:
! 28: /* Initialise writing with a window. */
! 29: void
! 30: screen_write_start(
! 31: struct screen_write_ctx *ctx, struct window_pane *wp, struct screen *s)
! 32: {
! 33: ctx->wp = wp;
! 34: if (wp != NULL && s == NULL)
! 35: ctx->s = wp->screen;
! 36: else
! 37: ctx->s = s;
! 38: }
! 39:
! 40: /* Finish writing. */
! 41: void
! 42: screen_write_stop(unused struct screen_write_ctx *ctx)
! 43: {
! 44: }
! 45:
! 46: /* Write character. */
! 47: void
! 48: screen_write_putc(
! 49: struct screen_write_ctx *ctx, struct grid_cell *gc, u_char ch)
! 50: {
! 51: gc->data = ch;
! 52: screen_write_cell(ctx, gc, NULL);
! 53: }
! 54:
! 55: /* Write string. */
! 56: void printflike3
! 57: screen_write_puts(
! 58: struct screen_write_ctx *ctx, struct grid_cell *gc, const char *fmt, ...)
! 59: {
! 60: va_list ap;
! 61: char *msg, *ptr;
! 62:
! 63: va_start(ap, fmt);
! 64: xvasprintf(&msg, fmt, ap);
! 65: va_end(ap);
! 66:
! 67: for (ptr = msg; *ptr != '\0'; ptr++)
! 68: screen_write_putc(ctx, gc, (u_char) *ptr);
! 69:
! 70: xfree(msg);
! 71: }
! 72:
! 73: /* Copy from another screen. */
! 74: void
! 75: screen_write_copy(struct screen_write_ctx *ctx,
! 76: struct screen *src, u_int px, u_int py, u_int nx, u_int ny)
! 77: {
! 78: struct screen *s = ctx->s;
! 79: struct grid *gd = src->grid;
! 80: const struct grid_cell *gc;
! 81: struct grid_utf8 *gu;
! 82: u_char *udata;
! 83: u_int xx, yy, cx, cy;
! 84:
! 85: cx = s->cx;
! 86: cy = s->cy;
! 87: for (yy = py; yy < py + ny; yy++) {
! 88: for (xx = px; xx < px + nx; xx++) {
! 89: if (xx >= gd->sx || yy >= gd->hsize + gd->sy)
! 90: gc = &grid_default_cell;
! 91: else
! 92: gc = grid_peek_cell(gd, xx, yy);
! 93:
! 94: udata = NULL;
! 95: if (gc->flags & GRID_FLAG_UTF8) {
! 96: gu = grid_get_utf8(gd, xx, yy);
! 97: udata = gu->data;
! 98: }
! 99:
! 100: screen_write_cell(ctx, gc, udata);
! 101: }
! 102: cy++;
! 103: screen_write_cursormove(ctx, cx, cy);
! 104: }
! 105: }
! 106:
! 107: /* Save cursor and region positions. */
! 108: void
! 109: screen_write_save(struct screen_write_ctx *ctx)
! 110: {
! 111: struct screen *s = ctx->s;
! 112:
! 113: s->old_cx = s->cx;
! 114: s->old_cy = s->cy;
! 115:
! 116: s->old_rlower = s->rlower;
! 117: s->old_rupper = s->rupper;
! 118: }
! 119:
! 120: /* Cursor up by ny. */
! 121: void
! 122: screen_write_cursorup(struct screen_write_ctx *ctx, u_int ny)
! 123: {
! 124: struct screen *s = ctx->s;
! 125:
! 126: if (ny == 0)
! 127: ny = 1;
! 128:
! 129: if (ny > s->cy)
! 130: ny = s->cy;
! 131: if (ny == 0)
! 132: return;
! 133:
! 134: s->cy -= ny;
! 135: }
! 136:
! 137: /* Cursor down by ny. */
! 138: void
! 139: screen_write_cursordown(struct screen_write_ctx *ctx, u_int ny)
! 140: {
! 141: struct screen *s = ctx->s;
! 142:
! 143: if (ny == 0)
! 144: ny = 1;
! 145:
! 146: if (ny > screen_size_y(s) - 1 - s->cy)
! 147: ny = screen_size_y(s) - 1 - s->cy;
! 148: if (ny == 0)
! 149: return;
! 150:
! 151: s->cy += ny;
! 152: }
! 153:
! 154: /* Cursor right by nx. */
! 155: void
! 156: screen_write_cursorright(struct screen_write_ctx *ctx, u_int nx)
! 157: {
! 158: struct screen *s = ctx->s;
! 159:
! 160: if (nx == 0)
! 161: nx = 1;
! 162:
! 163: if (nx > screen_size_x(s) - 1 - s->cx)
! 164: nx = screen_size_x(s) - 1 - s->cx;
! 165: if (nx == 0)
! 166: return;
! 167:
! 168: s->cx += nx;
! 169: }
! 170:
! 171: /* Cursor left by nx. */
! 172: void
! 173: screen_write_cursorleft(struct screen_write_ctx *ctx, u_int nx)
! 174: {
! 175: struct screen *s = ctx->s;
! 176:
! 177: if (nx == 0)
! 178: nx = 1;
! 179:
! 180: if (nx > s->cx)
! 181: nx = s->cx;
! 182: if (nx == 0)
! 183: return;
! 184:
! 185: s->cx -= nx;
! 186: }
! 187:
! 188: /* Insert nx characters. */
! 189: void
! 190: screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx)
! 191: {
! 192: struct screen *s = ctx->s;
! 193:
! 194: if (nx == 0)
! 195: nx = 1;
! 196:
! 197: if (nx > screen_size_x(s) - 1 - s->cx)
! 198: nx = screen_size_x(s) - 1 - s->cx;
! 199: if (nx == 0)
! 200: return;
! 201:
! 202: screen_write_save(ctx);
! 203:
! 204: if (s->cx <= screen_size_x(s) - 1)
! 205: grid_view_insert_cells(s->grid, s->cx, s->cy, nx);
! 206:
! 207: tty_write_cmd(ctx->wp, TTY_INSERTCHARACTER, nx);
! 208: }
! 209:
! 210: /* Delete nx characters. */
! 211: void
! 212: screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx)
! 213: {
! 214: struct screen *s = ctx->s;
! 215:
! 216: if (nx == 0)
! 217: nx = 1;
! 218:
! 219: if (nx > screen_size_x(s) - 1 - s->cx)
! 220: nx = screen_size_x(s) - 1 - s->cx;
! 221: if (nx == 0)
! 222: return;
! 223:
! 224: screen_write_save(ctx);
! 225:
! 226: if (s->cx <= screen_size_x(s) - 1)
! 227: grid_view_delete_cells(s->grid, s->cx, s->cy, nx);
! 228:
! 229: tty_write_cmd(ctx->wp, TTY_DELETECHARACTER, nx);
! 230: }
! 231:
! 232: /* Insert ny lines. */
! 233: void
! 234: screen_write_insertline(struct screen_write_ctx *ctx, u_int ny)
! 235: {
! 236: struct screen *s = ctx->s;
! 237:
! 238: if (ny == 0)
! 239: ny = 1;
! 240:
! 241: if (ny > screen_size_y(s) - 1 - s->cy)
! 242: ny = screen_size_y(s) - 1 - s->cy;
! 243: if (ny == 0)
! 244: return;
! 245:
! 246: screen_write_save(ctx);
! 247:
! 248: if (s->cy < s->rupper || s->cy > s->rlower)
! 249: grid_view_insert_lines(s->grid, s->cy, ny);
! 250: else {
! 251: grid_view_insert_lines_region(
! 252: s->grid, s->rupper, s->rlower, s->cy, ny);
! 253: }
! 254:
! 255: tty_write_cmd(ctx->wp, TTY_INSERTLINE, ny);
! 256: }
! 257:
! 258: /* Delete ny lines. */
! 259: void
! 260: screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny)
! 261: {
! 262: struct screen *s = ctx->s;
! 263:
! 264: if (ny == 0)
! 265: ny = 1;
! 266:
! 267: if (ny > screen_size_y(s) - 1 - s->cy)
! 268: ny = screen_size_y(s) - 1 - s->cy;
! 269: if (ny == 0)
! 270: return;
! 271:
! 272: screen_write_save(ctx);
! 273:
! 274: if (s->cy < s->rupper || s->cy > s->rlower)
! 275: grid_view_delete_lines(s->grid, s->cy, ny);
! 276: else {
! 277: grid_view_delete_lines_region(
! 278: s->grid, s->rupper, s->rlower, s->cy, ny);
! 279: }
! 280:
! 281: tty_write_cmd(ctx->wp, TTY_DELETELINE, ny);
! 282: }
! 283:
! 284: /* Clear line at cursor. */
! 285: void
! 286: screen_write_clearline(struct screen_write_ctx *ctx)
! 287: {
! 288: struct screen *s = ctx->s;
! 289:
! 290: screen_write_save(ctx);
! 291:
! 292: grid_view_clear(s->grid, 0, s->cy, screen_size_x(s), 1);
! 293:
! 294: tty_write_cmd(ctx->wp, TTY_CLEARLINE);
! 295: }
! 296:
! 297: /* Clear to end of line from cursor. */
! 298: void
! 299: screen_write_clearendofline(struct screen_write_ctx *ctx)
! 300: {
! 301: struct screen *s = ctx->s;
! 302: u_int sx;
! 303:
! 304: screen_write_save(ctx);
! 305:
! 306: sx = screen_size_x(s);
! 307:
! 308: if (s->cx <= sx - 1)
! 309: grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
! 310:
! 311: tty_write_cmd(ctx->wp, TTY_CLEARENDOFLINE);
! 312: }
! 313:
! 314: /* Clear to start of line from cursor. */
! 315: void
! 316: screen_write_clearstartofline(struct screen_write_ctx *ctx)
! 317: {
! 318: struct screen *s = ctx->s;
! 319: u_int sx;
! 320:
! 321: screen_write_save(ctx);
! 322:
! 323: sx = screen_size_x(s);
! 324:
! 325: if (s->cx > sx - 1)
! 326: grid_view_clear(s->grid, 0, s->cy, sx, 1);
! 327: else
! 328: grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1);
! 329:
! 330: tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFLINE);
! 331: }
! 332:
! 333: /* Move cursor to px,py. */
! 334: void
! 335: screen_write_cursormove(struct screen_write_ctx *ctx, u_int px, u_int py)
! 336: {
! 337: struct screen *s = ctx->s;
! 338:
! 339: if (px > screen_size_x(s) - 1)
! 340: px = screen_size_x(s) - 1;
! 341: if (py > screen_size_y(s) - 1)
! 342: py = screen_size_y(s) - 1;
! 343:
! 344: s->cx = px;
! 345: s->cy = py;
! 346: }
! 347:
! 348: /* Set cursor mode. */
! 349: void
! 350: screen_write_cursormode(struct screen_write_ctx *ctx, int state)
! 351: {
! 352: struct screen *s = ctx->s;
! 353:
! 354: if (state)
! 355: s->mode |= MODE_CURSOR;
! 356: else
! 357: s->mode &= ~MODE_CURSOR;
! 358: }
! 359:
! 360: /* Reverse index (up with scroll). */
! 361: void
! 362: screen_write_reverseindex(struct screen_write_ctx *ctx)
! 363: {
! 364: struct screen *s = ctx->s;
! 365:
! 366: screen_write_save(ctx);
! 367:
! 368: if (s->cy == s->rupper)
! 369: grid_view_scroll_region_down(s->grid, s->rupper, s->rlower);
! 370: else if (s->cy > 0)
! 371: s->cy--;
! 372:
! 373: tty_write_cmd(ctx->wp, TTY_REVERSEINDEX);
! 374: }
! 375:
! 376: /* Set scroll region. */
! 377: void
! 378: screen_write_scrollregion(
! 379: struct screen_write_ctx *ctx, u_int rupper, u_int rlower)
! 380: {
! 381: struct screen *s = ctx->s;
! 382:
! 383: if (rupper > screen_size_y(s) - 1)
! 384: rupper = screen_size_y(s) - 1;
! 385: if (rlower > screen_size_y(s) - 1)
! 386: rlower = screen_size_y(s) - 1;
! 387: if (rupper > rlower)
! 388: return;
! 389:
! 390: /* Cursor moves to top-left. */
! 391: s->cx = 0;
! 392: s->cy = 0;
! 393:
! 394: s->rupper = rupper;
! 395: s->rlower = rlower;
! 396: }
! 397:
! 398: /* Set insert mode. */
! 399: void
! 400: screen_write_insertmode(struct screen_write_ctx *ctx, int state)
! 401: {
! 402: struct screen *s = ctx->s;
! 403:
! 404: if (state)
! 405: s->mode |= MODE_INSERT;
! 406: else
! 407: s->mode &= ~MODE_INSERT;
! 408: }
! 409:
! 410: /* Set mouse mode. */
! 411: void
! 412: screen_write_mousemode(struct screen_write_ctx *ctx, int state)
! 413: {
! 414: struct screen *s = ctx->s;
! 415:
! 416: if (state)
! 417: s->mode |= MODE_MOUSE;
! 418: else
! 419: s->mode &= ~MODE_MOUSE;
! 420: }
! 421:
! 422: /* Line feed (down with scroll). */
! 423: void
! 424: screen_write_linefeed(struct screen_write_ctx *ctx)
! 425: {
! 426: struct screen *s = ctx->s;
! 427:
! 428: screen_write_save(ctx);
! 429:
! 430: if (s->cy == s->rlower)
! 431: grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
! 432: else if (s->cy < screen_size_y(s) - 1)
! 433: s->cy++;
! 434:
! 435: tty_write_cmd(ctx->wp, TTY_LINEFEED);
! 436: }
! 437:
! 438: /* Carriage return (cursor to start of line). */
! 439: void
! 440: screen_write_carriagereturn(struct screen_write_ctx *ctx)
! 441: {
! 442: struct screen *s = ctx->s;
! 443:
! 444: s->cx = 0;
! 445: }
! 446:
! 447: /* Set keypad cursor keys mode. */
! 448: void
! 449: screen_write_kcursormode(struct screen_write_ctx *ctx, int state)
! 450: {
! 451: struct screen *s = ctx->s;
! 452:
! 453: if (state)
! 454: s->mode |= MODE_KCURSOR;
! 455: else
! 456: s->mode &= ~MODE_KCURSOR;
! 457: }
! 458:
! 459: /* Set keypad number keys mode. */
! 460: void
! 461: screen_write_kkeypadmode(struct screen_write_ctx *ctx, int state)
! 462: {
! 463: struct screen *s = ctx->s;
! 464:
! 465: if (state)
! 466: s->mode |= MODE_KKEYPAD;
! 467: else
! 468: s->mode &= ~MODE_KKEYPAD;
! 469: }
! 470:
! 471: /* Clear to end of screen from cursor. */
! 472: void
! 473: screen_write_clearendofscreen(struct screen_write_ctx *ctx)
! 474: {
! 475: struct screen *s = ctx->s;
! 476: u_int sx, sy;
! 477:
! 478: screen_write_save(ctx);
! 479:
! 480: sx = screen_size_x(s);
! 481: sy = screen_size_y(s);
! 482:
! 483: if (s->cx <= sx - 1)
! 484: grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1);
! 485: grid_view_clear(s->grid, 0, s->cy + 1, sx, sy - (s->cy + 1));
! 486:
! 487: tty_write_cmd(ctx->wp, TTY_CLEARENDOFSCREEN);
! 488: }
! 489:
! 490: /* Clear to start of screen. */
! 491: void
! 492: screen_write_clearstartofscreen(struct screen_write_ctx *ctx)
! 493: {
! 494: struct screen *s = ctx->s;
! 495: u_int sx;
! 496:
! 497: screen_write_save(ctx);
! 498:
! 499: sx = screen_size_x(s);
! 500:
! 501: if (s->cy > 0)
! 502: grid_view_clear(s->grid, 0, 0, sx, s->cy - 1);
! 503: if (s->cx > sx - 1)
! 504: grid_view_clear(s->grid, 0, s->cy, sx, 1);
! 505: else
! 506: grid_view_clear(s->grid, 0, s->cy, s->cx, 1);
! 507:
! 508: tty_write_cmd(ctx->wp, TTY_CLEARSTARTOFSCREEN);
! 509: }
! 510:
! 511: /* Clear entire screen. */
! 512: void
! 513: screen_write_clearscreen(struct screen_write_ctx *ctx)
! 514: {
! 515: struct screen *s = ctx->s;
! 516:
! 517: screen_write_save(ctx);
! 518:
! 519: grid_view_clear(s->grid, 0, 0, screen_size_x(s), screen_size_y(s));
! 520:
! 521: tty_write_cmd(ctx->wp, TTY_CLEARSCREEN);
! 522: }
! 523:
! 524: /* Write cell data. */
! 525: void
! 526: screen_write_cell(
! 527: struct screen_write_ctx *ctx, const struct grid_cell *gc, u_char *udata)
! 528: {
! 529: struct screen *s = ctx->s;
! 530: struct grid *gd = s->grid;
! 531: struct grid_utf8 gu, *tmp_gu;
! 532: u_int width, xx, i;
! 533: struct grid_cell tmp_gc, *tmp_gc2;
! 534: size_t size;
! 535:
! 536: /* Ignore padding. */
! 537: if (gc->flags & GRID_FLAG_PADDING)
! 538: return;
! 539:
! 540: /* Find character width. */
! 541: if (gc->flags & GRID_FLAG_UTF8) {
! 542: width = utf8_width(udata);
! 543:
! 544: gu.width = width;
! 545: memcpy(&gu.data, udata, sizeof gu.data);
! 546: } else
! 547: width = 1;
! 548:
! 549: /* If the width is zero, combine onto the previous character. */
! 550: if (width == 0) {
! 551: if (s->cx == 0)
! 552: return;
! 553: tmp_gc2 = grid_view_get_cell(gd, s->cx - 1, s->cy);
! 554: if (!(tmp_gc2->flags & GRID_FLAG_UTF8)) {
! 555: tmp_gc2->flags |= GRID_FLAG_UTF8;
! 556: memset(&gu.data, 0xff, sizeof gu.data);
! 557: *gu.data = tmp_gc2->data;
! 558: gu.width = 1;
! 559: grid_view_set_utf8(gd, s->cx - 1, s->cy, &gu);
! 560: }
! 561: tmp_gu = grid_view_get_utf8(gd, s->cx - 1, s->cy);
! 562:
! 563: for (i = 0; i < UTF8_SIZE; i++) {
! 564: if (tmp_gu->data[i] == 0xff)
! 565: break;
! 566: }
! 567: memcpy(tmp_gu->data + i, udata, UTF8_SIZE - i);
! 568:
! 569: /* Assume the previous character has just been input. */
! 570: for (size = 0; size < UTF8_SIZE; size++) {
! 571: if (udata[size] == 0xff)
! 572: break;
! 573: }
! 574: tty_write_cmd(ctx->wp, TTY_RAW, udata, size);
! 575: return;
! 576: }
! 577:
! 578: /* If the character is wider than the screen, don't print it. */
! 579: if (width > screen_size_x(s)) {
! 580: memcpy(&tmp_gc, gc, sizeof tmp_gc);
! 581: tmp_gc.data = '_';
! 582: width = 1;
! 583: gc = &tmp_gc;
! 584: }
! 585:
! 586: /* Check this will fit on the current line; scroll if not. */
! 587: if (s->cx > screen_size_x(s) - width) {
! 588: screen_write_carriagereturn(ctx);
! 589: screen_write_linefeed(ctx);
! 590: }
! 591:
! 592: /* Sanity checks. */
! 593: if (s->cx > screen_size_x(s) - 1 || s->cy > screen_size_y(s) - 1)
! 594: return;
! 595:
! 596: /* Handle overwriting of UTF-8 characters. */
! 597: screen_write_overwrite(ctx);
! 598:
! 599: /*
! 600: * If the new character is UTF-8 wide, fill in padding cells. Have
! 601: * already ensured there is enough room.
! 602: */
! 603: for (xx = s->cx + 1; xx < s->cx + width; xx++) {
! 604: tmp_gc2 = grid_view_get_cell(gd, xx, s->cy);
! 605: if (tmp_gc2 != NULL)
! 606: tmp_gc2->flags |= GRID_FLAG_PADDING;
! 607: }
! 608:
! 609: /* Set the cell. */
! 610: grid_view_set_cell(gd, s->cx, s->cy, gc);
! 611: if (gc->flags & GRID_FLAG_UTF8)
! 612: grid_view_set_utf8(gd, s->cx, s->cy, &gu);
! 613:
! 614: /* Move the cursor. */
! 615: screen_write_save(ctx);
! 616: s->cx += width;
! 617:
! 618: /* Draw to the screen if necessary. */
! 619: if (screen_check_selection(s, s->cx - width, s->cy)) {
! 620: s->sel.cell.data = gc->data;
! 621: tty_write_cmd(ctx->wp, TTY_CELL, &s->sel.cell, &gu);
! 622: } else
! 623: tty_write_cmd(ctx->wp, TTY_CELL, gc, &gu);
! 624: }
! 625:
! 626: /*
! 627: * UTF-8 wide characters are a bit of an annoyance. They take up more than one
! 628: * cell on the screen, so following cells must not be drawn by marking them as
! 629: * padding.
! 630: *
! 631: * So far, so good. The problem is, when overwriting a padding cell, or a UTF-8
! 632: * character, it is necessary to also overwrite any other cells which covered
! 633: * by the same character.
! 634: */
! 635: void
! 636: screen_write_overwrite(struct screen_write_ctx *ctx)
! 637: {
! 638: struct screen *s = ctx->s;
! 639: struct grid *gd = s->grid;
! 640: const struct grid_cell *gc;
! 641: const struct grid_utf8 *gu;
! 642: u_int xx;
! 643:
! 644: gc = grid_view_peek_cell(gd, s->cx, s->cy);
! 645: gu = grid_view_peek_utf8(gd, s->cx, s->cy);
! 646:
! 647: if (gc->flags & GRID_FLAG_PADDING) {
! 648: /*
! 649: * A padding cell, so clear any following and leading padding
! 650: * cells back to the character. Don't overwrite the current
! 651: * cell as that happens later anyway.
! 652: */
! 653: xx = s->cx + 1;
! 654: while (--xx > 0) {
! 655: gc = grid_view_peek_cell(gd, xx, s->cy);
! 656: if (!(gc->flags & GRID_FLAG_PADDING))
! 657: break;
! 658: grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
! 659: }
! 660:
! 661: /* Overwrite the character at the start of this padding. */
! 662: grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
! 663:
! 664: /* Overwrite following padding cells. */
! 665: xx = s->cx;
! 666: while (++xx < screen_size_x(s)) {
! 667: gc = grid_view_peek_cell(gd, xx, s->cy);
! 668: if (!(gc->flags & GRID_FLAG_PADDING))
! 669: break;
! 670: grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
! 671: }
! 672: } else if (gc->flags & GRID_FLAG_UTF8 && gu->width > 1) {
! 673: /*
! 674: * An UTF-8 wide cell; overwrite following padding cells only.
! 675: */
! 676: xx = s->cx;
! 677: while (++xx < screen_size_x(s)) {
! 678: gc = grid_view_peek_cell(gd, xx, s->cy);
! 679: if (!(gc->flags & GRID_FLAG_PADDING))
! 680: break;
! 681: grid_view_set_cell(gd, xx, s->cy, &grid_default_cell);
! 682: }
! 683: }
! 684: }