void TermView::_GetCell(VTermPos pos, VTermScreenCell& cell) { // First handle cells from the normal screen if (vterm_screen_get_cell(fTermScreen, pos, &cell) != 0) return; // Try the scroll-back buffer if (pos.row < 0 && pos.col >= 0) { int offset = - pos.row - 1; ScrollBufferItem* line = (ScrollBufferItem*)fScrollBuffer.ItemAt(offset); if (line != NULL && pos.col < line->cols) { cell = line->cells[pos.col]; return; } } // All cells outside the used terminal area are drawn with the same // background color as the top-left one. // TODO should they use the attributes of the closest neighbor instead? VTermPos firstPos; firstPos.row = 0; firstPos.col = 0; vterm_screen_get_cell(fTermScreen, firstPos, &cell); cell.chars[0] = 0; cell.width = 1; }
void render_gl_term(GLTerminal* term) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glBindFramebuffer(GL_FRAMEBUFFER, term->render_target_fb); glClearColor(0.0f,0.0f,0.0f,0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); int i=0; glColor3d(1,1,1); glDisable(GL_TEXTURE_2D); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); // glOrtho(0, TERM_SIZE*3, 0, TERM_SIZE, -1,1); glOrtho(0,TERM_SIZE*3,0,TERM_SIZE*1.5,-1,1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glEnable(GL_TEXTURE_2D); int row=0; int col=0; glBindTexture(GL_TEXTURE_2D,term->font_texture); glBegin(GL_QUADS); char cur_char[2]; cur_char[1]=0; VTermPos cur_pos; VTermScreenCell cell; VTermPos cursor_pos; vterm_state_get_cursorpos( vterm_obtain_state(term->vt),&cursor_pos); cursor_pos.row = cursor_pos.row+(25 - CHAR_PIXEL_H); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); for(col=0; col<80; col++) { for(row=0; row<25; row++) { cur_pos.row = row+(25-CHAR_PIXEL_H); cur_pos.col = col; cur_char[0] = term->contents[row][col]; vterm_screen_get_cell(term->vts,cur_pos,&cell); glColor3d(cell.bg.red,cell.bg.green,cell.bg.blue); OGLCONSOLE_DrawString(" ",col*(TERM_SIZE/80),row*(TERM_SIZE/25),CHAR_PIXEL_W,CHAR_PIXEL_H,0); glEnable(GL_TEXTURE_2D); glColor3d(cell.fg.red,cell.fg.green,cell.fg.blue); OGLCONSOLE_DrawString(cur_char,col*(TERM_SIZE/80),row*(TERM_SIZE/25),CHAR_PIXEL_W,CHAR_PIXEL_H,0); } } OGLCONSOLE_DrawString("_",cursor_pos.col*(TERM_SIZE/80),cursor_pos.row*(TERM_SIZE/25),CHAR_PIXEL_W,CHAR_PIXEL_H,0); glEnd(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glBindFramebuffer(GL_FRAMEBUFFER,0); }
int movecursor(VTermPos pos, VTermPos oldpos, int visible, void *user) { struct fbterm_ctx *ctx = (struct fbterm_ctx *) user; /* Remove cursor and redraw cell */ fbterm_rect_clear(ctx, oldpos.row, oldpos.row+1, oldpos.col, oldpos.col+1); VTermScreenCell cell; vterm_screen_get_cell(ctx->screen, oldpos, &cell); uint32_t fg = _RGB(cell.fg.red, cell.fg.green, cell.fg.blue); uint32_t bg = _RGB(cell.bg.red, cell.bg.green, cell.bg.blue); fbterm_putc(ctx, oldpos.row, oldpos.col, cell.chars[0], fg, bg); /* Set new cursor if visible */ //if (visible) fbterm_set_cursor(ctx, pos.row, pos.col); }
static int moverect_internal(VTermRect dest, VTermRect src, void *user) { VTermScreen *screen = user; if(screen->callbacks && screen->callbacks->sb_pushline && dest.start_row == 0 && dest.start_col == 0 && /* starts top-left corner */ dest.end_col == screen->cols && /* full width */ screen->buffer == screen->buffers[0]) { /* not altscreen */ VTermPos pos; for(pos.row = 0; pos.row < src.start_row; pos.row++) { for(pos.col = 0; pos.col < screen->cols; pos.col++) vterm_screen_get_cell(screen, pos, screen->sb_buffer + pos.col); (screen->callbacks->sb_pushline)(screen->cols, screen->sb_buffer, screen->cbdata); } } { int cols = src.end_col - src.start_col; int downward = src.start_row - dest.start_row; int init_row, test_row, inc_row; int row; if(downward < 0) { init_row = dest.end_row - 1; test_row = dest.start_row - 1; inc_row = -1; } else { init_row = dest.start_row; test_row = dest.end_row; inc_row = +1; } for(row = init_row; row != test_row; row += inc_row) memmove(getcell(screen, row, dest.start_col), getcell(screen, row + downward, src.start_col), cols * sizeof(ScreenCell)); } return 1; }
int damage(VTermRect rect, void *user) { struct fbterm_ctx *ctx = (struct fbterm_ctx *) user; fbterm_rect_clear(ctx, rect.start_row, rect.end_row, rect.start_col, rect.end_col); VTermScreenCell cell; VTermPos pos; int row, col; for (row = rect.start_row; row < rect.end_row; row++) { for (col = rect.start_col; col < rect.end_col; col++) { pos.col = col; pos.row = row; vterm_screen_get_cell(ctx->screen, pos, &cell); uint32_t fg = _RGB(cell.fg.red, cell.fg.green, cell.fg.blue); uint32_t bg = _RGB(cell.bg.red, cell.bg.green, cell.bg.blue); fbterm_putc(ctx, row, col, cell.chars[0], fg, bg); } } return 1; }
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; } } }
/********* TODO - Test some different strings to figure out EOL character Split terminal into rows *********/ void update_gl_term(GLTerminal* term) { int rc; char input[150]; memset((void*)input,0,150); rc = read(term->fd_master,input,sizeof(input)-1); if(rc>0) { vterm_input_write(term->vt, input,rc); // send contents of input to the terminal here } else { // fprintf(stderr,"GLTerminal closed\n"); // return; } if(term->pending_input_size > 0) { write(term->fd_master,term->pending_input,term->pending_input_size); term->pending_input_size = 0; } VTermScreenCell cell; VTermRect rect = {0,0,0,0}; rect.start_row=0; rect.start_col=0; rect.end_row=25; rect.end_col=80; memset((void*)term->contents,' ',sizeof(char)*80*25); vterm_screen_get_text(term->vts, &(term->contents),sizeof(char)*80*25,rect); int row=0; int col=0; VTermPos pos; for(row=0; row<25; row++) { for(col=0; col<80; col++) { pos.col = col; pos.row = row; vterm_screen_get_cell(term->vts,pos,&cell); term->contents[25-1-row][col] = cell.chars[0]; } } }
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; } } } }