[BACK]Return to screen-write.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/screen-write.c between version 1.192 and 1.193

version 1.192, 2021/01/27 10:42:52 version 1.193, 2021/01/29 09:48:43
Line 23 
Line 23 
   
 #include "tmux.h"  #include "tmux.h"
   
   static struct screen_write_citem *screen_write_collect_trim(
                       struct screen_write_ctx *, u_int, u_int, u_int, int *);
 static void     screen_write_collect_clear(struct screen_write_ctx *, u_int,  static void     screen_write_collect_clear(struct screen_write_ctx *, u_int,
                     u_int);                      u_int);
 static void     screen_write_collect_clear_end(struct screen_write_ctx *, u_int,  static void     screen_write_collect_scroll(struct screen_write_ctx *, u_int);
                     u_int);  
 static void     screen_write_collect_clear_start(struct screen_write_ctx *,  
                     u_int, u_int);  
 static void     screen_write_collect_scroll(struct screen_write_ctx *);  
 static void     screen_write_collect_flush(struct screen_write_ctx *, int,  static void     screen_write_collect_flush(struct screen_write_ctx *, int,
                     const char *);                      const char *);
   
Line 38 
Line 36 
 static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,  static const struct grid_cell *screen_write_combine(struct screen_write_ctx *,
                     const struct utf8_data *, u_int *);                      const struct utf8_data *, u_int *);
   
 struct screen_write_collect_item {  struct screen_write_citem {
         u_int                    x;          u_int                           x;
         int                      wrapped;          int                             wrapped;
   
         enum { TEXT, CLEAR_END, CLEAR_START } type;          enum { TEXT, CLEAR }            type;
         u_int                    used;          u_int                           used;
         u_int                    bg;          u_int                           bg;
   
         struct grid_cell         gc;          struct grid_cell                gc;
   
         TAILQ_ENTRY(screen_write_collect_item) entry;          TAILQ_ENTRY(screen_write_citem) entry;
 };  };
 struct screen_write_collect_line {  struct screen_write_cline {
         u_int                                    bg;          char                            *data;
         char                                    *data;          TAILQ_HEAD(, screen_write_citem) items;
         TAILQ_HEAD(, screen_write_collect_item)  items;  
 };  };
   TAILQ_HEAD(, screen_write_citem)  screen_write_citem_freelist =
       TAILQ_HEAD_INITIALIZER(screen_write_citem_freelist);
   
   static struct screen_write_citem *
   screen_write_get_citem(void)
   {
       struct screen_write_citem   *ci;
   
       ci = TAILQ_FIRST(&screen_write_citem_freelist);
       if (ci != NULL) {
           TAILQ_REMOVE(&screen_write_citem_freelist, ci, entry);
           memset(ci, 0, sizeof *ci);
           return (ci);
       }
       return (xcalloc(1, sizeof *ci));
   }
   
 static void  static void
   screen_write_free_citem(struct screen_write_citem *ci)
   {
       TAILQ_INSERT_TAIL(&screen_write_citem_freelist, ci, entry);
   }
   
   static void
 screen_write_offset_timer(__unused int fd, __unused short events, void *data)  screen_write_offset_timer(__unused int fd, __unused short events, void *data)
 {  {
         struct window   *w = data;          struct window   *w = data;
Line 125 
Line 144 
                  * Redraw is already deferred to redraw another pane - redraw                   * Redraw is already deferred to redraw another pane - redraw
                  * this one also when that happens.                   * this one also when that happens.
                  */                   */
                 log_debug("adding %%%u to deferred redraw", wp->id);                  log_debug("%s: adding %%%u to deferred redraw", __func__,
                       wp->id);
                 wp->flags |= PANE_REDRAW;                  wp->flags |= PANE_REDRAW;
                 return (-1);                  return (-1);
         }          }
Line 220 
Line 240 
   
         if (ctx->s->write_list == NULL)          if (ctx->s->write_list == NULL)
                 screen_write_make_list(ctx->s);                  screen_write_make_list(ctx->s);
         ctx->item = xcalloc(1, sizeof *ctx->item);          ctx->item = screen_write_get_citem();
   
         ctx->scrolled = 0;          ctx->scrolled = 0;
         ctx->bg = 8;          ctx->bg = 8;
