void TermView::_PushLine(int cols, const VTermScreenCell* cells) { ScrollBufferItem* item = (ScrollBufferItem*)malloc(sizeof(int) + cols * sizeof(VTermScreenCell)); item->cols = cols; memcpy(item->cells, cells, cols * sizeof(VTermScreenCell)); fScrollBuffer.AddItem(item, 0); free(fScrollBuffer.RemoveItem(kScrollBackSize)); int availableRows, availableCols; vterm_get_size(fTerm, &availableRows, &availableCols); VTermRect dirty; dirty.start_col = 0; dirty.end_col = availableCols; dirty.end_row = 0; dirty.start_row = -fScrollBuffer.CountItems(); // FIXME we should rather use CopyRect if possible, and only invalidate the // newly exposed area here. Invalidate(_GlyphsToPixels(dirty)); BScrollBar* scrollBar = ScrollBar(B_VERTICAL); if (scrollBar != NULL) { float range = (fScrollBuffer.CountItems() + availableRows) * fFontHeight; scrollBar->SetRange(availableRows * fFontHeight - range, 0.0f); // TODO we need to adjust this in FrameResized, as availableRows can // change scrollBar->SetProportion(availableRows * fFontHeight / range); scrollBar->SetSteps(fFontHeight, fFontHeight * 3); } }
void vterm_screen_enable_altscreen(VTermScreen *screen, int altscreen) { if(!screen->buffers[1] && altscreen) { int rows, cols; vterm_get_size(screen->vt, &rows, &cols); screen->buffers[1] = realloc_buffer(screen, NULL, rows, cols); } }
/* * Allocate a new screen and return it. * Return NULL when out of memory. */ static VTermScreen *screen_new(VTerm *vt) { VTermState *state = vterm_obtain_state(vt); VTermScreen *screen; int rows, cols; if (state == NULL) return NULL; screen = vterm_allocator_malloc(vt, sizeof(VTermScreen)); if (screen == NULL) return NULL; vterm_get_size(vt, &rows, &cols); screen->vt = vt; screen->state = state; screen->damage_merge = VTERM_DAMAGE_CELL; screen->damaged.start_row = -1; screen->pending_scrollrect.start_row = -1; screen->rows = rows; screen->cols = cols; screen->callbacks = NULL; screen->cbdata = NULL; screen->buffers[0] = realloc_buffer(screen, NULL, rows, cols); screen->buffer = screen->buffers[0]; screen->sb_buffer = vterm_allocator_malloc(screen->vt, sizeof(VTermScreenCell) * cols); if (screen->buffer == NULL || screen->sb_buffer == NULL) { vterm_screen_free(screen); return NULL; } vterm_state_set_callbacks(screen->state, &state_cbs, screen); return screen; }
void vterm_render_buffer(vterm_state_t *s) { assert(s && s->magic == VTERM_MAGIC && s->buffer); int bufferHeight, bufferWidth; vterm_get_size(s->vt, &bufferHeight, &bufferWidth); for (int i = 0; i < bufferHeight; i++) { for (int j = 0; j < bufferWidth; ) { VTermPos pos = { .row = i, .col = j }; VTermScreenCell cell; vterm_screen_get_cell(s->vts, pos, &cell); s->fgColour = vterm_internal_colour_to_vterm_colour_index(cell.fg); s->bgColour = vterm_internal_colour_to_vterm_colour_index(cell.bg); vterm_buffer_puts_internal(s, i, j, cell.chars, cell.width); j += cell.width; } } }
void TermView::Draw(BRect updateRect) { VTermRect updatedChars = PixelsToGlyphs(updateRect); VTermPos pos; font_height height; GetFontHeight(&height); int availableRows, availableCols; vterm_get_size(fTerm, &availableRows, &availableCols); for (pos.row = updatedChars.start_row; pos.row <= updatedChars.end_row; pos.row++) { float x = updatedChars.start_col * fFontWidth + kBorderSpacing; float y = pos.row * fFontHeight + height.ascent + kBorderSpacing + 1; MovePenTo(x, y); for (pos.col = updatedChars.start_col; pos.col <= updatedChars.end_col;) { VTermScreenCell cell; if (pos.col < 0 || pos.row < 0 || pos.col >= availableCols || pos.row >= availableRows) { // All cells outside the used terminal area are drawn with the // same background color as the top-left one. VTermPos firstPos; firstPos.row = 0; firstPos.col = 0; vterm_screen_get_cell(fTermScreen, firstPos, &cell); cell.chars[0] = 0; cell.width = 1; } else vterm_screen_get_cell(fTermScreen, pos, &cell); rgb_color foreground, background; foreground.red = cell.fg.red; foreground.green = cell.fg.green; foreground.blue = cell.fg.blue; foreground.alpha = 255; background.red = cell.bg.red; background.green = cell.bg.green; background.blue = cell.bg.blue; background.alpha = 255; if(cell.attrs.reverse) { SetLowColor(foreground); SetViewColor(foreground); SetHighColor(background); } else { SetLowColor(background); SetViewColor(background); SetHighColor(foreground); } BPoint penLocation = PenLocation(); FillRect(BRect(penLocation.x, penLocation.y - height.ascent, penLocation.x + cell.width * fFontWidth, penLocation.y + 1), B_SOLID_LOW); if (cell.chars[0] == 0) { DrawString(" "); pos.col ++; } else { char buffer[VTERM_MAX_CHARS_PER_CELL]; wcstombs(buffer, (wchar_t*)cell.chars, VTERM_MAX_CHARS_PER_CELL); DrawString(buffer); pos.col += cell.width; } } } }
void term_dims(const struct aug_term *term, int *rows, int *cols) { vterm_get_size(term->vt, rows, cols); }