void tb_present(void) { unsigned int x,y; struct tb_cell *back, *front; /* invalidate cursor position */ lastx = LAST_COORD_INIT; lasty = LAST_COORD_INIT; if (buffer_size_change_request) { update_size(); buffer_size_change_request = 0; } for (y = 0; y < front_buffer.height; ++y) { for (x = 0; x < front_buffer.width; ++x) { back = &CELL(&back_buffer, x, y); front = &CELL(&front_buffer, x, y); if (memcmp(back, front, sizeof(struct tb_cell)) == 0) continue; send_attr(back->fg, back->bg); send_char(x, y, back->ch); memcpy(front, back, sizeof(struct tb_cell)); } } if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) write_cursor(cursor_x, cursor_y); memstream_flush(&write_buffer); }
static void send_clear(void) { send_attr(foreground, background); memstream_puts(&write_buffer, funcs[T_CLEAR_SCREEN]); if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) write_cursor(cursor_x, cursor_y); memstream_flush(&write_buffer); /* we need to invalidate cursor position too and these two vars are * used only for simple cursor positioning optimization, cursor * actually may be in the correct place, but we simply discard * optimization once and it gives us simple solution for the case when * cursor moved */ lastx = LAST_COORD_INIT; lasty = LAST_COORD_INIT; }
static void send_clear() { send_attr(foreground, background); fputs(funcs[T_CLEAR_SCREEN], out); if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) fprintf(out, funcs[T_MOVE_CURSOR], cursor_y+1, cursor_x+1); fflush(out); /* we need to invalidate cursor position too and these two vars are * used only for simple cursor positioning optimization, cursor * actually may be in the correct place, but we simply discard * optimization once and it gives us simple solution for the case when * cursor moved */ lastx = LAST_COORD_INIT; lasty = LAST_COORD_INIT; }
void tb_present(void) { int x,y,w,i; struct tb_cell *back, *front; /* invalidate cursor position */ lastx = LAST_COORD_INIT; lasty = LAST_COORD_INIT; if (buffer_size_change_request) { update_size(); buffer_size_change_request = 0; } for (y = 0; y < front_buffer.height; ++y) { for (x = 0; x < front_buffer.width; ) { back = &CELL(&back_buffer, x, y); front = &CELL(&front_buffer, x, y); w = wcwidth(back->ch); if (w < 1) w = 1; if (memcmp(back, front, sizeof(struct tb_cell)) == 0) { x += w; continue; } memcpy(front, back, sizeof(struct tb_cell)); send_attr(back->fg, back->bg); if (w > 1 && x >= front_buffer.width - (w - 1)) { // Not enough room for wide ch, so send spaces for (i = x; i < front_buffer.width; ++i) { send_char(i, y, ' '); } } else { send_char(x, y, back->ch); for (i = 1; i < w; ++i) { front = &CELL(&front_buffer, x + i, y); front->ch = 0; front->fg = back->fg; front->bg = back->bg; } } x += w; } } if (!IS_CURSOR_HIDDEN(cursor_x, cursor_y)) write_cursor(cursor_x, cursor_y); bytebuffer_flush(&output_buffer, inout); }
static int process_ver_info(struct vio_driver_state *vio, struct vio_ver_info *pkt) { struct vio_version *vap; int err; viodbg(HS, "GOT VERSION INFO maj[%u] min[%u] devclass[%u]\n", pkt->major, pkt->minor, pkt->dev_class); if (vio->hs_state != VIO_HS_INVALID) { /* XXX Perhaps invoke start_handshake? XXX */ memset(&vio->ver, 0, sizeof(vio->ver)); vio->hs_state = VIO_HS_INVALID; } vap = find_by_major(vio, pkt->major); vio->_peer_sid = pkt->tag.sid; if (!vap) { pkt->tag.stype = VIO_SUBTYPE_NACK; pkt->major = 0; pkt->minor = 0; viodbg(HS, "SEND VERSION NACK maj[0] min[0]\n"); err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); } else if (vap->major != pkt->major) { pkt->tag.stype = VIO_SUBTYPE_NACK; pkt->major = vap->major; pkt->minor = vap->minor; viodbg(HS, "SEND VERSION NACK maj[%u] min[%u]\n", pkt->major, pkt->minor); err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); } else { struct vio_version ver = { .major = pkt->major, .minor = pkt->minor, }; if (ver.minor > vap->minor) ver.minor = vap->minor; pkt->minor = ver.minor; pkt->tag.stype = VIO_SUBTYPE_ACK; viodbg(HS, "SEND VERSION ACK maj[%u] min[%u]\n", pkt->major, pkt->minor); err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); if (err > 0) { vio->ver = ver; vio->hs_state = VIO_HS_GOTVERS; } } if (err < 0) return handshake_failure(vio); return 0; } static int process_ver_ack(struct vio_driver_state *vio, struct vio_ver_info *pkt) { viodbg(HS, "GOT VERSION ACK maj[%u] min[%u] devclass[%u]\n", pkt->major, pkt->minor, pkt->dev_class); if (vio->hs_state & VIO_HS_GOTVERS) { if (vio->ver.major != pkt->major || vio->ver.minor != pkt->minor) { pkt->tag.stype = VIO_SUBTYPE_NACK; (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); return handshake_failure(vio); } } else { vio->ver.major = pkt->major; vio->ver.minor = pkt->minor; vio->hs_state = VIO_HS_GOTVERS; } switch (vio->dev_class) { case VDEV_NETWORK: case VDEV_DISK: if (send_attr(vio) < 0) return handshake_failure(vio); break; default: break; } return 0; }