Line 278 
Line 298 
         screen_write_collect_end(ctx);          screen_write_collect_end(ctx);
         screen_write_collect_flush(ctx, 0, __func__);          screen_write_collect_flush(ctx, 0, __func__);
   
         log_debug("%s: %u cells (%u written, %u skipped)", __func__,          screen_write_free_citem(ctx->item);
             ctx->cells, ctx->written, ctx->skipped);  
         if (ctx->wp != NULL) {  
                 ctx->wp->written += ctx->written;  
                 ctx->wp->skipped += ctx->skipped;  
         }  
   
         free(ctx->item);  
 }  }
   
 /* Reset screen state. */  /* Reset screen state. */
Line 1094 
Line 1107 
 void  void
 screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)  screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
 {  {
         struct screen            *s = ctx->s;          struct screen                   *s = ctx->s;
         struct grid_line         *gl;          struct grid_line                *gl;
         u_int                     sx = screen_size_x(s);          u_int                            sx = screen_size_x(s);
           struct screen_write_citem       *ci = ctx->item;
   
         gl = grid_get_line(s->grid, s->grid->hsize + s->cy);          gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
         if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))          if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))
Line 1105 
Line 1119 
         grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);          grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
   
         screen_write_collect_clear(ctx, s->cy, 1);          screen_write_collect_clear(ctx, s->cy, 1);
         ctx->s->write_list[s->cy].bg = 1 + bg;          ci->x = 0;
         ctx->item->used = 0;          ci->used = sx;
           ci->type = CLEAR;
           ci->bg = bg;
           TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
           ctx->item = screen_write_get_citem();
 }  }
   
 /* Clear to end of line from cursor. */  /* Clear to end of line from cursor. */
 void  void
 screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)  screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)
 {  {
         struct screen                    *s = ctx->s;          struct screen                   *s = ctx->s;
         struct grid_line                 *gl;          struct grid_line                *gl;
         u_int                             sx = screen_size_x(s);          u_int                            sx = screen_size_x(s);
         struct screen_write_collect_item *ci = ctx->item;          struct screen_write_citem       *ci = ctx->item, *before;
   
         if (s->cx == 0) {          if (s->cx == 0) {
                 screen_write_clearline(ctx, bg);                  screen_write_clearline(ctx, bg);
Line 1129 
Line 1147 
   
         grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);          grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);
   
         screen_write_collect_clear_end(ctx, s->cy, s->cx);          before = screen_write_collect_trim(ctx, s->cy, s->cx, sx - s->cx, NULL);
         ci->x = s->cx;          ci->x = s->cx;
         ci->type = CLEAR_END;          ci->used = sx - s->cx;
           ci->type = CLEAR;
         ci->bg = bg;          ci->bg = bg;
         TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);          if (before == NULL)
         ctx->item = xcalloc(1, sizeof *ctx->item);                  TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
           else
                   TAILQ_INSERT_BEFORE(before, ci, entry);
           ctx->item = screen_write_get_citem();
 }  }
   
 /* Clear to start of line from cursor. */  /* Clear to start of line from cursor. */
Line 1142 
Line 1164 
 screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)  screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
 {  {
         struct screen                    *s = ctx->s;          struct screen                    *s = ctx->s;
         u_int                             sx = screen_size_x(s);          u_int                            sx = screen_size_x(s);
         struct screen_write_collect_item *ci = ctx->item;          struct screen_write_citem       *ci = ctx->item, *before;
   
         if (s->cx >= sx - 1) {          if (s->cx >= sx - 1) {
                 screen_write_clearline(ctx, bg);                  screen_write_clearline(ctx, bg);
Line 1155 
Line 1177 
         else          else
                 grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);                  grid_view_clear(s->grid, 0, s->cy, s->cx + 1, 1, bg);
   
         screen_write_collect_clear_start(ctx, s->cy, s->cx);          before = screen_write_collect_trim(ctx, s->cy, 0, s->cx + 1, NULL);
         ci->x = s->cx;          ci->x = 0;
         ci->type = CLEAR_START;          ci->used = s->cx + 1;
           ci->type = CLEAR;
         ci->bg = bg;          ci->bg = bg;
         TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);          if (before == NULL)
         ctx->item = xcalloc(1, sizeof *ctx->item);                  TAILQ_INSERT_TAIL(&ctx->s->write_list[s->cy].items, ci, entry);
           else
                   TAILQ_INSERT_BEFORE(before, ci, entry);
           ctx->item = screen_write_get_citem();
 }  }
   
 /* Move cursor to px,py. */  /* Move cursor to px,py. */
