/* ================== CON_Resize The window has just been resized, move everything back into place ================== */ static void CON_Resize(void) { #ifndef _WIN32 struct winsize winsz = {0, }; ioctl(fileno(stdout), TIOCGWINSZ, &winsz); if (winsz.ws_col < 12 || winsz.ws_row < 5) return; resizeterm(winsz.ws_row + 1, winsz.ws_col + 1); resizeterm(winsz.ws_row, winsz.ws_col); delwin(logwin); delwin(borderwin); delwin(inputwin); delwin(scrollwin); erase(); wnoutrefresh(stdscr); CON_Init(); #endif }
void WindowManager::resetWindows() { stdscrDimensions.x = getmaxx(stdscr); stdscrDimensions.y = getmaxy(stdscr); resizeterm(stdscrDimensions.y,stdscrDimensions.x); wclear(stdscr); init_title(); init_levelView(); init_gameLog(); init_debugLog(); }
/*** Change the terminal size. @function resizeterm @int nlines number of lines @int ncols number of columns @treturn bool `true`, if successful @raise unimplemented @fixme ncurses only? */ static int Presizeterm(lua_State *L) { int nlines = checkint(L, 1); int ncols = checkint(L, 2); #if HAVE_RESIZETERM return pushokresult(resizeterm (nlines, ncols)); #else return binding_notimplemented(L, "resizeterm", "curses"); #endif }
void debug_console::recreate_terminal() { term_change = false; determine_terminal_size(&max_y, &max_x); resizeterm(max_y, max_x); endwin(); refresh(); /* <- as specified by ncurses faq, was: doupdate(); */ create_windows(); }
void MainProg::smartresize() { if (!MainProg::needresize) return; struct winsize size; ioctl(fileno(stdout), TIOCGWINSZ, (char *) &size); resizeterm(size.ws_row, size.ws_col); menu->resize(1, getmaxx(stdscr)); //ширина верхнего меню wmain->resize(getmaxy(stdscr)-2, getmaxx(stdscr)); wstatus->resize(1, getmaxx(stdscr)); //ширина статус строки wstatus->move(getmaxy(stdscr)-1,0); //позиция статус строки centermodalitems(getmaxy(stdscr),getmaxx(stdscr)); //центрировать модальные формы (если есть) MainProg::needresize = false; }
void resize_curses(void) { int eLines = -1, eCols = -2; char *x; int i_mx, i_my; getmaxyx(stdscr, i_my, i_mx); x = getenv("LINES"); if (x != NULL) { eLines = atoi(x); } x = getenv("COLUMNS"); if (x != NULL) { eCols = atoi(x); } debug(DEBUGLEVEL_INFO, "resize(%d, %d) -> %d, %d -> %d, %d\n", COLS, LINES, eCols, eLines, i_mx, i_my); resizeterm(LINES, COLS); }
static void ui_resize(Ui *ui) { struct winsize ws; int width, height; if (ioctl(STDERR_FILENO, TIOCGWINSZ, &ws) == -1) { getmaxyx(stdscr, height, width); } else { width = ws.ws_col; height = ws.ws_row; } resizeterm(height, width); wresize(stdscr, height, width); ui_resize_to(ui, width, height); }
/* * This uses functions that are "unsafe", but it seems to work on SunOS and * Linux. The 'wrefresh(curscr)' is needed to force the refresh to start from * the top of the screen -- some xterms mangle the bitmap while resizing. */ static RETSIGTYPE adjust(int sig) { if (waiting || sig == 0) { struct winsize size; if (ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) { resizeterm(size.ws_row, size.ws_col); wrefresh(curscr); /* Linux needs this */ show_all(); } interrupted = FALSE; } else { interrupted = TRUE; } (void) signal(SIGWINCH, adjust); /* some systems need this */ }
void screen_resize(struct mpdclient *c) { if (COLS<SCREEN_MIN_COLS || LINES<SCREEN_MIN_ROWS) { screen_exit(); fprintf(stderr, "%s\n", _("Error: Screen too small")); exit(EXIT_FAILURE); } #ifdef PDCURSES resize_term(LINES, COLS); #else resizeterm(LINES, COLS); #endif screen.cols = COLS; screen.rows = LINES; title_bar_resize(&screen.title_bar, screen.cols); /* main window */ screen.main_window.cols = screen.cols; screen.main_window.rows = screen.rows-4; wresize(screen.main_window.w, screen.main_window.rows, screen.cols); wclear(screen.main_window.w); /* progress window */ progress_bar_resize(&screen.progress_bar, screen.cols, screen.rows - 2, 0); progress_bar_paint(&screen.progress_bar); /* status window */ status_bar_resize(&screen.status_bar, screen.cols, screen.rows - 1, 0); status_bar_paint(&screen.status_bar, c->status, c->song); screen.buf_size = screen.cols; g_free(screen.buf); screen.buf = g_malloc(screen.cols); /* resize all screens */ screen_list_resize(screen.main_window.cols, screen.main_window.rows); /* ? - without this the cursor becomes visible with aterm & Eterm */ curs_set(1); curs_set(0); screen_paint(c); }
void ui_resize(void) { struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); erase(); resizeterm(w.ws_row, w.ws_col); refresh(); log_debug("Resizing UI"); title_bar_resize(); wins_resize_all(); status_bar_resize(); inp_win_resize(); ProfWin *window = wins_get_current(); win_update_virtual(window); }
/* this routine should be called after receiving SIGWINCH */ void mutt_resize_screen (void) { char *cp; int fd; struct winsize w; #ifdef HAVE_RESIZETERM int SLtt_Screen_Rows, SLtt_Screen_Cols; #endif SLtt_Screen_Rows = -1; SLtt_Screen_Cols = -1; if ((fd = open ("/dev/tty", O_RDONLY)) != -1) { if (ioctl (fd, TIOCGWINSZ, &w) != -1) { SLtt_Screen_Rows = w.ws_row; SLtt_Screen_Cols = w.ws_col; } close (fd); } if (SLtt_Screen_Rows <= 0) { if ((cp = getenv ("LINES")) != NULL) { SLtt_Screen_Rows = atoi (cp); } else SLtt_Screen_Rows = 24; } if (SLtt_Screen_Cols <= 0) { if ((cp = getenv ("COLUMNS")) != NULL) SLtt_Screen_Cols = atoi (cp); else SLtt_Screen_Cols = 80; } #ifdef USE_SLANG_CURSES delwin (stdscr); SLsmg_reset_smg (); SLsmg_init_smg (); stdscr = newwin (0, 0, 0, 0); keypad (stdscr, TRUE); #else resizeterm (SLtt_Screen_Rows, SLtt_Screen_Cols); #endif }
void redraw_all (void) { int min_lines = TITLE_WIN_LINES+SHOW_WIN_LINES+COMMAND_WIN_LINES+3; struct winsize ws; int save_col, save_lines; /* get the size of the terminal connected to stdout */ ioctl(1, TIOCGWINSZ, &ws); /* * Do it again because GDB doesn't stop before the first ioctl * call, we want an up-to-date size when we're * single-stepping. */ if (ioctl(1, TIOCGWINSZ, &ws) == 0) { if (ws.ws_row < min_lines) ws.ws_row = min_lines; if ((ws.ws_row != LINES) || (ws.ws_col != COLS)) { wmove (show_win,2,COLS-18); wclrtoeol(show_win); wrefresh(show_win); resizeterm(ws.ws_row, ws.ws_col); wresize(title_win, TITLE_WIN_LINES,COLS); wresize(show_win, SHOW_WIN_LINES,COLS); wresize(command_win, COMMAND_WIN_LINES,COLS); wresize(mt_win1, 1,COLS); wresize(mt_win2, 1,COLS); mvwin(mt_win2, LINES-COMMAND_WIN_LINES-1,0); mvwin(command_win, LINES-COMMAND_WIN_LINES,0); draw_title_win(); show_pad_info.display_lines=LINES-TITLE_WIN_LINES-SHOW_WIN_LINES-COMMAND_WIN_LINES-2; show_pad_info.display_cols=COLS; } } clearok(title_win, 1); clearok(show_win, 1); clearok(command_win, 1); clearok(mt_win1, 1); clearok(mt_win2, 1); wrefresh(mt_win1); wrefresh(mt_win2); refresh_show_pad(); refresh_show_win(); refresh_title_win (); refresh_command_win (); }
static void tresize(void) { struct winsize ws; winchg=0; if (ioctl(0, TIOCGWINSZ, &ws)<0) panic("Ioctl (TIOCGWINSZ) failed."); resizeterm(scr.y=ws.ws_row, scr.x=ws.ws_col); if (scr.y<3 || scr.x<10) panic("Screen too small."); wresize(scr.mw, scr.y-2, scr.x); wresize(scr.iw, 1, scr.x); wresize(scr.sw, 1, scr.x); mvwin(scr.iw, scr.y-1, 0); tredraw(); tdrawbar(); }
static void resize(void) { struct winsize ws; if (ioctl(fileno(stdout), TIOCGWINSZ, &ws) != -1 && ws.ws_row && ws.ws_col) { LINES = ws.ws_row; COLS = ws.ws_col; #if HAVE_RESIZETERM resizeterm(ws.ws_row, ws.ws_col); #endif clearok(stdscr, TRUE); } touchwin(stdscr); DBG(FRONTEND, ul_debug("ui: resize refresh COLS=%d, LINES=%d", COLS, LINES)); ui_resize = 0; }
bool set_game_size() { struct winsize w; ioctl(0, TIOCGWINSZ, &w); int y_save = ScreenVars::MAX_BOARD_Y; int x_save = ScreenVars::MAX_BOARD_X; ScreenVars::MAX_BOARD_Y = w.ws_row - 1; ScreenVars::MAX_BOARD_X = (w.ws_col / 2) - 1; if (y_save != ScreenVars::MAX_BOARD_Y || x_save != ScreenVars::MAX_BOARD_X) { // Only resize term if window size changed resizeterm(w.ws_row, w.ws_col); return true; } return false; }
void resize_screen(void) { char *tty; int fd = 0; int result = 0; struct winsize win; tty = ttyname(0); if (!tty) { return; } fd = open(tty, O_RDWR); if (fd == -1) { return; } result = ioctl(fd, TIOCGWINSZ, &win); if (result == -1) { return; } COLS = win.ws_col; LINES = win.ws_row; if(LINES <10){ LINES = 10; } if(COLS <10){ COLS = 10; } #ifdef HAVE_RESIZETERM resizeterm(LINES, COLS); #ifdef HAVE_WRESIZE if (wresize(stdscr, LINES, COLS) == ERR) { c_die("Cannot resize window!"); } #endif /* HAVE_WRESIZE */ #endif /* HAVE_RESIZETERM */ var_init(); /* Do these because width may have changed... */ clear(); refresh(); }
static void resize(void) { struct winsize ws; if (ioctl(fileno(stdout), TIOCGWINSZ, &ws) != -1 && ws.ws_row && ws.ws_col) { ui_lines = ws.ws_row; ui_cols = ws.ws_col; #if HAVE_RESIZETERM resizeterm(ws.ws_row, ws.ws_col); #endif clearok(stdscr, TRUE); } touchwin(stdscr); DBG(UI, ul_debug("ui: resize refresh ui_cols=%zu, ui_lines=%zu", ui_cols, ui_lines)); ui_resize = 0; }
void redraw(int signo) { sigset_t set; struct winsize win; sigemptyset(&set); sigaddset(&set, SIGALRM); sigprocmask(SIG_BLOCK, &set, NULL); if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1 && (win.ws_row != LINES || win.ws_col != COLS)) { resizeterm(win.ws_row, win.ws_col); CMDLINE = LINES - 1; labels(); } sigprocmask(SIG_UNBLOCK, &set, NULL); display(0); }
WindowManager::WindowManager( World &world, LogStream& gameLogStream, LogStream& debugLogStream) : title(nullptr), levelView(nullptr), gameLog(nullptr), debugLog(nullptr), stdscrDimensions(0,0), world(&world), gameLogStream(&gameLogStream), debugLogStream(&debugLogStream) { resizeterm(51,103); getmaxyx(stdscr,stdscrDimensions.y,stdscrDimensions.x); init_title(true); init_levelView(true); init_gameLog(true); init_debugLog(true); }
static void ncurses_handle_resize(caca_display_t *dp) { struct winsize size; #if defined HAVE_SYS_IOCTL_H if(ioctl(fileno(stdout), TIOCGWINSZ, &size) == 0) { dp->resize.w = size.ws_col; dp->resize.h = size.ws_row; #if defined HAVE_RESIZE_TERM resize_term(dp->resize.h, dp->resize.w); #else resizeterm(dp->resize.h, dp->resize.w); #endif wrefresh(curscr); return; } #endif /* Fallback */ dp->resize.w = caca_get_canvas_width(dp->cv); dp->resize.h = caca_get_canvas_height(dp->cv); }
void low_level_change_screen_size (void) { #if defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 #if defined TIOCGWINSZ && !defined SCO_FLAVOR struct winsize winsz; winsz.ws_col = winsz.ws_row = 0; /* Ioctl on the STDIN_FILENO */ ioctl (0, TIOCGWINSZ, &winsz); if (winsz.ws_col && winsz.ws_row){ #if defined(NCURSES_VERSION) && defined(HAVE_RESIZETERM) resizeterm(winsz.ws_row, winsz.ws_col); clearok(stdscr,TRUE); /* FIXME: sigwinch's should use a semaphore! */ #else COLS = winsz.ws_col; LINES = winsz.ws_row; #endif #ifdef HAVE_SUBSHELL_SUPPORT resize_subshell (); #endif } #endif /* TIOCGWINSZ && !SCO_FLAVOR */ #endif /* defined(HAVE_SLANG) || NCURSES_VERSION_MAJOR >= 4 */ }
static void resize_display_all(void) { struct winsize winsz; /* get new window size */ winsz.ws_col = winsz.ws_row = 0; ioctl(0, TIOCGWINSZ, &winsz); /* ioctl on STDIN */ if (winsz.ws_col && winsz.ws_row) resizeterm(winsz.ws_row, winsz.ws_col); COLS = winsz.ws_col; LINES = winsz.ws_row; resize_display_main(); if (show_win) wresize(show_win, LINES-1, COLS); if (conf_win) { if (conf_win_current == 'f') mvwin(conf_win, LINES/2-12, COLS/2-28); else if (conf_win_current == 'c') mvwin(conf_win, LINES/2-5, COLS/2-20); } }
int main(int argc, const char * argv[]) { /* * Main function, this is what the OS calls when the * program execution is requested (and on some systems * after the signature is verified and a sandbox is set * up). This sets everything up for the game to be playable. * After everything is set up, it forwards its args to the * game function and all is good. */ //if (streamlib_version != GLOBAL_STREAMLIB_VERSION) if (!check_version_compadible()) //better method { cout << "Error! Streamlib error" << endl; exit(-1); } resizeterm(181, 48); environment_init(env); long seed = time(0); /* BEGIN DEVELOPER MODE CHECK */ if (argc > 1) { if (strcmp(argv[1], "developer-mode") == 0) { env.developer_mode = true; devsettings(); if (argc > 2) { seed = atol(argv[2]); } } else { seed = atol(argv[1]); } } /* END DEVELOPER MODE CHECK */ //clear(); int selection = -1; while (selection == -1) selection = displaylauncher(seed); extern int playernum; extern char * hostname; //env.allow_refresh = false; if (selection == 1) { //nothing here... idk why i added this } if (selection == 2) { env.music = false; } if (selection == 1 || selection == 2) { int difficulty_selection = 1; //patch for difficulty selections //while (difficulty_selection < 1 || difficulty_selection > 2) { selectdifficulty(); /*cout << "Please select a difficulty:" << endl << "1. Normal (1x damage and strength)" << endl << "2. Hard (2x damage and strength)" << endl << "--> Hard also has around 2.5x more enemies" << endl; cin >> difficulty_selection;*/ } env.difficulty = (character::difficulty)(difficulty_selection); } if (selection == 3) { multiplayer = true; cout << "Which player are you? (1/2) "; int player; cin >> player; playernum = player; strcpy(hostname, "localhost"); }
int main(int argc, char *argv[]) { int optc; int option_differences = 0, option_differences_cumulative = 0, option_exec = 0, option_beep = 0, option_errexit = 0, option_help = 0, option_version = 0; double interval = 2; char *command; char **command_argv; int command_length = 0; /* not including final \0 */ watch_usec_t next_loop; /* next loop time in us, used for precise time keeping only */ int pipefd[2]; int status; pid_t child; setlocale(LC_ALL, ""); progname = argv[0]; while ((optc = getopt_long(argc, argv, "+bed::hn:pvtx", longopts, (int *) 0)) != EOF) { switch (optc) { case 'b': option_beep = 1; break; case 'd': option_differences = 1; if (optarg) option_differences_cumulative = 1; break; case 'e': option_errexit = 1; break; case 'h': option_help = 1; break; case 't': show_title = 0; break; case 'x': option_exec = 1; break; case 'n': { char *str; interval = strtod(optarg, &str); if (!*optarg || *str) do_usage(); if(interval < 0.1) interval = 0.1; if(interval > ~0u/1000000) interval = ~0u/1000000; } break; case 'p': precise_timekeeping = 1; break; case 'v': option_version = 1; break; default: do_usage(); break; } } if (option_version) { fprintf(stderr, "%s\n", VERSION); if (!option_help) exit(0); } if (option_help) { fprintf(stderr, usage, progname); fputs(" -b, --beep\t\t\t\tbeep if the command has a non-zero exit\n", stderr); fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr); fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr); fputs(" -e, --errexit\t\t\t\texit watch if the command has a non-zero exit\n", stderr); fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr); fputs(" -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr); fputs(" -p, --precise\t\t\t\tprecise timing, ignore command run time\n", stderr); fputs(" -v, --version\t\t\t\tprint the version number\n", stderr); fputs(" -t, --no-title\t\t\tturns off showing the header\n", stderr); fputs(" -x, --exec\t\t\t\tpass command to exec instead of sh\n", stderr); exit(0); } if (optind >= argc) do_usage(); command_argv=&(argv[optind]); /* save for later */ command = strdup(argv[optind++]); command_length = strlen(command); for (; optind < argc; optind++) { char *endp; int s = strlen(argv[optind]); command = realloc(command, command_length + s + 2); /* space and \0 */ endp = command + command_length; *endp = ' '; memcpy(endp + 1, argv[optind], s); command_length += 1 + s; /* space then string length */ command[command_length] = '\0'; } get_terminal_size(); /* Catch keyboard interrupts so we can put tty back in a sane state. */ signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); signal(SIGWINCH, winch_handler); /* Set up tty for curses use. */ curses_started = 1; initscr(); nonl(); noecho(); cbreak(); if (precise_timekeeping) next_loop = get_time_usec(); for (;;) { time_t t = time(NULL); char *ts = ctime(&t); int tsl = strlen(ts); char *header; FILE *p; int x, y; int oldeolseen = 1; if (screen_size_changed) { get_terminal_size(); resizeterm(height, width); clear(); /* redrawwin(stdscr); */ screen_size_changed = 0; first_screen = 1; } if (show_title) { // left justify interval and command, // right justify time, clipping all to fit window width asprintf(&header, "Every %.1fs: %.*s", interval, min(width - 1, command_length), command); mvaddstr(0, 0, header); if (strlen(header) > (size_t) (width - tsl - 1)) mvaddstr(0, width - tsl - 4, "... "); mvaddstr(0, width - tsl + 1, ts); free(header); } /* allocate pipes */ if (pipe(pipefd)<0) { perror("pipe"); do_exit(7); } /* flush stdout and stderr, since we're about to do fd stuff */ fflush(stdout); fflush(stderr); /* fork to prepare to run command */ child=fork(); if (child<0) { /* fork error */ perror("fork"); do_exit(2); } else if (child==0) { /* in child */ close (pipefd[0]); /* child doesn't need read side of pipe */ close (1); /* prepare to replace stdout with pipe */ if (dup2 (pipefd[1], 1)<0) { /* replace stdout with write side of pipe */ perror("dup2"); exit(3); } dup2(1, 2); /* stderr should default to stdout */ if (option_exec) { /* pass command to exec instead of system */ if (execvp(command_argv[0], command_argv)==-1) { perror("exec"); exit(4); } } else { status=system(command); /* watch manpage promises sh quoting */ /* propagate command exit status as child exit status */ if (!WIFEXITED(status)) { /* child exits nonzero if command does */ exit(1); } else { exit(WEXITSTATUS(status)); } } } /* otherwise, we're in parent */ close(pipefd[1]); /* close write side of pipe */ if ((p=fdopen(pipefd[0], "r"))==NULL) { perror("fdopen"); do_exit(5); } for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0; for (x = 0; x < width; x++) { int c = ' '; int attr = 0; if (!eolseen) { /* if there is a tab pending, just spit spaces until the next stop instead of reading characters */ if (!tabpending) do c = getc(p); while (c != EOF && !isprint(c) && c != '\n' && c != '\t'); if (c == '\n') if (!oldeolseen && x == 0) { x = -1; continue; } else eolseen = 1; else if (c == '\t') tabpending = 1; if (c == EOF || c == '\n' || c == '\t') c = ' '; if (tabpending && (((x + 1) % 8) == 0)) tabpending = 0; } move(y, x); if (option_differences) { chtype oldch = inch(); unsigned char oldc = oldch & A_CHARTEXT; attr = !first_screen && ((char)c != oldc || (option_differences_cumulative && (oldch & A_ATTRIBUTES))); } if (attr) standout(); addch(c); if (attr) standend(); } oldeolseen = eolseen; } fclose(p); /* harvest child process and get status, propagated from command */ if (waitpid(child, &status, 0)<0) { perror("waitpid"); do_exit(8); }; /* if child process exited in error, beep if option_beep is set */ if ((!WIFEXITED(status) || WEXITSTATUS(status))) { if (option_beep) beep(); if (option_errexit) do_exit(8); } first_screen = 0; refresh(); if (precise_timekeeping) { watch_usec_t cur_time = get_time_usec(); next_loop += USECS_PER_SEC*interval; if (cur_time < next_loop) usleep(next_loop - cur_time); } else usleep(interval * 1000000); } endwin(); return 0; }
int main(int argc, char *argv[]) { int optc; int option_differences = 0, option_differences_cumulative = 0, option_help = 0, option_version = 0; double interval = 2; char *command; int command_length = 0; /* not including final \0 */ setlocale(LC_ALL, ""); progname = argv[0]; while ((optc = getopt_long(argc, argv, "+d::hn:vt", longopts, (int *) 0)) != EOF) { switch (optc) { case 'd': option_differences = 1; if (optarg) option_differences_cumulative = 1; break; case 'h': option_help = 1; break; case 't': show_title = 0; break; case 'n': { char *str; interval = strtod(optarg, &str); if (!*optarg || *str) do_usage(); if(interval < 0.1) interval = 0.1; if(interval > ~0u/1000000) interval = ~0u/1000000; } break; case 'v': option_version = 1; break; default: do_usage(); break; } } if (option_version) { fprintf(stderr, "%s\n", VERSION); if (!option_help) exit(0); } if (option_help) { fprintf(stderr, usage, progname); fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr); fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr); fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr); fputs(" -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr); fputs(" -v, --version\t\t\t\tprint the version number\n", stderr); fputs(" -t, --no-title\t\t\tturns off showing the header\n", stderr); exit(0); } if (optind >= argc) do_usage(); command = strdup(argv[optind++]); command_length = strlen(command); for (; optind < argc; optind++) { char *endp; int s = strlen(argv[optind]); command = realloc(command, command_length + s + 2); /* space and \0 */ endp = command + command_length; *endp = ' '; memcpy(endp + 1, argv[optind], s); command_length += 1 + s; /* space then string length */ command[command_length] = '\0'; } get_terminal_size(); /* Catch keyboard interrupts so we can put tty back in a sane state. */ signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); signal(SIGWINCH, winch_handler); /* Set up tty for curses use. */ curses_started = 1; initscr(); nonl(); noecho(); cbreak(); for (;;) { time_t t = time(NULL); char *ts = ctime(&t); int tsl = strlen(ts); char *header; FILE *p; int x, y; int oldeolseen = 1; if (screen_size_changed) { get_terminal_size(); resizeterm(height, width); clear(); /* redrawwin(stdscr); */ screen_size_changed = 0; first_screen = 1; } if (show_title) { // left justify interval and command, // right justify time, clipping all to fit window width asprintf(&header, "Every %.1fs: %.*s", interval, min(width - 1, command_length), command); mvaddstr(0, 0, header); if (strlen(header) > (size_t) (width - tsl - 1)) mvaddstr(0, width - tsl - 4, "... "); mvaddstr(0, width - tsl + 1, ts); free(header); } if (!(p = popen(command, "r"))) { perror("popen"); do_exit(2); } for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0; for (x = 0; x < width; x++) { int c = ' '; int attr = 0; if (!eolseen) { /* if there is a tab pending, just spit spaces until the next stop instead of reading characters */ if (!tabpending) do c = getc(p); while (c != EOF && !isprint(c) && c != '\n' && c != '\t'); if (c == '\n') if (!oldeolseen && x == 0) { x = -1; continue; } else eolseen = 1; else if (c == '\t') tabpending = 1; if (c == EOF || c == '\n' || c == '\t') c = ' '; if (tabpending && (((x + 1) % 8) == 0)) tabpending = 0; } move(y, x); if (option_differences) { chtype oldch = inch(); char oldc = oldch & A_CHARTEXT; attr = !first_screen && ((char)c != oldc || (option_differences_cumulative && (oldch & A_ATTRIBUTES))); } if (attr) standout(); addch(c); if (attr) standend(); } oldeolseen = eolseen; } pclose(p); first_screen = 0; refresh(); usleep(interval * 1000000); } endwin(); return 0; }
/*------------------------------------------------------------------------ * Program: piggy3 * * Purpose: Network middleware where a client can connect to the left side * of piggy and piggy can also connect to a server with an address specified * by -raddr option. Alternatively if -noright option is set then piggy will * echo what is read from the left. * * Syntax: piggy -option * * Options: * lacct_addr - specifies what address the server can accept. * raddr - specifies what address piggy should connect to. * noleft - flags that piggy should use stdin for it's left side. * noright - flags that piggy should use stdout for it's right side. * luseport - Port to use for left side server. * loopr - Data from the left that would be written to the right is looped back to the left. * loopl - Data from the right that would be written to the left is looped back to the right. * * The address for lacct_addr and raddr can be a dotted IP address or * a DNS name and the value must directly follow the argument. * * Note: No default address for right side so raddr value or noright * must be set. Laddr defaults to accepting any left side connection * which is equivalent to setting it's value to "*". * * The default port is 36790 *------------------------------------------------------------------------ */ main(int argc,char *argv[]) { /* setup for select */ int input_ready; struct timeval timeout; timeout.tv_sec = .5; /* loop through arguments and set values */ bool no_left = false; /* holds value of command line argument -noleft */ bool no_right = false;/* Holds value of command line argument -no_right */ char *lacct_addr = NULL;/* Holds the address of the left connect as either an IP address or DNS name*/ char *raddr = NULL; /* Holds the address of the left connect as either an IP address or DNS name*/ int lacctport = -1; /* Holds the port number will be accepted on the left connection */ int luseport = -1; /* Holds the port number that will be assigned to the left connection server */ int rport = -1; /* Holds the port number used when making the connection the raddr */ bool loopr = false; /* Holds value of command line argument -loopr */ bool loopl = false; /* Holds value of command line argument -loopl */ int arg_i; for (arg_i = 1; arg_i < argc; arg_i++){ if (strcmp(argv[arg_i],"-noleft") == 0) no_left = true; else if (strcmp(argv[arg_i], "-noright") == 0) no_right = true; else if (strcmp(argv[arg_i], "-laddr") == 0 && (arg_i + 1) < argc) lacct_addr = argv[++arg_i]; /* Note that this will also move arg_i past val */ else if (strcmp(argv[arg_i], "-raddr") == 0 && (arg_i + 1) < argc) raddr = argv[++arg_i]; /* Note that this will also move arg_i past val */ else if (strcmp(argv[arg_i], "-lacctport") == 0 && (arg_i + 1) < argc) lacctport = atoi(argv[++arg_i]); else if (strcmp(argv[arg_i], "-luseport") == 0 && (arg_i + 1) < argc) luseport = atoi(argv[++arg_i]); else if (strcmp(argv[arg_i], "-rport") == 0 && (arg_i + 1) < argc) rport = atoi(argv[++arg_i]); else if (strcmp(argv[arg_i], "-loopr") == 0) loopr = true; else if (strcmp(argv[arg_i], "-loopl") == 0) loopl = true; else fprintf(stderr,"%s is not a valid option. It will be ignored.\n", argv[arg_i]); } /* Check that there is either a left or right address (or both) */ if ( no_left && no_right || argc < 2){ printf("Piggy must have either a left or right side.\n"); exit(EXIT_FAILURE); } /* Map TCP transport protocol name to protocol number */ if ( ((long int)(ptrp = getprotobyname("tcp"))) == 0) { fprintf(stderr, "cannot map \"tcp\" to protocol number"); exit(EXIT_FAILURE); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Set up ncurses /************************************************************************************************************************************/ int i,j,a,b,c,d,nch; chtype ch; char response[132]; ch=(chtype) " "; ls=(chtype) 0; rs=(chtype) 0; ts=(chtype) 0; bs=(chtype) 0; tl=(chtype) 0; tr=(chtype) 0; bl=(chtype) 0; br=(chtype) 0; setlocale(LC_ALL,""); // this has to do with the character set to use initscr(); // must always call this (or newterm) to initialize the // library before any routines that deal with windows // or the screen can be called // set up some foreground / background color pairs cbreak(); // this allows use to get characters as they are typed // without the need for the userpressing the enter key noecho(); // this means the characters typed are not // shown on the screen unless we put them there nonl(); // this means don't translate a newline character // to a carraige return linefeed sequence on output intrflush(stdscr, FALSE); // keypad(stdscr, TRUE); // if (!(LINES==43) || !(COLS==132) ){ if (resizeterm(43,132)==ERR){ clear(); move(0,0); addstr("Piggy3 requires a screen size of 132 columns and 43 rows"); move(1,0); addstr("Set screen size to 132 by 43 and try again"); move(2,0); addstr("Press enter to terminate program"); refresh(); getstr(response); // Pause so we can see the screen endwin(); exit(EXIT_FAILURE); } } clear(); // make sure screen is clear before we start w[0]=newwin(0,0,0,0); touchwin(w[0]); wmove(w[0],0,0); wrefresh(w[0]); // Create the 5 windows a = 18; b=66; c=0; d=0; w[1]=subwin(w[0],a,b,c,d); w[2]=subwin(w[0],a,b,c,b); w[3]=subwin(w[0],a,b,a,c); w[4]=subwin(w[0],a,b,a,b); w[5]=subwin(w[0],7,132,36,c); for (i=1; i < MAXWIN - 1; i++){ ww[i]= b - 1; wh[i]= a - 1; } ww[5]= 131; wh[5]= 6; for (i=1;i < MAXWIN; i++){ wattron(w[i], A_STANDOUT); wborder(w[i],ls,rs,ts,bs,tl,tr,bl,br); wrefresh(w[i]); wattroff(w[i], A_STANDOUT); wrpos[i] = 1; wcpos[i] = 1; } wAddstr(IN_L,"Data arriving from the left:\n"); wAddstr(OUT_R,"Data leaving from left to right:\n"); wAddstr(OUT_L,"Data leaving from right to left:\n"); wAddstr(IN_R,"Data arriving from the right:\n"); wmove(w[IO],1,1);// start curser in IO window at top left wrefresh(w[0]); /*****************************************************************************************************************/ // create initial sockets /*****************************************************************************************************************/ /* Set up for left side of the connection */ /* Acts like a server so programs can connect to piggy */ int left_passive_sock = -1; /* socket descriptors */ /* If luseport is not set then use protoport value */ if (luseport == -1) luseport = PROTOPORT; if (!no_left){ if((left_passive_sock = create_server(luseport)) != -1){ FD_SET(left_passive_sock, &inputs); if (left_passive_sock > max_fd) max_fd = left_passive_sock;} else wAddstr(IO,"An error has occured creating the left connection. Piggy does not have a left side.\n"); } /* Right side of connection */ /* Acts like a client connection to a server */ int right_sock = -1; /* socket descriptor for left side*/ if (!no_right && raddr != NULL){ /* If rport was not set by the command line then use default PROTOPORT */ if (rport == -1) rport = PROTOPORT; if ((right_sock = create_client(raddr, rport)) != -1){ wAddstr(IO,"Piggy has a valid right connection.\n"); FD_SET(right_sock, &inputs); if (right_sock > max_fd) max_fd = right_sock;} else wAddstr(IO,"An error has occured creating the right connection. Piggy does not have a right side.\n"); } else if (!no_right && raddr == NULL){ wAddstr(IO,"Must specify -raddr or set -noright\n"); } /* Main server loop - accept and handle requests */ /* For left side */ int left_sock = -1; /* socket descriptor for accept socket */ char *lconnect_addr = NULL; char left_buf[1000]; /* buffer for string the server reads*/ int left_n = 0; /* number of characters read from input stream */ /* For right side */ int right_passive_sock = -1; /* socket descriptor for right side server */ int ruseport = PROTOPORT; int racctport = -1; char *racct_addr = NULL; char right_buf[1000]; /* buffer for string the server sends */ int right_n = 0; /* number of characters read to go to output stream*/ /* For keyboard input */ char stdin_buf[1000]; /* buffer for insert mode */ int stdin_n = 0; /* number of characters read in insert mode */ char *commands[3]; char command1[10]; char command2[20]; char command3[20]; commands[0] = command1; commands[1] = command2; commands[2] = command3; int command_lengths[3]; int command_i; int command_count; /* set output defaults */ bool outputr = true; bool outputl = false; if (no_right){ outputr = false; outputl = true; } fd_set inputs_loop = inputs; while (1) { wmove(w[IO],wrpos[IO],wcpos[IO]); inputs_loop = inputs; input_ready = select(max_fd+1,&inputs_loop,NULL,NULL,&timeout); /* accepts incoming client from left side and assigns to left_sock */ if (left_passive_sock != -1 && FD_ISSET(left_passive_sock,&inputs_loop)) if ((left_sock = Accept(left_passive_sock,lacct_addr,lacctport)) != -1) wAddstr(IO,"Piggy established a valid left connection.\n"); if (right_passive_sock != -1 && FD_ISSET(right_passive_sock,&inputs_loop)) if ((right_sock = Accept(right_passive_sock,racct_addr,racctport)) != -1) wAddstr(IO,"Piggy established a valid right connection.\n"); /* read input from stdin */ char cur_char; halfdelay(20); if ( (cur_char = wgetch(w[IO])) != ERR){ wrefresh(w[IO]); int cur_y,cur_x; getyx(w[IO],cur_y,cur_x); wrpos[IO]=cur_y; wcpos[IO]=cur_x; /* Process input commands */ /* Insert Mode */ if (cur_char == 'i'){ /* show that the user has entered insert mode */ mvwprintw(w[IO],wh[IO] -1,1,"-- INSERT --"); wrpos[IO]=cur_y; wcpos[IO]=cur_x; wmove(w[IO],wrpos[IO],wcpos[IO]); /* parse input */ while ((cur_char = wgetch(w[IO])) != 27){ if (cur_char == BACKSPACE){ // A backspace if (stdin_n != 0){ --stdin_n; mvwaddch(w[IO],wrpos[IO],wcpos[IO],' '); wmove(w[IO],wrpos[IO],wcpos[IO]); wcpos[IO]--; }} else if (cur_char == ENTER){ // An enter stdin_buf[stdin_n++] = '\n'; if (++wrpos[IO] == wh[IO] - 1) wrpos[IO] = 1; wcpos[IO] = 1; wmove(w[IO],wrpos[IO],wcpos[IO]);} else if ((cur_char >= 32) && (cur_char != 127)){ if (++wcpos[IO] == ww[IO]){ wcpos[IO]=1; if (++wrpos[IO]==wh[IO] -1) wrpos[IO]=1; } stdin_buf[stdin_n++] = cur_char; mvwaddch(w[IO],wrpos[IO],wcpos[IO],cur_char); } wrefresh(w[5]); } /* Clean up */ stdin_buf[stdin_n] = 0;// make it a proper string for (i = 1; i < wh[IO]; i++){ for (j = 1; j < ww[IO]; j++) mvwaddch(w[IO],i,j,' '); } wrpos[IO] = wcpos[IO] = 1; wmove(w[IO],wrpos[IO],wcpos[IO]); } /* Command Mode */ else if (cur_char == ':'){ mvwaddch(w[IO],wh[IO]-1, 1,':'); nocbreak(); echo(); /* Put command into commands[]*/ command_count = 0; for (i = 0; i < 3; i++) command_lengths[i] = 0; while ((cur_char = wgetch(w[IO])) != EOF && cur_char != '\n'){ if (cur_char == ' '){ commands[command_count][command_lengths[command_count]] = '\0'; // make command i proper if (++command_count > 2){ wAddstr(IO,"No valid commands have more than two args."); break; } command_lengths[command_count] = 0; } else commands[command_count][command_lengths[command_count]++] = cur_char; } if (command_lengths[command_count] > 0) commands[command_count][command_lengths[command_count]] = '\0'; cbreak(); noecho(); wrpos[IO] = wh[IO] -1; wcpos[IO] = 1; wClrtoeol(IO); wrpos[IO] = 1; wcpos[IO] =1; wmove(w[IO],wrpos[IO],wcpos[IO]); wrefresh(w[IO]); /* Check if valid command and process it*/ if (strncmp(commands[0],"q",command_lengths[0]) == 0){ /* Close the sockets. */ closesocket(left_sock); closesocket(right_sock); closesocket(left_passive_sock); closesocket(right_passive_sock); /* Put piggy out to paster */ endwin(); exit(0);} else if (strncmp(commands[0],"dropl",command_lengths[0]) == 0){ if (left_passive_sock != -1 || left_sock != -1){ Close(&left_sock); Close(&left_passive_sock); wAddstr(IO,"Dropped the left side connection.\n");} else wAddstr(IO,"No left side connection to drop.\n");} else if (strncmp(commands[0],"dropr",command_lengths[0]) == 0){ if (right_passive_sock != -1 || right_sock != -1){ Close(&right_passive_sock); Close(&right_sock); wAddstr(IO,"Dropped the right side connection.\n");} else wAddstr(IO,"No right side connection to drop.\n");} else if (strncmp(commands[0],"output",command_lengths[0]) == 0){ if (outputr) wAddstr(IO,"The current output direction for insert mode is to the right.\n"); else wAddstr(IO,"The current output direction for insert mode is to the left. \n");} else if (strncmp(commands[0],"outputl",command_lengths[0]) == 0){ outputr = false; outputl = true;} else if (strncmp(commands[0],"outputr",command_lengths[0]) == 0){ outputl = false; outputr = true;} else if (strncmp(commands[0], "lpair", command_lengths[0]) == 0) pair_info(left_passive_sock, left_sock, luseport); else if (strncmp(commands[0], "rpair", command_lengths[0]) == 0) pair_info(right_passive_sock, right_sock, ruseport); else if (strncmp(commands[0],"loopl",command_lengths[0]) == 0){ loopr = false; loopl = true;} else if (strncmp(commands[0],"loopr",command_lengths[0]) == 0){ loopl = false; loopr = true;} else if (strncmp(commands[0],"luseport",command_lengths[0]) == 0){ if (command_lengths[1] > 0) luseport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :luseport\n");} else if (strncmp(commands[0],"ruseport", command_lengths[0]) == 0){ if (command_lengths[1] > 0) ruseport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :ruseport\n");} else if (strncmp(commands[0],"lacctport",command_lengths[0]) == 0){ if (command_lengths[1] > 0) lacctport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :lacctport\n");} else if (strncmp(commands[0],"racctport", command_lengths[0]) == 0){ if (command_lengths[1] > 0) racctport = atoi(commands[1]); else wAddstr(IO,"Must specify valid port number after :racctport.\n");} else if (strncmp(commands[0],"laccptip", command_lengths[0]) == 0){ if (command_lengths[1] > 0) lacct_addr = commands[1]; else wAddstr(IO,"Must specify valid IP number after :lacctip\n");} else if (strncmp(commands[0],"racctip", command_lengths[0]) == 0){ if (command_lengths[1] > 0) racct_addr = commands[1]; else wAddstr(IO,"Must specify valid IP number after :racctip\n");} else if (strncmp(commands[0],"listenl", command_lengths[0]) == 0){ if (left_passive_sock != -1 || left_sock != -1) wAddstr(IO,"Already a left side. Use dropl and try agian\n"); else { /* If luseport is not set then use protoport value */ if (command_lengths[1] > 0) luseport = atoi(commands[1]); if((left_passive_sock = create_server(luseport)) != -1){ FD_SET(left_passive_sock, &inputs); if (left_passive_sock > max_fd) max_fd = left_passive_sock;} else wAddstr(IO,"An error has occured creating the left connection. Piggy does not have a left side.\n"); }} else if (strncmp(commands[0],"listenr",command_lengths[0]) == 0){ if (right_passive_sock != -1 || right_sock != -1) wAddstr(IO,"Already a right side. Use dropr and try agian.\n"); else { /* If port specified use it. else use protoport value */ if (command_lengths[1] > 0) ruseport = atoi(commands[1]); if((right_passive_sock = create_server(ruseport)) != -1){ FD_SET(right_passive_sock, &inputs); if (right_passive_sock > max_fd) max_fd = right_passive_sock;} else wAddstr(IO,"An error has occured creating the right connection. Piggy does not have a right side.\n"); }} else if (strncmp(commands[0],"connectl",command_lengths[0]) == 0){ if (left_passive_sock != -1 || left_sock != -1) wAddstr(IO,"Already a left side. Use dropl and try again.\n"); else { /* Get IP address */ if (command_lengths[1] > 0) lconnect_addr = commands[1]; else wAddstr(IO,"Must specify address or host name to connect to.\n"); /* Get port number */ if (command_lengths[2] > 0) luseport = atoi(commands[2]); else wAddstr(IO,"Must specify port number to connect to.\n"); /* Create socket */ if ((left_sock = create_client(lconnect_addr, luseport)) != -1){ wAddstr(IO,"Piggy has a valid left connection.\n"); FD_SET(right_sock, &inputs); if (left_sock > max_fd) max_fd = left_sock;} else wAddstr(IO,"An error has occured creating the left connection. Piggy does not have a left side.\n"); }} else if (strncmp(commands[0],"connectr",command_lengths[0]) == 0){ if (right_passive_sock != -1 || right_sock != -1) wAddstr(IO,"Already a right side. Use dropr and try again.\n"); else { /* Get IP address */ if (command_lengths[1] > 0) raddr = commands[1]; else wAddstr(IO,"Must specify address or host name to connect to.\n"); /* Get port number */ if (command_lengths[2] > 0) rport = atoi(commands[2]); else wAddstr(IO,"Must specify port number to connect to.\n"); /* Create socket */ if ((right_sock = create_client(raddr, rport)) != -1){ wAddstr(IO,"Piggy has a valid right connection.\n"); FD_SET(right_sock, &inputs); if (right_sock > max_fd) max_fd = right_sock;} else wAddstr(IO,"An error has occured creating the right connection. Piggy does not have a right side.\n"); }} else if ((strncmp(commands[0],"read",command_lengths[0])) == 0){ if (command_lengths[1] > 0){ int read_fd = open(commands[1],O_RDONLY); while ((stdin_n = read(read_fd,stdin_buf,sizeof(stdin_buf))) > 0){ if (outputr && right_sock != -1){ write(right_sock,stdin_buf,stdin_n); wAddnstr(OUT_R,stdin_buf,stdin_n);} else if (outputl && left_sock != -1){ write(left_sock, stdin_buf,stdin_n); wAddnstr(OUT_L,stdin_buf,stdin_n);} } if (stdin_n < 0) wAddstr(IO,"Error reading file\n"); if (stdin_n = 0) wAddstr(IO,"Seccessfully read whole file\n"); /*clean up */ close(read_fd); stdin_n = 0;} else wAddstr(IO,"Must specify name of file to read from\n"); } else wAddstr(IO,"Not a valid command.\n"); wrefresh(w[IO]); } } /* read from left side. */ if (FD_ISSET(left_sock,&inputs_loop)){ if ((left_n = read(left_sock,left_buf,sizeof(left_buf))) == 0){ wAddstr(IO,"Lost connection to left side. \n"); Close(&left_sock);} else // Display input from left to top left corner wAddnstr(IN_L,left_buf,left_n); } /* read from right side. */ if (FD_ISSET(right_sock, &inputs_loop)){ if ((right_n = read(right_sock, right_buf,sizeof(right_buf))) == 0){ wAddstr(IO,"Lost connection to right side. \n"); Close(&right_sock);} else // Display input from right to bottom right corner wAddnstr(IN_R,right_buf,right_n); } /* output contents of stdin_buf */ if (stdin_n != 0){ if (outputr && right_sock != -1){ write(right_sock,stdin_buf,stdin_n); wAddnstr(OUT_R,stdin_buf,stdin_n);} else if (outputl && left_sock != -1){ write(left_sock, stdin_buf,stdin_n); wAddnstr(OUT_L,stdin_buf,stdin_n);} else wAddstr(IO,"Unable to output string. Check your output and loop settings are correct and try again.\n"); stdin_n = 0; } /* Output contents of left and right buffer if data is present */ if (left_n != 0){ if (!loopr && right_sock != -1){ write(right_sock,left_buf,left_n); wAddnstr(OUT_R,left_buf,left_n);} else if (loopr && left_sock != -1){ write(left_sock,left_buf,left_n); wAddnstr(OUT_L,left_buf,left_n);} left_n = 0; } if (right_n != 0){ if (!loopl && left_sock != -1){ write(left_sock,right_buf,right_n); wAddnstr(OUT_L,right_buf,right_n);} else if (loopl && right_sock != -1){ write(right_sock,right_buf,right_n); wAddnstr(OUT_R,right_buf,right_n);} right_n = 0; } } }
int main(int argc, char *argv[]) { enum wavemon_screen cur, next; sigset_t blockmask, oldmask; getconf(argc, argv); if (!isatty(STDIN_FILENO)) errx(1, "input is not from a terminal"); /* honour numeric separators if the environment defines them */ setlocale(LC_NUMERIC, ""); /* initialize the ncurses interface */ initscr(); noecho(); nonl(); cbreak(); curs_set(0); clear(); check_geometry(); start_color(); init_pair(CP_STANDARD, COLOR_WHITE, COLOR_BLACK); init_pair(CP_SCALEHI, COLOR_RED, COLOR_BLACK); init_pair(CP_SCALEMID, COLOR_YELLOW, COLOR_BLACK); init_pair(CP_SCALELOW, COLOR_GREEN, COLOR_BLACK); init_pair(CP_WTITLE, COLOR_CYAN, COLOR_BLACK); init_pair(CP_INACTIVE, COLOR_CYAN, COLOR_BLACK); init_pair(CP_ACTIVE, COLOR_CYAN, COLOR_BLUE); init_pair(CP_STATSIG, COLOR_GREEN, COLOR_BLACK); init_pair(CP_STATNOISE, COLOR_RED, COLOR_BLACK); init_pair(CP_STATSNR, COLOR_BLUE, COLOR_BLUE); init_pair(CP_STATBKG, COLOR_BLUE, COLOR_BLACK); init_pair(CP_STATSIG_S, COLOR_GREEN, COLOR_BLUE); init_pair(CP_STATNOISE_S, COLOR_RED, COLOR_BLUE); init_pair(CP_PREF_NORMAL, COLOR_WHITE, COLOR_BLACK); init_pair(CP_PREF_SELECT, COLOR_WHITE, COLOR_BLUE); init_pair(CP_PREF_ARROW, COLOR_RED, COLOR_BLACK); init_pair(CP_SCAN_CRYPT, COLOR_RED, COLOR_BLACK); init_pair(CP_SCAN_UNENC, COLOR_GREEN, COLOR_BLACK); init_pair(CP_SCAN_NON_AP, COLOR_YELLOW, COLOR_BLACK); /* Override signal handlers installed during ncurses initialisation. */ xsignal(SIGCHLD, SIG_IGN); xsignal(SIGWINCH, sig_winch); /* triggers only when env_winch_ready */ sigemptyset(&blockmask); sigaddset(&blockmask, SIGWINCH); for (cur = conf.startup_scr; cur != SCR_QUIT; cur = next) { WINDOW *w_menu; int escape = 0; if (sigprocmask(SIG_BLOCK, &blockmask, &oldmask) < 0) err_sys("cannot block SIGWINCH"); next = cur; w_menu = init_menubar(cur); (*screens[cur].init)(); if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) err_sys("cannot unblock SIGWINCH"); if (sigsetjmp(env_winch, true) == 0) { env_winch_ready = true; do { int key = (*screens[cur].loop)(w_menu); if (key <= 0) usleep(5000); /* * Translate vt100 PF1..4 escape sequences sent * by some X terminals (e.g. aterm) into F1..F4. */ switch (key) { case 033: escape = 1; break; case 'O': escape = 2; break; case 'P' ... 'S': if (escape == 2) key = KEY_F(key - 'P' + 1); /* fall through */ default: escape = 0; } /* Main menu */ switch (key) { case 'i': case KEY_F(1): next = SCR_INFO; break; case 'l': case KEY_F(2): next = SCR_LHIST; break; case 's': case KEY_F(3): next = SCR_SCAN; break; case 'p': case KEY_F(7): next = SCR_PREFS; break; case 'h': case KEY_F(8): next = SCR_HELP; break; case 'a': case KEY_F(9): next = SCR_ABOUT; break; case 'q': case KEY_F(10): next = SCR_QUIT; } } while (next == cur); } delwin(w_menu); (*screens[cur].fini)(); /* * next = cur is set in the protected critical section before * sigsetjmp. Due to the loop condition, it can not occur when * no SIGWINCH occurred, hence it indicates a resizing event. */ if (next == cur) { struct winsize size; if (ioctl(STDIN_FILENO, TIOCGWINSZ, &size) < 0) err_sys("can not determine terminal size"); resizeterm(size.ws_row, size.ws_col); check_geometry(); } clear(); refresh(); }
void xyzsh_readline_interface_on_curses(char* cmdline, int cursor_point, char** argv, int argc, BOOL exit_in_spite_ofjob_exist, BOOL welcome_msg) { gSigChld = FALSE; gSigWinch = FALSE; signal(SIGCHLD, handler); signal(SIGWINCH, handler); const int maxx = mgetmaxx(); const int maxy = mgetmaxy(); int temulator_y = 0; int temulator_x = 0; int temulator_height = maxy; int temulator_width = maxx; sTEmulator* temulator = temulator_init(temulator_height, temulator_width); struct sTEmulatorFunArg arg; arg.cmdline = cmdline; arg.cursor_point = cursor_point; arg.argv = argv; arg.argc = argc; arg.exit_in_spite_ofjob_exist = exit_in_spite_ofjob_exist; arg.welcome_msg = welcome_msg; temulator_open(temulator, temulator_fun, &arg); initscr(); start_color(); noecho(); raw(); nodelay(stdscr, TRUE); keypad(stdscr, TRUE); curs_set(0); ESCDELAY=50; temulator_init_colors(); WINDOW* term_win = newwin(temulator_height, temulator_width, temulator_y, temulator_x); int pty = temulator->mFD; fd_set mask, read_ok; FD_ZERO(&mask); FD_SET(0, &mask); FD_SET(pty, &mask); int dirty = 0; struct timeval next; gettimeofday(&next, NULL); while(1) { struct timeval tv = { 0, 1000 * 1000 / 100 }; read_ok = mask; if(select(pty+1, &read_ok, NULL, NULL, &tv) > 0) { if(FD_ISSET(pty, &read_ok)) { temulator_read(temulator); dirty = 1; } } int key; while((key = getch()) != ERR) { temulator_write(temulator, key); dirty = 1; } gettimeofday(&tv, NULL); if(dirty && is_expired(tv, next)) { temulator_draw_on_curses(temulator, term_win, temulator_y, temulator_x); wrefresh(term_win); dirty = 0; next = timeval_add(tv, slice); } if(gSigChld) { gSigChld = FALSE; break; } if(gSigWinch) { gSigWinch = 0; temulator_height = mgetmaxy(); temulator_width = mgetmaxx(); if(temulator_width >= 10 && temulator_height >= 10) { resizeterm(temulator_height, temulator_width); wresize(term_win, temulator_height, temulator_width); temulator_resize(temulator, temulator_height, temulator_width); dirty = 1; } } } endwin(); temulator_final(temulator); }
void treatSigWinch(int signo) { struct winsize size; ioctl(fileno(stdout), TIOCGWINSZ, (char *) &size); resizeterm(size.ws_row, size.ws_col); }
int main(int argc, char *argv[]) { int optc; int option_differences = 0, option_differences_cumulative = 0, option_exec = 0, option_beep = 0, option_color = 0, option_errexit = 0, option_help = 0, option_version = 0; double interval = 2; char *command; wchar_t *wcommand = NULL; char **command_argv; int command_length = 0; /* not including final \0 */ int wcommand_columns = 0; /* not including final \0 */ int wcommand_characters = 0; /* not including final \0 */ watch_usec_t next_loop; /* next loop time in us, used for precise time keeping only */ int pipefd[2]; int status; pid_t child; setlocale(LC_ALL, ""); progname = argv[0]; while ((optc = getopt_long(argc, argv, "+bced::hn:pvtx", longopts, (int *) 0)) != EOF) { switch (optc) { case 'b': option_beep = 1; break; case 'c': option_color = 1; break; case 'd': option_differences = 1; if (optarg) option_differences_cumulative = 1; break; case 'e': option_errexit = 1; break; case 'h': option_help = 1; break; case 't': show_title = 0; break; case 'x': option_exec = 1; break; case 'n': { char *str; interval = strtod(optarg, &str); if (!*optarg || *str) do_usage(); if(interval < 0.1) interval = 0.1; if(interval > ~0u/1000000) interval = ~0u/1000000; } break; case 'p': precise_timekeeping = 1; break; case 'v': option_version = 1; break; default: do_usage(); break; } } if (option_version) { fprintf(stderr, "%s\n", VERSION); if (!option_help) exit(0); } if (option_help) { fprintf(stderr, usage, progname); fputs(" -b, --beep\t\t\t\tbeep if the command has a non-zero exit\n", stderr); fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr); fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr); fputs(" -e, --errexit\t\t\t\texit watch if the command has a non-zero exit\n", stderr); fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr); fputs(" -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr); fputs(" -p, --precise\t\t\t\tprecise timing, ignore command run time\n", stderr); fputs(" -v, --version\t\t\t\tprint the version number\n", stderr); fputs(" -t, --no-title\t\t\tturns off showing the header\n", stderr); fputs(" -x, --exec\t\t\t\tpass command to exec instead of sh\n", stderr); exit(0); } if (optind >= argc) do_usage(); command_argv=&(argv[optind]); /* save for later */ command = strdup(argv[optind++]); command_length = strlen(command); for (; optind < argc; optind++) { char *endp; int s = strlen(argv[optind]); command = realloc(command, command_length + s + 2); /* space and \0 */ endp = command + command_length; *endp = ' '; memcpy(endp + 1, argv[optind], s); command_length += 1 + s; /* space then string length */ command[command_length] = '\0'; } // convert to wide for printing purposes //mbstowcs(NULL, NULL, 0); wcommand_characters = mbstowcs(NULL, command, 0); if(wcommand_characters < 0) { fprintf(stderr, "Unicode Handling Error\n"); exit(1); } wcommand = (wchar_t*)malloc((wcommand_characters+1) * sizeof(wcommand)); if(wcommand == NULL) { fprintf(stderr, "Unicode Handling Error (malloc)\n"); exit(1); } mbstowcs(wcommand, command, wcommand_characters+1); wcommand_columns = wcswidth(wcommand, -1); get_terminal_size(); /* Catch keyboard interrupts so we can put tty back in a sane state. */ signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); signal(SIGWINCH, winch_handler); /* Set up tty for curses use. */ curses_started = 1; initscr(); if (option_color) { if (has_colors()) { start_color(); use_default_colors(); init_ansi_colors(); } else option_color = 0; } nonl(); noecho(); cbreak(); if (precise_timekeeping) next_loop = get_time_usec(); for (;;) { time_t t = time(NULL); char *ts = ctime(&t); int tsl = strlen(ts); char *header; FILE *p; int x, y; int oldeolseen = 1; if (screen_size_changed) { get_terminal_size(); resizeterm(height, width); clear(); /* redrawwin(stdscr); */ screen_size_changed = 0; first_screen = 1; } if (show_title) { // left justify interval and command, // right justify time, clipping all to fit window width int hlen = asprintf(&header, "Every %.1fs: ", interval); // the rules: // width < tsl : print nothing // width < tsl + hlen + 1: print ts // width = tsl + hlen + 1: print header, ts // width < tsl + hlen + 4: print header, ..., ts // width < tsl + hlen + wcommand_columns: print header, truncated wcommand, ..., ts // width > "": print header, wcomand, ts // this is slightly different from how it used to be if(width >= tsl) { if(width >= tsl + hlen + 1) { mvaddstr(0, 0, header); if(width >= tsl + hlen + 2) { if(width < tsl + hlen + 4) { mvaddstr(0, width - tsl - 4, "... "); }else{ if(width < tsl + hlen + wcommand_columns) { // print truncated int avail_columns = width - tsl - hlen; int using_columns = wcommand_columns; int using_characters = wcommand_characters; while(using_columns > avail_columns - 4) { using_characters--; using_columns = wcswidth(wcommand, using_characters); } mvaddnwstr(0, hlen, wcommand, using_characters); mvaddstr(0, width - tsl - 4, "... "); }else{ mvaddwstr(0, hlen, wcommand); } } } } mvaddstr(0, width - tsl + 1, ts); } free(header); } /* allocate pipes */ if (pipe(pipefd)<0) { perror("pipe"); do_exit(7); } /* flush stdout and stderr, since we're about to do fd stuff */ fflush(stdout); fflush(stderr); /* fork to prepare to run command */ child=fork(); if (child<0) { /* fork error */ perror("fork"); do_exit(2); } else if (child==0) { /* in child */ close (pipefd[0]); /* child doesn't need read side of pipe */ close (1); /* prepare to replace stdout with pipe */ if (dup2 (pipefd[1], 1)<0) { /* replace stdout with write side of pipe */ perror("dup2"); exit(3); } dup2(1, 2); /* stderr should default to stdout */ if (option_exec) { /* pass command to exec instead of system */ if (execvp(command_argv[0], command_argv)==-1) { perror("exec"); exit(4); } } else { status=system(command); /* watch manpage promises sh quoting */ /* propagate command exit status as child exit status */ if (!WIFEXITED(status)) { /* child exits nonzero if command does */ exit(1); } else { exit(WEXITSTATUS(status)); } } } /* otherwise, we're in parent */ close(pipefd[1]); /* close write side of pipe */ if ((p=fdopen(pipefd[0], "r"))==NULL) { perror("fdopen"); do_exit(5); } for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0; wint_t carry = WEOF; for (x = 0; x < width; x++) { wint_t c = L' '; int attr = 0; if (!eolseen) { /* if there is a tab pending, just spit spaces until the next stop instead of reading characters */ if (!tabpending) do { if(carry == WEOF) { c = my_getwc(p); }else{ c = carry; carry = WEOF; } }while (c != WEOF && !isprint(c) && c<128 && wcwidth(c) == 0 && c != L'\n' && c != L'\t' && (c != L'\033' || option_color != 1)); if (c == L'\033' && option_color == 1) { x--; process_ansi(p); continue; } if (c == L'\n') if (!oldeolseen && x == 0) { x = -1; continue; } else eolseen = 1; else if (c == L'\t') tabpending = 1; if (x==width-1 && wcwidth(c)==2) { y++; x = -1; //process this double-width carry = c; //character on the next line continue; //because it won't fit here } if (c == WEOF || c == L'\n' || c == L'\t') c = L' '; if (tabpending && (((x + 1) % 8) == 0)) tabpending = 0; } move(y, x); if (option_differences) { cchar_t oldc; in_wch(&oldc); attr = !first_screen && ((wchar_t)c != oldc.chars[0] || (option_differences_cumulative && (oldc.attr & A_ATTRIBUTES))); } if (attr) standout(); addnwstr((wchar_t*)&c,1); if (attr) standend(); if(wcwidth(c) == 0) { x--; } if(wcwidth(c) == 2) { x++; } } oldeolseen = eolseen; } fclose(p); /* harvest child process and get status, propagated from command */ if (waitpid(child, &status, 0)<0) { perror("waitpid"); do_exit(8); }; /* if child process exited in error, beep if option_beep is set */ if ((!WIFEXITED(status) || WEXITSTATUS(status))) { if (option_beep) beep(); if (option_errexit) do_exit(8); } first_screen = 0; refresh(); if (precise_timekeeping) { watch_usec_t cur_time = get_time_usec(); next_loop += USECS_PER_SEC*interval; if (cur_time < next_loop) usleep(next_loop - cur_time); } else usleep(interval * 1000000); } endwin(); return 0; }