int vterm_init(vterm_state_t *s, int width, int height, volatile uint16_t *buffer) { memset(s, 0, sizeof(vterm_state_t)); s->magic = VTERM_MAGIC; s->width = width; s->height = height; s->buffer = buffer; s->fgColour = VTERM_LIGHT_GRAY; s->bgColour = VTERM_BLACK; s->autoRenderUpdate = true; /* Initialise virtual terminal. */ dprintf("Initialising %d x %d Virtual Terminal object...\n", width, height); s->vt = vterm_new(s->height, s->width); if (!s->vt) { ROS_ERROR("Failed to create terminal.\n"); return EINVALID; } /* Grab the virtual screen & state object. */ s->vts = vterm_obtain_screen(s->vt); s->vtstate = vterm_obtain_state(s->vt); assert(s->vts && s->vtstate); /* Set parameters. */ vterm_parser_set_utf8(s->vt, true); vterm_state_set_bold_highbright(s->vtstate, true); vterm_screen_reset(s->vts, 1); return ESUCCESS; }
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 init(void) { context_t* cx = kcalloc(1, sizeof(context_t), GFP_KERNEL); if(unlikely(!cx)) { errno = ENOMEM; return -1; } cx->vmode = KD_TEXT; if(fb_init(cx) != 0) return -1; cx->vt = vterm_new_with_allocator(cx->console.rows, cx->console.cols, &mm, NULL); cx->vs = vterm_obtain_screen(cx->vt); cx->vc = vterm_obtain_state(cx->vt); //vterm_set_utf8(cx->vt, 1); vterm_screen_set_callbacks(cx->vs, &cbs, cx); vterm_screen_reset(cx->vs, 0); vterm_state_reset(cx->vc, 0); VTermRect r = { .start_row = 0, .start_col = 0, .end_row = cx->console.rows, .end_col = cx->console.cols }; console_cbs_damage(r, cx); vterm_input_write(cx->vt, "\e[20h", 5); inode_t* ino = vfs_mkdev("console", -1, S_IFCHR | 0222); ino->ioctl = console_ioctl; ino->write = console_write; ino->userdata = cx; return 0; } int dnit(void) { return 0; }
/* * 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 term_init(struct aug_term *term, int rows, int cols) { VTermScreen *vts; VTermState *state; term->master = 0; term->vt = vterm_new(rows, cols); state = vterm_obtain_state(term->vt); /* have to cast default_color because the api isnt const correct */ vterm_state_set_default_colors(state, &VTERM_DEFAULT_COLOR, &VTERM_DEFAULT_COLOR); vterm_parser_set_utf8(term->vt, 1); vts = vterm_obtain_screen(term->vt); vterm_screen_enable_altscreen(vts, 1); vterm_screen_set_damage_merge(vts, VTERM_DAMAGE_SCROLL); vterm_screen_reset(vts, 1); term_inject_clear(term); term->user = NULL; term->io_callbacks.refresh = NULL; AUG_LOCK_INIT(term); }
VTermMM::VTermMM(int rows, int columns) : fd(0), foreground(VTERMMM_WHITE), background(VTERMMM_BLACK), cells(rows, vrow(columns)), reverse(false), invalid_region() { for(int row = 0; row < rows; ++row) { for(int col = 0; col < columns; ++col) { cells[row][col].SetX(col); cells[row][col].SetY(row); } } cursor.row = 0; cursor.col = 0; invalidate(0, rows, 0, columns); _term = vterm_new(rows, columns); vterm_parser_set_utf8(_term, 1); VTermState *vts = vterm_obtain_state(_term); vterm_state_set_callbacks(vts, &vterm_callbacks, this); }
void TermView::Draw(BRect updateRect) { VTermRect updatedChars = _PixelsToGlyphs(updateRect); VTermPos pos; font_height height; GetFontHeight(&height); VTermPos cursorPos; vterm_state_get_cursorpos(vterm_obtain_state(fTerm), &cursorPos); for (pos.row = updatedChars.start_row; pos.row <= updatedChars.end_row; pos.row++) { int x = updatedChars.start_col * fFontWidth + kBorderSpacing; int y = pos.row * fFontHeight + (int)ceil(height.ascent) + kBorderSpacing; MovePenTo(x, y); BString string; VTermScreenCell cell; int width = 0; bool isCursor = false; pos.col = updatedChars.start_col; _GetCell(pos, cell); for (pos.col = updatedChars.start_col; pos.col <= updatedChars.end_col;) { VTermScreenCell newCell; _GetCell(pos, newCell); // We need to start a new extent if: // - The attributes change // - The colors change // - The end of line is reached // - The current cell is under the cursor // - The current cell is right of the cursor if (*(uint32_t*)&cell.attrs != *(uint32_t*)&newCell.attrs || !vterm_color_equal(cell.fg, newCell.fg) || !vterm_color_equal(cell.bg, newCell.bg) || pos.col >= updatedChars.end_col || (pos.col == cursorPos.col && pos.row == cursorPos.row) || (pos.col == cursorPos.col + 1 && pos.row == cursorPos.row)) { 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; // Draw the cursor by swapping foreground and background colors if (isCursor) { SetLowColor(foreground); SetViewColor(foreground); SetHighColor(background); } else { SetLowColor(background); SetViewColor(background); SetHighColor(foreground); } FillRect(BRect(x, y - ceil(height.ascent) + 1, x + width * fFontWidth - 1, y + ceil(height.descent) + ceil(height.leading)), B_SOLID_LOW); BFont font = be_fixed_font; if (cell.attrs.bold) font.SetFace(B_BOLD_FACE); if (cell.attrs.underline) font.SetFace(B_UNDERSCORE_FACE); if (cell.attrs.italic) font.SetFace(B_ITALIC_FACE); if (cell.attrs.blink) // FIXME make it actually blink font.SetFace(B_OUTLINED_FACE); if (cell.attrs.reverse) font.SetFace(B_NEGATIVE_FACE); if (cell.attrs.strike) font.SetFace(B_STRIKEOUT_FACE); // TODO handle "font" (alternate fonts), dwl and dhl (double size) SetFont(&font); DrawString(string); x += width * fFontWidth; // Prepare for next cell cell = newCell; string = ""; width = 0; } if (pos.col == cursorPos.col && pos.row == cursorPos.row) isCursor = true; else isCursor = false; if (newCell.chars[0] == 0) { string += " "; pos.col ++; width += 1; } else { char buffer[VTERM_MAX_CHARS_PER_CELL]; wcstombs(buffer, (wchar_t*)newCell.chars, VTERM_MAX_CHARS_PER_CELL); string += buffer; width += newCell.width; pos.col += newCell.width; } } } }
case FORMAT_SGR: if(prevcell->attrs.bold || prevcell->attrs.underline || prevcell->attrs.italic || prevcell->attrs.blink || prevcell->attrs.reverse || prevcell->attrs.strike || prevcell->attrs.font) printf("\e[m"); break; } printf("\n"); } void dump_row(int row) { VTermPos pos = { .row = row, .col = 0 }; VTermScreenCell prevcell = {}; vterm_state_get_default_colors(vterm_obtain_state(vt), &prevcell.fg, &prevcell.bg); while(pos.col < cols) { VTermScreenCell cell; vterm_screen_get_cell(vts, pos, &cell); dump_cell(&cell, &prevcell); pos.col += cell.width; prevcell = cell; } dump_eol(&prevcell); } static int screen_sb_pushline(int cols, const VTermScreenCell *cells, void *user)
void TermView::Draw(BRect updateRect) { VTermRect updatedChars = _PixelsToGlyphs(updateRect); VTermPos pos; font_height height; GetFontHeight(&height); VTermPos cursorPos; vterm_state_get_cursorpos(vterm_obtain_state(fTerm), &cursorPos); for (pos.row = updatedChars.start_row; pos.row <= updatedChars.end_row; pos.row++) { int x = updatedChars.start_col * fFontWidth + kBorderSpacing; int y = pos.row * fFontHeight + (int)ceil(height.ascent) + kBorderSpacing; MovePenTo(x, y); for (pos.col = updatedChars.start_col; pos.col <= updatedChars.end_col;) { VTermScreenCell cell; _GetCell(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 != 0) ^ (pos.col == cursorPos.col && pos.row == cursorPos.row)) { SetLowColor(foreground); SetViewColor(foreground); SetHighColor(background); } else { SetLowColor(background); SetViewColor(background); SetHighColor(foreground); } FillRect(BRect(x, y - ceil(height.ascent) + 1, x + cell.width * fFontWidth - 1, y + ceil(height.descent) + ceil(height.leading)), B_SOLID_LOW); if (cell.chars[0] == 0) { x += fFontWidth; MovePenTo(x, y); pos.col ++; } else { char buffer[VTERM_MAX_CHARS_PER_CELL]; wcstombs(buffer, (wchar_t*)cell.chars, VTERM_MAX_CHARS_PER_CELL); DrawString(buffer); x += (int)ceil(StringWidth(buffer)); pos.col += cell.width; } } } }