void heartbeat(void) { time_t now = time(NULL); struct tm *ptm = localtime(&now); static int x = 0, y = 0, dx = 1, dy = 1; static NEWWIN *hb_win = NULL; x += dx; y += dy; if (x >= (max_x - 8)) { dx = -(myrand(1) + 1); x = max_x - (8 + 1); } else if (x < 0) { dx = (myrand(2) + 1); x = 0; } if (y >= max_y) { dy = -(myrand(2) + 1); y = max_y - 1; } else if (y < 0) { dy = (myrand(2) + 1); y = 0; } if (dx == 0 && dy == 0) { dy = 1; dy = -1; } if (!hb_win) { hb_win = create_popup(1, 8); } move_panel(hb_win -> pwin, y, x); ui_inverse_on(hb_win); mvwprintw(hb_win -> win, 0, 0, "%02d:%02d:%02d", ptm -> tm_hour, ptm -> tm_min, ptm -> tm_sec); ui_inverse_off(hb_win); mydoupdate(); }
void refresh_wc_window(void) { int wc_index = 0; werase(wc_window -> win); for(wc_index=wc_offset; wc_index<min(wc_offset + wc_window -> nlines, wc_list_n); wc_index++) { int y = wc_index - wc_offset; if (y == wc_cursor) mywattron(wc_window -> win, A_REVERSE); limit_print(wc_window, wc_window -> ncols, y, 0, "%s (%d)", wc_list[wc_index], wc_counts[wc_index]); if (y == wc_cursor) mywattroff(wc_window -> win, A_REVERSE); } mydoupdate(); }
int selection_box(void **list, char *needs_mark, int nlines, selbox_type_t type, int what_help, char *heading) { NEWWIN *mywin; int wlines = min(nlines, (max_y - 1) - 4); int total_win_size = wlines + 4; int win_width = max(32, max_x / 3); int wcols = win_width - 4; int pos = 0, ppos = -1, offs = 0, poffs = -1; int loop = 0, sel = -1; char first = 1; char *dummy = (char *)mymalloc(wcols + 1); int path_max = find_path_max(); char *selstr = (char *)mymalloc(path_max + 1), selfound = 0; selstr[0] = 0x00; mywin = create_popup(total_win_size, win_width); for(;;) { int c; /* draw list */ if (pos != ppos) { int entries_left = (nlines - pos); werase(mywin -> win); if (heading) win_header(mywin, heading); else if (type == SEL_WIN) win_header(mywin, "Select window"); else if (type == SEL_SUBWIN) win_header(mywin, "Select subwindow"); else if (type == SEL_FILES) win_header(mywin, "Select file"); else if (type == SEL_CSCHEME) win_header(mywin, "Select color scheme"); else if (type == SEL_HISTORY) win_header(mywin, "Select string from history"); for(loop=0; loop<min(entries_left, wlines); loop++) { char invert = generate_string(dummy, list, type, wcols, loop + pos); if (loop == offs) ui_inverse_on(mywin); if (invert) color_on(mywin, find_colorpair(COLOR_YELLOW, -1, 0)); if (needs_mark && needs_mark[loop + pos]) mvwprintw(mywin -> win, loop + 2, 1, "*"); mvwprintw(mywin -> win, loop + 2, 2, "%s", dummy); if (invert) color_off(mywin, find_colorpair(COLOR_YELLOW, -1, 0)); if (loop == offs) ui_inverse_off(mywin); } draw_border(mywin); ppos = pos; poffs = offs; } else if (poffs != offs) { int yellow_cp = find_colorpair(COLOR_YELLOW, -1, 0); char invert = generate_string(dummy, list, type, wcols, poffs + pos); if (invert) color_on(mywin, yellow_cp); mvwprintw(mywin -> win, poffs + 2, 2, "%s", dummy); if (invert) color_off(mywin, yellow_cp); invert = generate_string(dummy, list, type, wcols, offs + pos); ui_inverse_on(mywin); if (invert) color_on(mywin, yellow_cp); if (needs_mark && needs_mark[offs + pos]) mvwprintw(mywin -> win, loop + 2, 1, "*"); mvwprintw(mywin -> win, offs + 2, 2, "%s", dummy); if (invert) color_off(mywin, yellow_cp); ui_inverse_off(mywin); poffs = offs; } if (first) { first = 0; color_on(mywin, find_colorpair(COLOR_GREEN, -1, 0)); mvwprintw(mywin -> win, total_win_size - 2, 2, "Press ^G to abort"); color_off(mywin, find_colorpair(COLOR_GREEN, -1, 0)); } else { int loop, len = strlen(selstr); for(loop=0; loop<wcols; loop++) mvwprintw(mywin -> win, total_win_size - 2, 1 + loop, " "); if (!selfound) color_on(mywin, find_colorpair(COLOR_RED, -1, 0)); mvwprintw(mywin -> win, total_win_size - 2, 1, "%s", &selstr[max(0, len - wcols)]); if (!selfound) color_off(mywin, find_colorpair(COLOR_RED, -1, 0)); } mydoupdate(); c = wait_for_keypress(what_help, 0, mywin, 1); if (c == KEY_UP) { if ((offs + pos) > 0) { if (offs) offs--; else pos--; } else { wrong_key(); } } else if (c == KEY_DOWN) { if ((pos + offs) < (nlines-1)) { if (offs < (wlines-1)) offs++; else pos++; } else { wrong_key(); } } else if (c == KEY_NPAGE) { if ((pos + offs) < (nlines - 1)) { pos += min(wlines, (nlines - 1) - (pos + offs)); } else { wrong_key(); } } else if (c == KEY_PPAGE) { if ((pos + offs - wlines) >= 0) { if (pos > wlines) { pos -= wlines; } else { pos -= (wlines - offs); offs = 0; } } else if (offs > 0) { offs = 0; } else if (pos > 0) { pos = 0; } else { wrong_key(); } } else if (c == KEY_ENTER || c == 13 || c == 10) { sel = pos + offs; break; } else if (c == abort_key || c == -1) { break; } else if ((c > 31 && c != 127) || (c == KEY_BACKSPACE)) { int index, curlen; curlen = strlen(selstr); if (c == KEY_BACKSPACE) { if (curlen > 0) selstr[curlen - 1] = 0x00; else wrong_key(); } else if (curlen < path_max) { selstr[curlen] = c; selstr[curlen + 1] = 0x00; } else wrong_key(); curlen = strlen(selstr); if (curlen > 0) { index = find_sb_string(list, type, nlines, selstr); if (index != -1) { ppos = -1; sel = pos = index; selfound = 1; } else { selfound = 0; } } } else { wrong_key(); } } delete_popup(mywin); myfree(dummy); myfree(selstr); return sel; }
void statistics_menu(void) { NEWWIN *mywin = create_popup(23, 65); int offset = 0, cur_line = 0; for(;;) { int c; int vmsize = get_vmsize(getpid()); time_t now = time(NULL); struct tm *tmnow = localtime(&now); proginfo **plist = NULL; char *issub = NULL; int *winnr = NULL; int loop, nwin = 0; /* create list of (sub-)windows */ for(loop=0; loop<nfd; loop++) { proginfo *cur = &pi[loop]; while(cur) { plist = (proginfo **)myrealloc(plist, (nwin + 1) * sizeof(proginfo *)); issub = (char *) myrealloc(issub, (nwin + 1) * sizeof(char) ); winnr = (int *) myrealloc(winnr, (nwin + 1) * sizeof(int) ); plist[nwin] = cur; issub[nwin] = (cur != &pi[loop]); winnr[nwin] = loop; nwin++; cur = cur -> next; } } werase(mywin -> win); win_header(mywin, "Statistics"); for(loop=0; loop<18; loop++) { int cur_index = loop + offset; int is_sub_indent; if (cur_index >= nwin) break; is_sub_indent = issub[cur_index]; if (loop == cur_line) ui_inverse_on(mywin); if (is_sub_indent) mvwprintw(mywin -> win, 2 + loop, 7, "%s", shorten_filename(plist[cur_index] -> filename, 54)); else mvwprintw(mywin -> win, 2 + loop, 2, "[%02d] %s", winnr[cur_index], shorten_filename(plist[cur_index] -> filename, 56)); if (loop == cur_line) ui_inverse_off(mywin); } mvwprintw(mywin -> win, 20, 2, "Run-time: %.2f hours %02d:%02d", (get_ts() - mt_started) / 3600.0, tmnow -> tm_hour, tmnow -> tm_min); if (vmsize != -1) { char *vmsize_str = amount_to_str(vmsize); mvwprintw(mywin -> win, 20, 35, "Memory usage: %s", vmsize_str); myfree(vmsize_str); } escape_print(mywin, 21, 2, "Press ^r^ to reset counters, ^q^ to exit"); draw_border(mywin); mydoupdate(); c = toupper(wait_for_keypress(HELP_STATISTICS, popup_refresh_interval, mywin, 1)); if (c == 'R') { for(loop=0; loop<nfd; loop++) { proginfo *cur = &pi[loop]; while(cur) { reset_counters(&cur -> statistics); cur = cur -> next; } } } else if (c == KEY_UP) { if (cur_line) cur_line--; else if (offset) offset--; else wrong_key(); } else if (c == KEY_DOWN) { if ((cur_line + offset) < (nwin - 1)) { if (cur_line < (18 - 1)) cur_line++; else offset++; } else wrong_key(); } else if (c == 13 || c == ' ') { statistics_popup(winnr[cur_line + offset], plist[cur_line + offset]); } else if (c == 'Q' || c == abort_key) { myfree(plist); myfree(issub); myfree(winnr); break; } else if (c != -1) { wrong_key(); } myfree(plist); myfree(issub); myfree(winnr); } delete_popup(mywin); }
void info(void) { NEWWIN *mywin = create_popup(19, 60); int line = 7; struct utsname uinfo; int proc_u_line; char *term = getenv("TERM"); mvwprintw(mywin -> win, 1, 2, "-=* MultiTail " VERSION " *=-"); mvwprintw(mywin -> win, 3, 2, "Written by [email protected]"); mvwprintw(mywin -> win, 4, 2, "Website: http://www.vanheusden.com/multitail/"); if (!use_colors) mvwprintw(mywin -> win, line++, 2, "Your terminal doesn't support colors"); if (uname(&uinfo) == -1) error_popup("Retrieving system information", -1, "uname() failed\n"); else { line++; mvwprintw(mywin -> win, line++, 2, "Running on:"); #ifdef _GNU_SOURCE mvwprintw(mywin -> win, line++, 2, "%s/%s %s %s", uinfo.nodename, uinfo.sysname, uinfo.machine, uinfo.domainname); #else mvwprintw(mywin -> win, line++, 2, "%s/%s %s", uinfo.nodename, uinfo.sysname, uinfo.machine); #endif mvwprintw(mywin -> win, line++, 2, "%s %s", uinfo.release, uinfo.version); line++; } if (has_colors()) mvwprintw(mywin -> win, line++, 2, "colors: %d, colorpairs: %d (%d), change colors: %s", COLORS, COLOR_PAIRS, cp.n_def, can_change_color()?"yes":"no"); else mvwprintw(mywin -> win, line++, 2, "Terminal does not support colors."); if (term) mvwprintw(mywin -> win, line++, 2, "Terminal size: %dx%d, terminal: %s", max_x, max_y, term); else mvwprintw(mywin -> win, line++, 2, "Terminal size: %dx%d", max_x, max_y); if (beep_interval > 0) mvwprintw(mywin -> win, line++, 2, "Did %d beeps.", did_n_beeps); proc_u_line = line++; escape_print(mywin, 16, 2, "_Press any key to exit this screen_"); #if defined(__FreeBSD__) || defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined(sun) || defined(__sun) || defined(__GNU__) || defined(__CYGWIN__) for(;;) { dtime_t run_time = get_ts() - mt_started; #ifndef __CYGWIN__ double v1, v2, v3; get_load_values(&v1, &v2, &v3); mvwprintw(mywin -> win, 6, 2, "Current load of system: %f %f %f", v1, v2, v3); #endif if (run_time) { struct rusage usage; if (getrusage(RUSAGE_SELF, &usage) == -1) error_exit(TRUE, FALSE, "getrusage() failed\n"); mvwprintw(mywin -> win, proc_u_line, 2, "Runtime: %02d:%02d:%02d, avg.proc.usage: %.2f%% ints/s: %.1f", (int)(run_time / 3600), ((int)run_time / 60) % 60, (int)run_time % 60, ((double)usage.ru_utime.tv_sec + (double)usage.ru_utime.tv_usec / 1000000.0 + (double)usage.ru_stime.tv_sec + (double)usage.ru_stime.tv_usec / 1000000.0) * 100.0 / run_time, (double)total_wakeups / run_time); } mydoupdate(); if (wait_for_keypress(-1, popup_refresh_interval, mywin, 0) != -1) break; } #else mydoupdate(); wait_for_keypress(-1, 0, mywin, 0); #endif delete_popup(mywin); }
void statistics_popup(int f_index, proginfo *cur) { NEWWIN *popup = create_popup(16, 68); const char *title = "Statistics for "; char *abbr_fname = shorten_filename(cur -> filename, 54 - strlen(title)); char buffer[54 + 1]; snprintf(buffer, sizeof(buffer), "%s%s", title, abbr_fname); for(;;) { dtime_t time_running = get_ts() - cur -> statistics.start_ts; time_t start_ts = (time_t)cur -> statistics.start_ts; char *start_ts_str = mystrdup(ctime(&start_ts)); time_t lastevent = (time_t)cur -> statistics.lastevent; char *last_ts_str = mystrdup(ctime(&lastevent)); char *dummy; char *vmsize_str = NULL; char *fsize_str = NULL; char *total_data_processed_str = amount_to_str(cur -> statistics.bytes_processed); char *buffer_kb; off64_t fsize = -1; int c; int total_re = 0; int loop; if (cur -> wt == WT_COMMAND) { vmsize_str = amount_to_str(get_vmsize(cur -> pid)); } else if (cur -> wt == WT_FILE) { (void)file_info(cur -> filename, &fsize, 0, NULL, NULL); fsize_str = amount_to_str(fsize); } dummy = strchr(start_ts_str, '\n'); if (dummy) *dummy = 0x00; dummy = strchr(last_ts_str, '\n'); if (dummy) *dummy = 0x00; werase(popup -> win); win_header(popup, buffer); ui_inverse_on(popup); mvwprintw(popup -> win, 3, 2, "# lines :"); mvwprintw(popup -> win, 3, 27, "#l/s :"); mvwprintw(popup -> win, 3, 44, "Avg len:"); mvwprintw(popup -> win, 4, 2, "Data interval :"); if (cur -> wt == WT_COMMAND) mvwprintw(popup -> win, 5, 2, "VM size :"); else if (cur -> wt == WT_FILE) mvwprintw(popup -> win, 5, 2, "File size :"); mvwprintw(popup -> win, 9, 2, "Data processed:"); mvwprintw(popup -> win, 9, 27, "Bps :"); mvwprintw(popup -> win, 6, 2, "Started at :"); mvwprintw(popup -> win, 7, 2, "Last event :"); mvwprintw(popup -> win, 8, 2, "Next expected@:"); mvwprintw(popup -> win, 10, 2, "# matched r.e.:"); mvwprintw(popup -> win, 11, 2, "Buffered lines:"); mvwprintw(popup -> win, 11, 27, "Bytes:"); mvwprintw(popup -> win, 11, 44, "Limit :"); mvwprintw(popup -> win, 12, 2, "# of beeps: "); if (cur -> wt == WT_COMMAND) { mvwprintw(popup -> win, 13, 2, "Number of runs:"); mvwprintw(popup -> win, 13, 27, "Last rc:"); } ui_inverse_off(popup); mvwprintw(popup -> win, 3, 18, "%d", cur -> statistics.n_events); mvwprintw(popup -> win, 6, 18, "%s", start_ts_str); if (cur -> statistics.lastevent != (dtime_t)0.0) mvwprintw(popup -> win, 7, 18, "%s", last_ts_str); else mvwprintw(popup -> win, 7, 18, "---"); if (cur -> statistics.n_events == 0) { mvwprintw(popup -> win, 4, 18, "Not yet available"); } else { double avg = cur -> statistics.med / (double)cur -> statistics.n_events; double dev = sqrt((cur -> statistics.dev / (double)cur -> statistics.n_events) - pow(avg, 2.0)); /* serial correlation coefficient */ double scct1 = cur -> statistics.scct1 + cur -> statistics.scclast * cur -> statistics.sccu0; double med = cur -> statistics.med * cur -> statistics.med; double scc = (double)cur -> statistics.n_events * cur -> statistics.dev - med; if (scc != 0.0) { scc = ((double)cur -> statistics.n_events * scct1 - med) / scc; mvwprintw(popup -> win, 4, 18, "average: %.2f, std.dev.: %.2f, SCC: %1.6f", avg, dev, scc); } else mvwprintw(popup -> win, 4, 18, "average: %.2f, std.dev.: %.2f, not correlated", avg, dev); if (avg) { double dummy_d = (double)(time(NULL) - cur -> statistics.lastevent) / avg; time_t next_event = cur -> statistics.lastevent + (ceil(dummy_d) * avg); char *ne_str = mystrdup(ctime(&next_event)); char *dummy_str = strchr(ne_str, '\n'); if (dummy_str) *dummy_str = 0x00; mvwprintw(popup -> win, 8, 18, "%s", ne_str); myfree(ne_str); } mvwprintw(popup -> win, 3, 53, "%.1f", (double)cur -> statistics.bytes_processed / (double)cur -> statistics.n_events); } if (cur -> wt == WT_COMMAND) mvwprintw(popup -> win, 5, 18, "%s", vmsize_str); else if (cur -> wt == WT_STDIN || cur -> wt == WT_SOCKET) mvwprintw(popup -> win, 5, 18, "n.a."); else if (cur -> wt == WT_FILE) mvwprintw(popup -> win, 5, 18, "%s", fsize_str); myfree(vmsize_str); myfree(fsize_str); mvwprintw(popup -> win, 9, 18, "%s", total_data_processed_str); myfree(total_data_processed_str); if (time_running > 0) { char *bps_str = amount_to_str((double)cur -> statistics.bytes_processed / (double)time_running); mvwprintw(popup -> win, 9, 34, "%s", bps_str); myfree(bps_str); mvwprintw(popup -> win, 3, 34, "%.4f", (double)cur -> statistics.n_events / (double)time_running); } buffer_kb = amount_to_str(lb[f_index].curbytes); mvwprintw(popup -> win, 11, 18, "%d", lb[f_index].curpos); mvwprintw(popup -> win, 11, 34, "%s", buffer_kb); myfree(buffer_kb); mvwprintw(popup -> win, 12, 18, "%d", cur -> beep.did_n_beeps); escape_print(popup, 14, 2, "Press ^r^ to reset counters, ^q^ to exit"); myfree(start_ts_str); myfree(last_ts_str); for(loop=0; loop<cur -> n_re; loop++) total_re += (cur -> pre)[loop].match_count; if (cur -> statistics.n_events) mvwprintw(popup -> win, 10, 18, "%d (%.2f%%)", total_re, (total_re * 100.0) / (double)cur -> statistics.n_events); else mvwprintw(popup -> win, 10, 18, "%d", total_re); if (cur -> wt == WT_COMMAND) { mvwprintw(popup -> win, 13, 18, "%d", cur -> n_runs); mvwprintw(popup -> win, 13, 36, "%d", cur -> last_exit_rc); } if (lb[f_index].maxnlines > 0) { mvwprintw(popup -> win, 11, 53, "%d lines", lb[f_index].maxnlines); } else if (lb[f_index].maxbytes > 0) { char *str = amount_to_str(lb[f_index].maxbytes); mvwprintw(popup -> win, 11, 53, "%s", str); myfree(str); } draw_border(popup); mydoupdate(); c = toupper(wait_for_keypress(HELP_STATISTICS_POPUP, popup_refresh_interval, popup, 0)); if (c == 'Q' || c == abort_key) { break; } else if (c == 'R') { reset_counters(&cur -> statistics); } else if (c != -1) { wrong_key(); } } delete_popup(popup); }
int scrollback_do(int window_nr, buffer *pbuf, int *winnrs, char *header) { int rc = 0; char *find = NULL; char fullscreen = scrollback_fullscreen_default; NEWWIN *mywin1 = NULL, *mywin2 = NULL; int nlines, ncols; compute_text_dimensions(&nlines, &ncols, fullscreen); int offset = max(0, pbuf -> curpos - nlines); /* FIXME: aantal regels laten afhangen van lengte */ char redraw = 2; int line_offset = 0; char show_winnr = default_sb_showwinnr; mybool_t case_insensitive = re_case_insensitive; buffer cur_lb; int loop = 0; memset(&cur_lb, 0x00, sizeof(cur_lb)); for(loop=0; loop<pbuf -> curpos; loop++) { if ((pbuf -> be)[loop].Bline == NULL) continue; cur_lb.be = myrealloc(cur_lb.be, (cur_lb.curpos + 1) * sizeof(buffered_entry)); cur_lb.be[cur_lb.curpos].pi = (pbuf -> be)[loop].pi; if ((pbuf -> be)[loop].pi != NULL && (!IS_MARKERLINE((pbuf -> be)[loop].pi)) && (pbuf -> be)[loop].pi -> cdef.term_emul != TERM_IGNORE) { color_offset_in_line *cmatches; int n_cmatches; cur_lb.be[cur_lb.curpos].Bline = emulate_terminal((pbuf -> be)[loop].Bline, &cmatches, &n_cmatches); myfree(cmatches); } else cur_lb.be[cur_lb.curpos].Bline = strdup((pbuf -> be)[loop].Bline); cur_lb.be[cur_lb.curpos].ts = (pbuf -> be)[loop].ts; cur_lb.curpos++; } LOG("---\n"); if (global_highlight_str) { find = mystrdup(global_highlight_str); } create_scrollback_windows(&mywin1, &mywin2, nlines, ncols, fullscreen); for(;;) { int c, uc; if (redraw == 2) { int index = 0; int lines_used = 0; if (mywin1) { ui_inverse_on(mywin1); mvwprintw(mywin1 -> win, nlines + 1, 1, "%s - %d buffered lines", shorten_filename(header, max(24, ncols - 24)), cur_lb.curpos); ui_inverse_off(mywin1); if (!no_linewrap) ui_inverse_on(mywin1); mvwprintw(mywin1 -> win, nlines + 1, ncols - 8, "LINEWRAP"); if (!no_linewrap) ui_inverse_off(mywin1); } werase(mywin2 -> win); if (!no_linewrap && line_offset > 0) { int temp_line_offset = line_offset; int n_chars_to_display_left = strlen((cur_lb.be)[offset].Bline) - temp_line_offset; while(lines_used < nlines && n_chars_to_display_left > 0) { scrollback_displayline(winnrs?winnrs[offset]:window_nr, mywin2, &cur_lb, offset, lines_used, temp_line_offset, 1, show_winnr); temp_line_offset += ncols; n_chars_to_display_left -= ncols; lines_used++; } index++; } for(;(offset + index) < cur_lb.curpos && lines_used < nlines;) { int lines_needed = get_lines_needed((cur_lb.be)[offset + index].Bline, ncols); if (no_linewrap || lines_needed == 1) { scrollback_displayline(winnrs?winnrs[offset + index]:window_nr, mywin2, &cur_lb, offset + index, lines_used, no_linewrap?line_offset:0, no_linewrap, show_winnr); lines_used++; } else { int cur_line_offset = 0; while(lines_used < nlines && lines_needed > 0) { scrollback_displayline(winnrs?winnrs[offset + index]:window_nr, mywin2, &cur_lb, offset + index, lines_used, cur_line_offset, 1, show_winnr); cur_line_offset += ncols; lines_used++; lines_needed--; } } index++; } redraw = 1; } if (redraw == 1) { mydoupdate(); redraw = 0; } c = wait_for_keypress(HELP_SCROLLBACK_HELP, 0, NULL, 1); uc = toupper(c); if (c == 'q' || c == abort_key || c == KEY_CLOSE || c == KEY_EXIT) { break; } else if (c == 'Q' || c == -1) /* Q: close whole stack of scrollbackwindows, -1: something got closed */ { rc = -1; break; } else if (c == 20 && winnrs != NULL) /* ^t */ { show_winnr = 1 - show_winnr; redraw = 2; } else if (c == 'x') { send_to_clipboard(pbuf); } else if (c == 'Y') { no_linewrap = !no_linewrap; redraw = 2; line_offset = 0; } else if (c == KEY_F(9) || c == 23) /* ^w */ { fullscreen = ! fullscreen; compute_text_dimensions(&nlines, &ncols, fullscreen); create_scrollback_windows(&mywin1, &mywin2, nlines, ncols, fullscreen); redraw = 2; } else if (c == 't') { statistics_menu(); } else if ((c == KEY_LEFT || c == KEY_BACKSPACE) && no_linewrap) { if (line_offset > 0) line_offset--; redraw = 2; } else if (c == KEY_SLEFT && no_linewrap) { if (line_offset >= (ncols / 2)) line_offset -= (ncols / 2); else line_offset = 0; redraw = 2; } else if (c == KEY_SRIGHT && no_linewrap) { line_offset += (ncols / 2); redraw = 2; } else if (c == KEY_BEG && no_linewrap) { if (line_offset) { line_offset = 0; redraw = 2; } } else if (c == KEY_BTAB) { if (line_offset >= 4) line_offset -= 4; else line_offset = 0; redraw = 2; } else if (c == KEY_RIGHT && no_linewrap) { line_offset++; redraw = 2; } else if ((c == KEY_UP || c == 'y' || c == 25 || /* ^y */ c == 'k' || /* c == 11 || */ /* ^k */ c == 16) /* ^p */ && (offset > 0 || (!no_linewrap && line_offset > 0))) { if (no_linewrap) { offset--; } else if (line_offset > 0) { line_offset = max(0, line_offset - ncols); } else { offset--; line_offset = (get_lines_needed((cur_lb.be)[offset].Bline, ncols) - 1) * ncols; } wmove(mywin2 -> win, 0, 0); winsdelln(mywin2 -> win, 1); scrollback_displayline(winnrs?winnrs[offset]:window_nr, mywin2, &cur_lb, offset, 0, line_offset, no_linewrap, show_winnr); redraw = 1; } else if ((c == KEY_DOWN || c == 'e' || c == 5 || /* ^e */ c == 'j' || c == 14 || /* ^n */ c == 13 || c == KEY_ENTER) && offset < (cur_lb.curpos - 1)) { if (no_linewrap) { offset++; } else if (strlen((cur_lb.be)[offset].Bline) > (line_offset + ncols)) { line_offset += ncols; } else if (offset < (cur_lb.curpos - 1)) { if (strlen((cur_lb.be)[offset].Bline) > (line_offset + ncols)) line_offset += ncols; else { line_offset = 0; offset++; } } redraw = 2; } else if ((c == KEY_NPAGE || c == 'f' || c == 6 || /* ^f */ c == ('V' - 65 + 1) || /* ^v */ c == ' ' || c == 'z' || c == 'u' || c == ('U' - 65 + 1)) /* ^u */ && offset < (cur_lb.curpos - 1)) { if (no_linewrap) { offset += nlines; if (offset >= cur_lb.curpos) offset = cur_lb.curpos - 1; } else { int n_lines_to_move = nlines; while(n_lines_to_move > 0 && offset < (cur_lb.curpos)) { if (line_offset > 0) { if (line_offset + ncols >= strlen((cur_lb.be)[offset].Bline)) { line_offset = 0; offset++; n_lines_to_move--; } else { line_offset += ncols; n_lines_to_move--; } } else { n_lines_to_move -= get_lines_needed((cur_lb.be)[offset].Bline, ncols); offset++; } } if (n_lines_to_move < 0) line_offset = (-n_lines_to_move) * ncols; } redraw = 2; } else if ((c == KEY_PPAGE || c == 'b' || c == 2 || /* ^b */ c == 'w' || c == 'd' || c == 4) /* ^d */ && offset > 0) { if (no_linewrap) { offset -= nlines; if (offset < 0) offset = 0; } else { int n_lines_to_move = nlines; if (line_offset) n_lines_to_move -= line_offset / ncols; while(n_lines_to_move > 0 && offset > 0) { offset--; n_lines_to_move -= get_lines_needed((cur_lb.be)[offset].Bline, ncols); if (n_lines_to_move < 0) { line_offset = (get_lines_needed((cur_lb.be)[offset].Bline, ncols) + n_lines_to_move) * ncols; } } } redraw = 2; } else if ((c == KEY_HOME || c == 'g' || c == '<' || c == KEY_SBEG) && offset > 0) { line_offset = offset = 0; redraw = 2; } else if ((c == KEY_END || c == 'G' || c == '>' || c == KEY_SEND) && offset < (cur_lb. curpos - 1)) { offset = cur_lb. curpos - 1; redraw = 2; } else if (uc == 'R' || c == ('R' - 65 + 1) || c == ('L' - 65 + 1) || c == KEY_REFRESH) { redraw = 2; } else if (c == ('K' - 65 + 1) || c == KEY_MARK) { scrollback_find_popup(&find, &case_insensitive); if (find) { int rc; regfree(&global_highlight_re); myfree(global_highlight_str); global_highlight_str = NULL; if ((rc = regcomp(&global_highlight_re, find, (case_insensitive == MY_TRUE?REG_ICASE:0) | REG_EXTENDED))) { regexp_error_popup(rc, &global_highlight_re); myfree(find); } else { global_highlight_str = find; } redraw = 2; /* force redraw */ } } else if (c == 'f' || c == '/' || c == '?' || c == KEY_FIND || c == KEY_SFIND) { char direction = (c == '?' || c == KEY_SFIND) ? -1 : 1; scrollback_find_popup(&find, &case_insensitive); if (find) { if (scrollback_search_new_window) { if (scrollback_search_to_new_window(&cur_lb, header, find, case_insensitive) == -1) { /* cascaded close */ rc = -1; break; } } else { int new_f_index; redraw = 2; /* force redraw */ regfree(&global_highlight_re); myfree(global_highlight_str); global_highlight_str = NULL; new_f_index = find_string(&cur_lb, find, 0, direction, case_insensitive); if (new_f_index == -1) { wrong_key(); } else { offset = new_f_index; line_offset = 0; } } } } else if (uc == 'N' || c == KEY_NEXT || c == KEY_PREVIOUS || c == KEY_SNEXT) { if (find != NULL) { char direction = (c == 'n' || c == KEY_NEXT) ? 1 : -1; int start_offset = offset + direction; int new_f_index = find_string(&cur_lb, find, start_offset, direction, case_insensitive); if (new_f_index == -1) { wrong_key(); } else { redraw = 2; /* force redraw */ offset = new_f_index; line_offset = 0; } } else { wrong_key(); } } else if (c == 's' || c == KEY_SAVE) { scrollback_savefile(&cur_lb); redraw = 2; /* force redraw */ } else if (c == 'h') { show_help(HELP_SCROLLBACK_HELP); } else if (c == 'c') { toggle_colors(); redraw = 2; /* force redraw */ } else if (c == 'i') { info(); } else if (c == 'T') { statistics_menu(); } else if (c == 20) { toggle_subwindow_nr(); redraw = 2; /* force redraw */ } else { wrong_key(); } } delete_popup(mywin2); if (mywin1) delete_popup(mywin1); myfree(find); delete_be_in_buffer(&cur_lb); return rc; }