Line 1182 
Line 1208 
         if (py != -1 && (u_int)py > screen_size_y(s) - 1)          if (py != -1 && (u_int)py > screen_size_y(s) - 1)
                 py = screen_size_y(s) - 1;                  py = screen_size_y(s) - 1;
   
           log_debug("%s: from %u,%u to %u,%u", __func__, s->cx, s->cy, px, py);
         screen_write_set_cursor(ctx, px, py);          screen_write_set_cursor(ctx, px, py);
 }  }
   
Line 1250 
Line 1277 
   
         if (s->cy == s->rlower) {          if (s->cy == s->rlower) {
                 grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);                  grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
                 screen_write_collect_scroll(ctx);                  screen_write_collect_scroll(ctx, bg);
                 ctx->scrolled++;                  ctx->scrolled++;
         } else if (s->cy < screen_size_y(s) - 1)          } else if (s->cy < screen_size_y(s) - 1)
                 screen_write_set_cursor(ctx, -1, s->cy + 1);                  screen_write_set_cursor(ctx, -1, s->cy + 1);
Line 1276 
Line 1303 
   
         for (i = 0; i < lines; i++) {          for (i = 0; i < lines; i++) {
                 grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);                  grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
                 screen_write_collect_scroll(ctx);                  screen_write_collect_scroll(ctx, bg);
         }          }
         ctx->scrolled += lines;          ctx->scrolled += lines;
 }  }
