static int console_write(struct inode* inode, void* buf, off_t pos, size_t size) { if(unlikely(!inode || !buf || !inode->userdata)) { errno = EINVAL; return -1; } if(unlikely(!size)) return 0; context_t* cx = (context_t*) inode->userdata; vterm_input_write(cx->vt, buf, size); return size; }
int main(int argc, char *argv[]) { int use_colour = isatty(1); int opt; while((opt = getopt(argc, argv, "c")) != -1) { switch(opt) { case 'c': use_colour = 1; break; } } const char *file = argv[optind++]; int fd; if(!file || streq(file, "-")) fd = 0; // stdin else { fd = open(file, O_RDONLY); if(fd == -1) { fprintf(stderr, "Cannot open %s - %s\n", file, strerror(errno)); exit(1); } } if(use_colour) { special_begin = "\x1b[7m{"; special_end = "}\x1b[m"; } /* Size matters not for the parser */ VTerm *vt = vterm_new(25, 80); vterm_set_utf8(vt, 1); vterm_parser_set_callbacks(vt, &parser_cbs, NULL); int len; char buffer[1024]; while((len = read(fd, buffer, sizeof(buffer))) > 0) { vterm_input_write(vt, buffer, len); } printf("\n"); close(fd); vterm_free(vt); return 0; }
/********* 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]; } } }
GLTerminal* init_gl_term() { int rc=0; GLTerminal* term = (GLTerminal*)malloc(sizeof(GLTerminal)); term->fd_master = posix_openpt(O_RDWR); if(term->fd_master < 0) { fprintf(stderr,"Error %d in posix_openpt()\n",errno); free(term); return NULL; } rc = grantpt(term->fd_master); if(rc != 0) { fprintf(stderr,"Error %d on grantpt()\n",errno); free(term); return NULL; } rc = unlockpt(term->fd_master); if(rc != 0) { fprintf(stderr,"Error %d on unlockpt()\n",errno); free(term); return NULL; } term->fd_slave = open(ptsname(term->fd_master), O_RDWR); term->vt = vterm_new(25,80); vterm_set_utf8(term->vt, false); term->vts = vterm_obtain_screen(term->vt); vterm_screen_reset(term->vts,1); int i=0; for(i=0; i<80*25; i++) vterm_input_write(term->vt," ",1); term->render_target_fb=0; // setup font glGenTextures(1,&(term->font_texture)); glBindTexture(GL_TEXTURE_2D, term->font_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, Console_FontData.width, Console_FontData.height, 0, GL_RGB, GL_UNSIGNED_BYTE, Console_FontData.pixel_data); // configure render target glGenFramebuffers(1,&(term->render_target_fb)); glBindFramebuffer(GL_FRAMEBUFFER,term->render_target_fb); GLuint tex_id; glGenTextures(1,&tex_id); term->render_target = tex_id; glBindTexture(GL_TEXTURE_2D,tex_id); glTexImage2D(GL_TEXTURE_2D, 0,3, TERM_SIZE, TERM_SIZE, 0,GL_RGB, GL_UNSIGNED_BYTE,NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, term->render_target,0); GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0}; glDrawBuffers(1,DrawBuffers); glBindFramebuffer(GL_FRAMEBUFFER,0); return term; }
int fbterm_init(struct fbterm_ctx *ctx) { if (!font) { font = font_open(DEFAULT_FONT); if (!font) return -1; } memset(ctx, 0, sizeof(struct fbterm_ctx)); ctx->font = font; fb_term_init(ctx); fb_cook_wallpaper(ctx, DEFAULT_WALLPAPER); VTerm *vt = vterm_new(ctx->rows, ctx->cols); ctx->vt = vt; VTermScreen *sc = vterm_obtain_screen(vt); vterm_screen_set_callbacks(sc, &screen_cbs, ctx); vterm_screen_reset(sc, 0); ctx->screen = sc; VTermRect r = {.start_row = 0, .end_row = ctx->rows, .start_col = 0, .end_col = ctx->cols}; damage(r, ctx); return 0; } int kbd_fd = -1; int pty = -1; int fbterm_main() { struct fbterm_ctx *active = &term[0]; struct winsize ws; ws.ws_row = active->rows; ws.ws_col = active->cols; ioctl(pty, TIOCSWINSZ, &ws); fbterm_redraw(active); size_t len; char buf[1024]; while (1) { /* Read input */ if ((len = read(pty, buf, sizeof(buf))) > 0) { vterm_input_write(active->vt, buf, len); } fbterm_redraw(active); /* Write output */ while (vterm_output_get_buffer_current(active->vt) > 0) { size_t s = vterm_output_read(active->vt, buf, 1024); write(pty, buf, s); } } return 0; } char *pts_fn = NULL; /* XXX */ void launch_shell() { int shell_pid = 0; relaunch: if (shell_pid = fork()) { /* Relaunch shell if died */ int s, pid; do { pid = waitpid(shell_pid, &s, 0); } while (pid != shell_pid); /* Uh..Oh shell died */ goto relaunch; } else { for (int i = 0; i < 10; ++i) close(i); int stdin_fd = open(pts_fn, O_RDONLY); int stdout_fd = open(pts_fn, O_WRONLY); int stderr_fd = open(pts_fn, O_WRONLY); /* run login shell */ char *argp[] = {DEFAULT_SHELL, "login", NULL}; char *envp[] = {"PWD=/", "TERM=VT100", NULL}; execve(DEFAULT_SHELL, argp, envp); for (;;); } }