WINDOW* vwmterm_init(gpointer anything) { extern WINDOW *SCREEN_WINDOW; extern ps_runq_t *vwm_runq; vterm_t *vterm; WINDOW *window; gint width,height; int master_fd; int fflags; getmaxyx(SCREEN_WINDOW,height,width); if(height>30 && width>84) { height=25; width=80; } else { /* calculate scaled window size */ window_get_size_scaled(NULL,&width,&height,0.85,0.65); if(width>80) width=80; if(height>25) height=25; } vterm=vterm_create(width,height,0); vterm_set_colors(vterm,COLOR_WHITE,COLOR_BLACK); master_fd=vterm_get_pty_fd(vterm); // configure SIGIO acceleration #ifdef SIGPOLL vwmterm_sigset(SIGPOLL,vwmterm_SIGIO); #else vwmterm_sigset(SIGIO,vwmterm_SIGIO); #endif fcntl(master_fd,F_SETOWN,getpid()); fflags=fcntl(master_fd,F_GETFL); fcntl(master_fd,F_SETFL,fflags | FASYNC); viper_thread_enter(); // create window window=viper_window_create(" VTerm ",0.5,0.5,width,height,TRUE); viper_window_set_state(window,STATE_UNSET | STATE_NORESIZE); viper_window_set_limits(window,15,2,WSIZE_UNCHANGED,WSIZE_UNCHANGED); // libviper set the default bkgd OR to WHITE on BLACK. undo it. wbkgdset(window,0); wattron(window,VIPER_COLORS(COLOR_WHITE,COLOR_BLACK)); // init terminal vterm_wnd_set(vterm,window); vterm_erase(vterm); // attache event handlers viper_event_set(window,"window-resized",vwmterm_ON_RESIZE,(gpointer)vterm); viper_event_set(window,"window-close",vwmterm_ON_CLOSE,(gpointer)vterm); viper_event_set(window,"window-destroy",vwmterm_ON_DESTROY, (gpointer)vterm); viper_window_set_key_func(window,vwmterm_ON_KEYSTROKE); viper_window_set_userptr(window,(gpointer)vterm); // push pseudo-thread onto run queue psthread_add(vwm_runq,vwmterm_psthread,(gpointer)window); viper_thread_leave(); return window; }
vterm_t* vterm_create(guint width,guint height,guint flags) { vterm_t *vterm; struct passwd *user_profile; const char *user_shell=NULL; pid_t child_pid; int master_fd; struct winsize ws={0};//.ws_xpixel=0,.ws_ypixel=0}; // int cell_count; guint i; if(height <= 0 || width <= 0) return NULL; vterm=(vterm_t*)g_malloc0(sizeof(vterm_t)); /* record dimensions */ vterm->rows=height; vterm->cols=width; // cell_count=width*height; /* create the cell matrix */ vterm->cells=(vterm_cell_t**)g_malloc0(sizeof(vterm_cell_t*)*height); for(i=0;i < height;i++) { vterm->cells[i]=(vterm_cell_t*)g_malloc0(sizeof(vterm_cell_t)*width); } // initialize all cells with defaults vterm_erase(vterm); // initialization of other public fields vterm->crow=0; vterm->ccol=0; // default active colors vterm->curattr = A_NORMAL;//COLOR_PAIR_TV(vterm->colors); //fprintf(stderr, "vterm->curattr = %d\n", vterm->curattr); // initial scrolling area is the whole window vterm->scroll_min=0; vterm->scroll_max=height-1; vterm->flags=flags; memset(&ws,0,sizeof(ws)); ws.ws_row=height; ws.ws_col=width; child_pid=forkpty(&master_fd,NULL,NULL,&ws); vterm->pty_fd=master_fd; if(child_pid < 0) { vterm_destroy(vterm); return NULL; } if(child_pid==0) { signal(SIGINT,SIG_DFL); // default is rxvt emulation setenv("TERM","rxvt",1); if(flags & VTERM_FLAG_VT100) { setenv("TERM","vt100",1); } user_profile=getpwuid(getuid()); if(user_profile==NULL) user_shell="/bin/sh"; else if(user_profile->pw_shell==NULL) user_shell="/bin/sh"; else user_shell=user_profile->pw_shell; if(user_shell==NULL) user_shell="/bin/sh"; //fprintf(stderr, "execl\n"); // start the shell if(execl(user_shell,user_shell,"-l",NULL)==-1) { //fprintf(stderr, "FAIL\n"); exit(EXIT_FAILURE); } //fprintf(stderr, "OK\n"); exit(EXIT_SUCCESS); } vterm->child_pid=child_pid; if(ttyname_r(master_fd,vterm->ttyname,sizeof(vterm->ttyname)-1) !=0) { snprintf(vterm->ttyname,sizeof(vterm->ttyname)-1,"vterm"); } if(flags & VTERM_FLAG_VT100) vterm->write=vterm_write_vt100; else vterm->write=vterm_write_rxvt; return vterm; }