Line 1390 
Line 1417 
         grid_clear_history(ctx->s->grid);          grid_clear_history(ctx->s->grid);
 }  }
   
 /* Clear to start of a collected line. */  /* Trim collected items. */
 static void  static struct screen_write_citem *
 screen_write_collect_clear_start(struct screen_write_ctx *ctx, u_int y, u_int x)  screen_write_collect_trim(struct screen_write_ctx *ctx, u_int y, u_int x,
       u_int used, int *wrapped)
 {  {
         struct screen_write_collect_item        *ci, *tmp;          struct screen_write_cline       *cl = &ctx->s->write_list[y];
         size_t                                   size = 0;          struct screen_write_citem       *ci, *ci2, *tmp, *before = NULL;
         u_int                                    items = 0;          u_int                            sx = x, ex = x + used - 1;
           u_int                            csx, cex;
   
         if (TAILQ_EMPTY(&ctx->s->write_list[y].items))          if (TAILQ_EMPTY(&cl->items))
                 return;                  return (NULL);
         TAILQ_FOREACH_SAFE(ci, &ctx->s->write_list[y].items, entry, tmp) {          TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
                 switch (ci->type) {                  csx = ci->x;
                 case CLEAR_START:                  cex = ci->x + ci->used - 1;
                         break;  
                 case CLEAR_END:                  /* Item is entirely before. */
                         if (ci->x <= x)                  if (cex < sx) {
                                 ci->x = x;                          log_debug("%s: %p %u-%u before %u-%u", __func__, ci,
                               csx, cex, sx, ex);
                         continue;                          continue;
                 case TEXT:                  }
                         if (ci->x > x)  
                                 continue;                  /* Item is entirely after. */
                   if (csx > ex) {
                           log_debug("%s: %p %u-%u after %u-%u", __func__, ci,
                               csx, cex, sx, ex);
                           before = ci;
                         break;                          break;
                 }                  }
                 items++;  
                 size += ci->used;  
                 TAILQ_REMOVE(&ctx->s->write_list[y].items, ci, entry);  
                 free(ci);  
         }  
         ctx->skipped += size;  
         log_debug("%s: dropped %u items (%zu bytes) (line %u)", __func__, items,  
             size, y);  
 }  
   
 /* Clear to end of a collected line. */                  /* Item is entirely inside. */
 static void                  if (csx >= sx && cex <= ex) {
 screen_write_collect_clear_end(struct screen_write_ctx *ctx, u_int y, u_int x)                          log_debug("%s: %p %u-%u inside %u-%u", __func__, ci,
 {                              csx, cex, sx, ex);
         struct screen_write_collect_item        *ci, *tmp;                          TAILQ_REMOVE(&cl->items, ci, entry);
         size_t                                   size = 0;                          screen_write_free_citem(ci);
         u_int                                    items = 0;                          if (csx == 0 && ci->wrapped && wrapped != NULL)
                                   *wrapped = 1;
                           continue;
                   }
   
         if (TAILQ_EMPTY(&ctx->s->write_list[y].items))                  /* Item under the start. */
                 return;                  if (csx < sx && cex >= sx && cex <= ex) {
         TAILQ_FOREACH_SAFE(ci, &ctx->s->write_list[y].items, entry, tmp) {                          log_debug("%s: %p %u-%u start %u-%u", __func__, ci,
                 switch (ci->type) {                              csx, cex, sx, ex);
                 case CLEAR_START:                          ci->used = sx - csx;
                         if (ci->x >= x)                          log_debug("%s: %p now %u-%u", __func__, ci, ci->x,
                                 ci->x = x;                              ci->x + ci->used + 1);
                         continue;                          continue;
                 case CLEAR_END:                  }
   
                   /* Item covers the end. */
                   if (cex > ex && csx >= sx && csx <= ex) {
                           log_debug("%s: %p %u-%u end %u-%u", __func__, ci,
                               csx, cex, sx, ex);
                           ci->x = ex + 1;
                           ci->used = cex - ex;
                           log_debug("%s: %p now %u-%u", __func__, ci, ci->x,
                               ci->x + ci->used + 1);
                           before = ci;
                         break;                          break;
                 case TEXT:  
                         if (ci->x < x)  
                                 continue;  
                         break;  
                 }                  }
                 items++;  
                 size += ci->used;                  /* Item must cover both sides. */
                 TAILQ_REMOVE(&ctx->s->write_list[y].items, ci, entry);                  log_debug("%s: %p %u-%u under %u-%u", __func__, ci,
                 free(ci);                      csx, cex, sx, ex);
                   ci2 = screen_write_get_citem();
                   ci2->type = ci->type;
                   ci2->bg = ci->bg;
                   memcpy(&ci2->gc, &ci->gc, sizeof ci2->gc);
                   TAILQ_INSERT_AFTER(&cl->items, ci, ci2, entry);
   
                   ci->used = sx - csx;
                   ci2->x = ex + 1;
                   ci2->used = cex - ex;
   
                   log_debug("%s: %p now %u-%u (%p) and %u-%u (%p)", __func__, ci,
                       ci->x, ci->x + ci->used - 1, ci, ci2->x,
                       ci2->x + ci2->used - 1, ci2);
                   before = ci2;
                   break;
         }          }
         ctx->skipped += size;          return (before);
         log_debug("%s: dropped %u items (%zu bytes) (line %u)", __func__, items,  
             size, y);  
 }  }
   
 /* Clear collected lines. */  /* Clear collected lines. */
 static void  static void
 screen_write_collect_clear(struct screen_write_ctx *ctx, u_int y, u_int n)  screen_write_collect_clear(struct screen_write_ctx *ctx, u_int y, u_int n)
 {  {
         struct screen_write_collect_item        *ci, *tmp;          struct screen_write_cline       *cl;
         struct screen_write_collect_line        *cl;          u_int                            i;
         u_int                                    i, items;  
         size_t                                   size;  
   
         for (i = y; i < y + n; i++) {          for (i = y; i < y + n; i++) {
                 if (TAILQ_EMPTY(&ctx->s->write_list[i].items))  
                         continue;  
                 items = 0;  
                 size = 0;  
                 cl = &ctx->s->write_list[i];                  cl = &ctx->s->write_list[i];
                 TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {                  TAILQ_CONCAT(&screen_write_citem_freelist, &cl->items, entry);
                         items++;  
                         size += ci->used;  
                         TAILQ_REMOVE(&cl->items, ci, entry);  
                         free(ci);  
                 }  
                 ctx->skipped += size;  
                 log_debug("%s: dropped %u items (%zu bytes) (line %u)",  
                     __func__, items, size, y);  
         }          }
 }  }
   
 /* Scroll collected lines up. */  /* Scroll collected lines up. */
 static void  static void
 screen_write_collect_scroll(struct screen_write_ctx *ctx)  screen_write_collect_scroll(struct screen_write_ctx *ctx, u_int bg)
 {  {
         struct screen                           *s = ctx->s;          struct screen                   *s = ctx->s;
         struct screen_write_collect_line        *cl;          struct screen_write_cline       *cl;
         u_int                                    y;          u_int                            y;
         char                                    *saved;          char                            *saved;
           struct screen_write_citem       *ci;
   
         log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy,          log_debug("%s: at %u,%u (region %u-%u)", __func__, s->cx, s->cy,
             s->rupper, s->rlower);              s->rupper, s->rlower);
Line 1500 
Line 1534 
         for (y = s->rupper; y < s->rlower; y++) {          for (y = s->rupper; y < s->rlower; y++) {
                 cl = &ctx->s->write_list[y + 1];                  cl = &ctx->s->write_list[y + 1];
                 TAILQ_CONCAT(&ctx->s->write_list[y].items, &cl->items, entry);                  TAILQ_CONCAT(&ctx->s->write_list[y].items, &cl->items, entry);
                 ctx->s->write_list[y].bg = cl->bg;  
                 ctx->s->write_list[y].data = cl->data;                  ctx->s->write_list[y].data = cl->data;
         }          }
         ctx->s->write_list[s->rlower].bg = 1 + 8;  
         ctx->s->write_list[s->rlower].data = saved;          ctx->s->write_list[s->rlower].data = saved;
   
           ci = screen_write_get_citem();
           ci->x = 0;
           ci->used = screen_size_x(s);
           ci->type = CLEAR;
           ci->bg = bg;
           TAILQ_INSERT_TAIL(&ctx->s->write_list[s->rlower].items, ci, entry);
 }  }
   
 /* Flush collected lines. */  /* Flush collected lines. */
