/* * refresh_screen: Whenever the REFRESH_SCREEN function is activated, this * swoops into effect */ void refresh_screen (unsigned char dumb, char *dumber) { extern int need_redraw; #if !defined(WINNT) && !defined(__EMX__) term_clear_screen(); unflash(); #else xterm_settitle(); term_clear_screen(); #endif #if 0 for (tmp = screen_list; tmp; tmp = tmp->next) tmp->co = TI_cols, tmp->li = TI_lines; #endif if (term_resize()) recalculate_windows(current_window->screen); else redraw_all_windows(); if (need_redraw) need_redraw = 0; update_all_windows(); update_input(UPDATE_ALL); }
void redraw_all_screens (void) { Screen *s, *old_os; old_os = output_screen; for (s = screen_list; s; s = s->next) { if (!s->alive) continue; output_screen = s; unflash(); term_clear_screen(); if (s == main_screen && term_resize()) recalculate_windows(current_window->screen); } /* Logically mark all windows as needing a redraw */ redraw_all_windows(); /* Physically redraw all windows and status bars */ update_all_windows(); /* Physically redraw all input lines */ update_input(NULL, UPDATE_ALL); output_screen = old_os; need_redraw = 0; }
void x_resize(size_t width, size_t height) { if (X.win_width == width && X.win_height == height) { return; } debug("%lux%lu", (long unsigned)width, (long unsigned)height); /* Update pixmap */ if (X.pixmap) XFreePixmap(X.dpy, X.pixmap); X.pixmap = XCreatePixmap(X.dpy, X.window, width, height, XDefaultDepth(X.dpy, X.screen)); XSetForeground(X.dpy, X.gc, config.background); XFillRectangle(X.dpy, X.pixmap, X.gc, 0, 0, width, height); X.win_width = width; X.win_height = height; size_t glyphs_w = X.win_width / X.glyph_width; size_t glyphs_h = X.win_height / X.glyph_height; term_resize(glyphs_w, glyphs_h); }
static void sig_term_resize(int sig GCC_UNUSED) { struct winsize newsize; Signal(SIGWINCH, SIG_IGN); /* Don't bother me! */ ioctl(0, TIOCGWINSZ, &newsize); term_resize(newsize.ws_col, newsize.ws_row); }
/* * refresh_screen: Whenever the REFRESH_SCREEN function is activated, this * swoops into effect */ void refresh_screen(u_int key, u_char *ptr) { term_clear_screen(); if (term_resize()) #if 1 balance_windows(); #else recalculate_windows(); #endif else
/* init_windows: */ int init_screen (void) { extern int term_initialized; term_initialized = 1; term_clear_screen(); term_resize(); create_new_screen(); new_window(main_screen); update_all_windows(); term_move_cursor(0, 0); return 0; }
/* Resize the terminal if needed */ void term_resize_dirty(void) { int width, height; if (!resize_dirty) return; resize_dirty = FALSE; if (!term_get_size(&width, &height)) width = height = -1; term_resize(width, height); mainwindows_resize(term_width, term_height); term_resize_final(width, height); }
void refresh_a_screen (Screen *screen) { unflash(); term_clear_screen(); if (screen != main_screen || term_resize()) recalculate_windows(screen); else redraw_all_windows(); if (need_redraw) need_redraw = 0; update_all_windows(); update_input(UPDATE_ALL); }
/* * init_screen() sets up a full screen display for normal display mode. * It will fail if your TERM setting doesn't have all of the necessary * capabilities to run in full screen mode. The client is expected to * fail-over to dumb mode in this case. * This may only be called once, at initial startup (by main()). */ int init_screen (void) { /* Investigate TERM and put the console in full-screen mode */ if (term_init()) return -1; term_clear_screen(); term_resize(); /* * System independant stuff */ create_new_screen(); new_window(main_screen); update_all_windows(); term_move_cursor(0, 0); return 0; }
/* init_windows: */ int init_screen (void) { /* * System dependant stuff */ if (term_init()) return -1; term_clear_screen(); term_resize(); /* * System independant stuff */ create_new_screen(); new_window(main_screen); update_all_windows(); term_move_cursor(0, 0); return 0; }
int main(int argc, char* argv[]) { printf("START! pid = %d\n", getpid()); if (!system("./restart.rb")) exit(1); if (signal(SIGUSR1, RestartHandler) == SIG_ERR) { fprintf(stderr, "An error occurred while setting a signal handler.\n"); exit(1); } bool fullscreen = true; s_config = new AppConfig(fullscreen, false, 1280, 800); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK); SDL_Window* displayWindow; SDL_Renderer* displayRenderer; uint32_t flags = SDL_WINDOW_OPENGL | (s_config->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); int err = SDL_CreateWindowAndRenderer(s_config->width, s_config->height, flags, &displayWindow, &displayRenderer); if (err == -1 || !displayWindow || !displayRenderer) { fprintf(stderr, "SDL_CreateWindowAndRenderer failed!\n"); } SDL_RendererInfo displayRendererInfo; SDL_GetRendererInfo(displayRenderer, &displayRendererInfo); /* TODO: Check that we have OpenGL */ if ((displayRendererInfo.flags & SDL_RENDERER_ACCELERATED) == 0 || (displayRendererInfo.flags & SDL_RENDERER_TARGETTEXTURE) == 0) { /* TODO: Handle this. We have no render surface and not accelerated. */ fprintf(stderr, "NO RENDERER wtf!\n"); } atexit(SDL_Quit); JOYSTICK_Init(); AppConfig& config = *s_config; config.title = "riftty"; //SDL_WM_SetCaption(config.title.c_str(), config.title.c_str()); //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); /* // clear glClearColor(s_clearColor.x, s_clearColor.y, s_clearColor.z, s_clearColor.w); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); SDL_GL_SwapWindow(displayWindow); */ RiftSetup(); RenderInit(); win_init(); init_config(); struct passwd *pw = getpwuid(getuid()); const char *homedir = pw->pw_dir; char config_filename[512]; strncpy(config_filename, homedir, 512); strncat(config_filename, "/.riftty", 512); load_config(config_filename); cs_init(); // TODO: code pages do not want // TODO: determine this based on window-size & font-size or vice versa. cfg.rows = 25; cfg.cols = 80; // TODO: load config from /etc/riffty or ~/.rifttyrc finish_config(); win_reconfig(); // TODO: get SHELL from env cs_reconfig(); // TODO: do not want term_init(); term_reset(); term_resize(cfg.rows, cfg.cols); // TODO: int font_width = 10; int font_height = 10; unsigned short term_width = font_width * cfg.cols; unsigned short term_height = font_height * cfg.rows; char login[128]; strncpy(login, getlogin(), 128); const char* login_argv[] = {"login", "-pfl", login, NULL}; unsigned short rows = cfg.rows; unsigned short cols = cfg.cols; winsize ws = {rows, cols, term_width, term_height}; child_create(login_argv, &ws); bool done = false; while (!done) { JOYSTICK_ClearFlags(); SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: done = true; break; case SDL_MOUSEMOTION: if (event.motion.state & SDL_BUTTON(1)) { // move touch } break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_LEFT) { // start touch } break; case SDL_MOUSEBUTTONUP: if (event.button.button == SDL_BUTTON_LEFT) { // end touch } break; case SDL_JOYAXISMOTION: JOYSTICK_UpdateMotion(&event.jaxis); break; case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: JOYSTICK_UpdateButton(&event.jbutton); break; case SDL_KEYDOWN: case SDL_KEYUP: if (ProcessKeyEvent(&event.key)) { done = true; } break; } } if (!done) { if (s_needsRestart) Restart(); unsigned int now = SDL_GetTicks(); // milliseconds float dt = (now - s_ticks) / 1000.0f; // convert to seconds. s_ticks = now; //printf("fps = %.0f\n", 1.0f/dt); Process(dt); Render(dt); } } child_kill(true); win_shutdown(); RiftShutdown(); JOYSTICK_Shutdown(); return 0; }
void reattach_tty(char *tty, char *password) { int s = -1; char *name; struct sockaddr_in addr; struct hostent *hp; int len = 0; fd_set rd_fd; struct timeval tm = {0}; char chr_c[] = "\003"; /* * this buffer has to be big enough to handle a full screen of * information from the detached process. */ unsigned char buffer[6 * BIG_BUFFER_SIZE + 1]; char *p; int port = 0; #if defined (TIOCGWINSZ) struct winsize window; #endif memset(&parm, 0, sizeof(struct param)); if (!(name = find_detach_socket(socket_path, tty))) { fprintf(stderr, "No detached process to attach to.\r\n"); _exit(1); } strcpy(parm.cookie, get_cookie(name)); if (!*parm.cookie) _exit(1); if ((p = strrchr(name, '/'))) p++; sscanf(p, "%d.%*s.%*s", &port); displays = 1; if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { displays = 0; _exit(1); } chmod(name, SOCKMODE); set_socket_options(s); memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_port = htons(port); addr.sin_family = AF_INET; if ((hp = gethostbyname("localhost"))) memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); else inet_aton("127.0.0.1", (struct in_addr *)&addr.sin_addr); if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { fprintf(stderr, "connection refused for %s\r\n", name); _exit(1); } parm.pid = getpid(); parm.pgrp = getpgrp(); parm.uid = getuid(); strcpy(parm.tty, ttyname(0)); strncpy(parm.termid, getenv("TERM"), 80); if (password) strncpy(parm.password, password, 60); fprintf(stderr, "attempting to wakeup %s\r\n", find_tty_name(name)); #if defined (TIOCGWINSZ) if (ioctl(0, TIOCGWINSZ, &window) > -1) { parm.cols = window.ws_col; parm.rows = window.ws_row; } else #endif { parm.cols = 79; parm.rows = 25; } write(s, &parm, sizeof(struct param)); sleep(2); alarm(15); len = read(s, &parm, sizeof(struct param)); alarm(0); if (len <= 0) { fprintf(stderr, "[1;37merror[0;37m reconnecting to %s\r\n", find_tty_name(name)); displays = 0; chmod(name, SOCKMODE); exit(1); } unlink(name); term_init(parm.termid); set_term_eight_bit(1); charset_ibmpc(); term_clear_screen(); term_resize(); term_move_cursor(0, 0); my_signal(SIGPIPE, handle_pipe, 0); my_signal(SIGINT, handle_ctrlc, 0); my_signal(SIGHUP, handle_hup, 0); /* * according to MHacker we need to set errno to 0 under BSD. * for some reason we get a address in use from a socket * */ errno = 0; while (1) { FD_ZERO(&rd_fd); FD_SET(0, &rd_fd); FD_SET(s, &rd_fd); tm.tv_sec = 2; switch (select(s + 1, &rd_fd, NULL, NULL, &tm)) { case -1: if (ctrl_c) { write(s, chr_c, 1); ctrl_c = 0; } else if (errno != EINTR) { close(s); _exit(1); } break; case 0: break; default: { if (FD_ISSET(0, &rd_fd)) { len = read(0, buffer, sizeof(buffer) - 1); write(s, buffer, len); } if (FD_ISSET(s, &rd_fd)) { len = read(s, buffer, sizeof(buffer) - 1); write(1, buffer, len); } } } } close(s); fprintf(stderr, "Never should have got here"); _exit(1); return; /* error return */ }
/* input: raw character * output: telnet command if c was handled, otherwise zero. */ unsigned int telnet_handler(unsigned char c) { static unsigned char iac_quote = 0; /* as byte to reduce memory */ static unsigned char iac_opt_req = 0; static unsigned char iac_buf[TELNET_IAC_MAXLEN]; static unsigned int iac_buflen = 0; /* we have to quote all IACs. */ if(c == IAC && !iac_quote) { iac_quote = 1; return NOP; } #ifdef DETECT_CLIENT /* hash client telnet sequences */ if(cuser.userid[0]==0) { if(iac_state == IAC_WAIT_SE) { // skip suboption } else { if(iac_quote) UpdateClientCode(IAC); UpdateClientCode(c); } } #endif /* a special case is the top level iac. otherwise, iac is just a quote. */ if (iac_quote) { if(iac_state == IAC_NONE) iac_state = IAC_COMMAND; if(iac_state == IAC_WAIT_SE && c == SE) iac_state = IAC_PROCESS_OPT; iac_quote = 0; } /* now, let's process commands by state */ switch(iac_state) { case IAC_NONE: return 0; case IAC_COMMAND: #if 0 // def DEBUG { int cx = c; /* to make compiler happy */ write(0, "-", 1); if(TELCMD_OK(cx)) write(0, TELCMD(c), strlen(TELCMD(c))); write(0, " ", 1); } #endif iac_state = IAC_NONE; /* by default we restore state. */ switch(c) { case IAC: // return 0; // we don't want to allow IACs as input. return 1; /* we don't want to process these. or maybe in future. */ case BREAK: /* break */ #ifdef DBG_OUTRPT fakeEscape = !fakeEscape; return NOP; #endif case ABORT: /* Abort process */ case SUSP: /* Suspend process */ case AO: /* abort output--but let prog finish */ case IP: /* interrupt process--permanently */ case EOR: /* end of record (transparent mode) */ case DM: /* data mark--for connect. cleaning */ case xEOF: /* End of file: EOF is already used... */ return NOP; case NOP: /* nop */ return NOP; /* we should process these, but maybe in future. */ case GA: /* you may reverse the line */ case EL: /* erase the current line */ case EC: /* erase the current character */ return NOP; /* good */ case AYT: /* are you there */ { const char *alive = "I'm still alive, loading: "; char buf[STRLEN]; /* respond as fast as we can */ write(0, alive, strlen(alive)); // cpuload(buf); buf[0] = '0'; // TODO: cpuload write(0, buf, strlen(buf)); write(0, "\r\n", 2); } return NOP; case DONT: /* you are not to use option */ case DO: /* please, you use option */ case WONT: /* I won't use option */ case WILL: /* I will use option */ iac_opt_req = c; iac_state = IAC_WAIT_OPT; return NOP; case SB: /* interpret as subnegotiation */ iac_state = IAC_WAIT_SE; iac_buflen = 0; return NOP; case SE: /* end sub negotiation */ default: return NOP; } return 1; case IAC_WAIT_OPT: #if 0 // def DEBUG write(0, "-", 1); if(TELOPT_OK(c)) write(0, TELOPT(c), strlen(TELOPT(c))); write(0, " ", 1); #endif iac_state = IAC_NONE; /* * According to RFC, there're some tricky steps to prevent loop. * However because we have a poor term which does not allow * most abilities, let's be a strong boss here. * * Although my old imeplementation worked, it's even better to follow this: * http://www.tcpipguide.com/free/t_TelnetOptionsandOptionNegotiation-3.htm */ switch(c) { /* i-dont-care: i don't care about what client is. * these should be clamed in init and * client must follow me. */ case TELOPT_TTYPE: /* termtype or line. */ case TELOPT_NAWS: /* resize terminal */ case TELOPT_SGA: /* supress GA */ case TELOPT_ECHO: /* echo */ case TELOPT_BINARY: /* we are CJK. */ break; /* i-dont-agree: i don't understand/agree these. * according to RFC, saying NO stopped further * requests so there'll not be endless loop. */ case TELOPT_RCP: /* prepare to reconnect */ default: if (iac_opt_req == WILL || iac_opt_req == DO) { /* unknown option, reply with won't */ unsigned char cmd[3] = { IAC, DONT, 0 }; if(iac_opt_req == DO) cmd[1] = WONT; cmd[2] = c; write(0, cmd, sizeof(cmd)); } break; } return 1; case IAC_WAIT_SE: iac_buf[iac_buflen++] = c; /* no need to convert state because previous quoting will do. */ if(iac_buflen == TELNET_IAC_MAXLEN) { /* may be broken protocol? * whether finished or not, break for safety * or user may be frozen. */ iac_state = IAC_NONE; return 0; } return 1; case IAC_PROCESS_OPT: iac_state = IAC_NONE; #if 0 // def DEBUG write(0, "-", 1); if(TELOPT_OK(iac_buf[0])) write(0, TELOPT(iac_buf[0]), strlen(TELOPT(iac_buf[0]))); write(0, " ", 1); #endif switch(iac_buf[0]) { /* resize terminal */ case TELOPT_NAWS: { int w = (iac_buf[1] << 8) + (iac_buf[2]); int h = (iac_buf[3] << 8) + (iac_buf[4]); term_resize(w, h); #ifdef DETECT_CLIENT if(cuser.userid[0]==0) { UpdateClientCode(iac_buf[0]); if(w==80 && h==24) UpdateClientCode(1); else if(w==80) UpdateClientCode(2); else if(h==24) UpdateClientCode(3); else UpdateClientCode(4); UpdateClientCode(IAC); UpdateClientCode(SE); } #endif } break; default: #ifdef DETECT_CLIENT if(cuser.userid[0]==0) { int i; for(i=0;i<iac_buflen;i++) UpdateClientCode(iac_buf[i]); UpdateClientCode(IAC); UpdateClientCode(SE); } #endif break; } return 1; } return 1; /* never reached */ }
int main (int argc, char **argv) { fd_set reads; int nread; char * port; char * host; char * tmp; char stuff[100]; my_signal(SIGHUP, SIG_IGN); my_signal(SIGQUIT, SIG_IGN); my_signal(SIGINT, ignore); my_signal(SIGWINCH, sigwinch_func); if (argc != 3) /* no socket is passed */ my_exit(1); host = argv[1]; port = argv[2]; if ((data = connectory(host, port)) < 0) my_exit(23); if ((cmd = connectory(host, port)) < 0) my_exit(25); /* * First thing we do is tell the parent what protocol we plan on * talking. We will start the protocol at version 4, for this is * the fourth generation of wservs. * * We cannot use 'snprintf' here because we do not have the compat * functions and some systems do not have snprintf! This use of * sprintf is demonstrably safe. */ sprintf(stuff, "version=%d\n", CURRENT_WSERV_VERSION); write(cmd, stuff, strlen(stuff)); /* * Next thing we take care of is to tell the parent client * what tty we are using and tell them what geometry our screen * is. This provides some amount of sanity against whatever * brain damage might occur. The parent client takes our word * for what size this screen should be, and handles it accordingly. * * Warning: I am using sprintf() and write() because previous * attempts to use writev() have shown that linux does not have * an atomic writev() function (boo, hiss). The parent client * does not take kindly to this data coming in multiple packets. */ tmp = ttyname(0); sprintf(stuff, "tty=%s\n", tmp); write(cmd, stuff, strlen(stuff)); term_init(); /* Set up the xterm */ term_resize(); /* Figure out how big xterm is and tell epic */ /* * The select call.. reads from the socket, and from the window.. * and pipes the output from out to the other.. nice and simple. * The command pipe is write-only. The parent client does not * send anything to us over the command pipe. */ for (;;) { FD_ZERO(&reads); FD_SET(0, &reads); FD_SET(data, &reads); if (select(data + 1, &reads, NULL, NULL, NULL) <= 0) { if (errno == EINTR && got_sigwinch) { got_sigwinch = 0; term_resize(); } continue; } if (FD_ISSET(0, &reads)) { if ((nread = read(0, buffer, sizeof(buffer))) > 0) write(data, buffer, nread); else my_exit(3); } if (FD_ISSET(data, &reads)) { if ((nread = read(data, buffer, sizeof(buffer))) > 0) write(0, buffer, nread); else my_exit(4); } } my_exit(8); }