Line 1512 
Line 1551 
 screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,  screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
     const char *from)      const char *from)
 {  {
         struct screen                           *s = ctx->s;          struct screen                   *s = ctx->s;
         struct screen_write_collect_item        *ci, *tmp;          struct screen_write_citem       *ci, *tmp;
         struct screen_write_collect_line        *cl;          struct screen_write_cline       *cl;
         u_int                                    y, cx, cy, items = 0;          u_int                            y, cx, cy, last, items = 0;
         struct tty_ctx                           ttyctx;          struct tty_ctx                   ttyctx;
         size_t                                   written = 0;  
   
         if (ctx->scrolled != 0) {          if (ctx->scrolled != 0) {
                 log_debug("%s: scrolled %u (region %u-%u)", __func__,                  log_debug("%s: scrolled %u (region %u-%u)", __func__,
Line 1539 
Line 1577 
         cx = s->cx; cy = s->cy;          cx = s->cx; cy = s->cy;
         for (y = 0; y < screen_size_y(s); y++) {          for (y = 0; y < screen_size_y(s); y++) {
                 cl = &ctx->s->write_list[y];                  cl = &ctx->s->write_list[y];
                 if (cl->bg != 0) {                  last = UINT_MAX;
                         screen_write_set_cursor(ctx, 0, y);  
                         screen_write_initctx(ctx, &ttyctx, 1);  
                         ttyctx.bg = cl->bg - 1;  
                         tty_write(tty_cmd_clearline, &ttyctx);  
                 }  
                 TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {                  TAILQ_FOREACH_SAFE(ci, &cl->items, entry, tmp) {
                           if (last != UINT_MAX && ci->x <= last) {
                                   fatalx("collect list not in order: %u <= %u",
                                       ci->x, last);
                           }
                         screen_write_set_cursor(ctx, ci->x, y);                          screen_write_set_cursor(ctx, ci->x, y);
                         if (ci->type == CLEAR_END) {                          if (ci->type == CLEAR) {
                                 screen_write_initctx(ctx, &ttyctx, 1);                                  screen_write_initctx(ctx, &ttyctx, 1);
                                 ttyctx.bg = ci->bg;                                  ttyctx.bg = ci->bg;
                                 tty_write(tty_cmd_clearendofline, &ttyctx);                                  ttyctx.num = ci->used;
                         } else if (ci->type == CLEAR_START) {                                  tty_write(tty_cmd_clearcharacter, &ttyctx);
                                 screen_write_initctx(ctx, &ttyctx, 1);  
                                 ttyctx.bg = ci->bg;  
                                 tty_write(tty_cmd_clearstartofline, &ttyctx);  
                         } else {                          } else {
                                 screen_write_initctx(ctx, &ttyctx, 0);                                  screen_write_initctx(ctx, &ttyctx, 0);
                                 ttyctx.cell = &ci->gc;                                  ttyctx.cell = &ci->gc;
Line 1563 
Line 1597 
                                 ttyctx.num = ci->used;                                  ttyctx.num = ci->used;
                                 tty_write(tty_cmd_cells, &ttyctx);                                  tty_write(tty_cmd_cells, &ttyctx);
                         }                          }
   
                         items++;                          items++;
                         written += ci->used;  
   
                         TAILQ_REMOVE(&cl->items, ci, entry);                          TAILQ_REMOVE(&cl->items, ci, entry);
                         free(ci);                          screen_write_free_citem(ci);
                           last = ci->x;
                 }                  }
                 cl->bg = 0;  
         }          }
         s->cx = cx; s->cy = cy;          s->cx = cx; s->cy = cy;
   
         log_debug("%s: flushed %u items (%zu bytes) (%s)", __func__, items,          log_debug("%s: flushed %u items (%s)", __func__, items, from);
             written, from);  
         ctx->written += written;  
 }  }
   
 /* Finish and store collected cells. */  /* Finish and store collected cells. */
 void  void
 screen_write_collect_end(struct screen_write_ctx *ctx)  screen_write_collect_end(struct screen_write_ctx *ctx)
 {  {
         struct screen                           *s = ctx->s;          struct screen                   *s = ctx->s;
         struct screen_write_collect_item        *ci = ctx->item;          struct screen_write_citem       *ci = ctx->item, *before;
         struct screen_write_collect_line        *cl = &s->write_list[s->cy];          struct screen_write_cline       *cl = &s->write_list[s->cy];
         struct grid_cell                         gc;          struct grid_cell                 gc;
         u_int                                    xx;          u_int                            xx;
           int                              wrapped = ci->wrapped;
   
         if (ci->used == 0)          if (ci->used == 0)
                 return;                  return;
   
           before = screen_write_collect_trim(ctx, s->cy, s->cx, ci->used,
               &wrapped);
         ci->x = s->cx;          ci->x = s->cx;
         TAILQ_INSERT_TAIL(&cl->items, ci, entry);          ci->wrapped = wrapped;
         ctx->item = xcalloc(1, sizeof *ctx->item);          if (before == NULL)
                   TAILQ_INSERT_TAIL(&cl->items, ci, entry);
           else
                   TAILQ_INSERT_BEFORE(before, ci, entry);
           ctx->item = screen_write_get_citem();
   
         log_debug("%s: %u %.*s (at %u,%u)", __func__, ci->used,          log_debug("%s: %u %.*s (at %u,%u)", __func__, ci->used,
             (int)ci->used, cl->data + ci->x, s->cx, s->cy);              (int)ci->used, cl->data + ci->x, s->cx, s->cy);
Line 1630 
Line 1667 
 screen_write_collect_add(struct screen_write_ctx *ctx,  screen_write_collect_add(struct screen_write_ctx *ctx,
     const struct grid_cell *gc)      const struct grid_cell *gc)
 {  {
         struct screen                           *s = ctx->s;          struct screen                   *s = ctx->s;
         struct screen_write_collect_item        *ci;          struct screen_write_citem       *ci;
         u_int                                    sx = screen_size_x(s);          u_int                            sx = screen_size_x(s);
         int                                      collect;          int                              collect;
   
         /*          /*
          * Don't need to check that the attributes and whatnot are still the           * Don't need to check that the attributes and whatnot are still the
Line 1658 
Line 1695 
                 screen_write_cell(ctx, gc);                  screen_write_cell(ctx, gc);
                 return;                  return;
         }          }
         ctx->cells++;  
   
         if (s->cx > sx - 1 || ctx->item->used > sx - 1 - s->cx)          if (s->cx > sx - 1 || ctx->item->used > sx - 1 - s->cx)
                 screen_write_collect_end(ctx);                  screen_write_collect_end(ctx);
Line 1695 
Line 1731 
         /* Ignore padding cells. */          /* Ignore padding cells. */
         if (gc->flags & GRID_FLAG_PADDING)          if (gc->flags & GRID_FLAG_PADDING)
                 return;                  return;
         ctx->cells++;  
   
         /* If the width is zero, combine onto the previous character. */          /* If the width is zero, combine onto the previous character. */
         if (width == 0) {          if (width == 0) {
Line 1822 
Line 1857 
                 } else                  } else
                         ttyctx.cell = gc;                          ttyctx.cell = gc;
                 tty_write(tty_cmd_cell, &ttyctx);                  tty_write(tty_cmd_cell, &ttyctx);
                 ctx->written++;          }
         } else  
                 ctx->skipped++;  
 }  }
   
 /* Combine a UTF-8 zero-width character onto the previous. */  /* Combine a UTF-8 zero-width character onto the previous. */

Legend:
Removed from v.1.192  
changed lines
  Added in v.1.193