JSBool Window_redraw (JSContext* cx, JSObject* object, uintN argc, jsval* argv, jsval* rval) { if (argc != 2 && argc != 0) { JS_ReportError(cx, "Not enough parameters."); return JS_FALSE; } WINDOW* win = ((WindowInformation*)JS_GetPrivate(cx, object))->win; JS_BeginRequest(cx); JS_EnterLocalRootScope(cx); switch (argc) { case 0: { wrefresh(win); } break; case 2: { jsint beg; JS_ValueToInt32(cx, argv[0], &beg); jsint num; JS_ValueToInt32(cx, argv[1], &num); wredrawln(win, beg, num); } break; } JS_LeaveLocalRootScope(cx); JS_EndRequest(cx); return JS_TRUE; }
static void print_mode(void) { const char *cp = cisco_netflow_dump; char src_buf[100], dst_buf[100], proto_buf[20]; /* sanity check */ if (!dump_match) return; hdr2str(&dump_match->ns_hdr, src_buf, sizeof(src_buf), dst_buf, sizeof(dst_buf), proto_buf, sizeof(proto_buf)); if (!cisco_netflow_dump) { switch (show_stat_mode) { case Size: cp = "HexData"; break; case Data: cp = "AsciiData"; break; case Packets: cp = "Packets"; break; } } attrset(A_STANDOUT); printw("\n--- %s %s > %s %s flow ---", proto_buf, src_buf, dst_buf, cp); attrset(A_NORMAL); #ifdef HAVE_WREDRAWLN wredrawln(stdscr, 0, LINES); #endif refresh(); }
void guiPrintOpt(int opt) { /* 0 10 20 30 40 50 60 -[-]?[0-9]*.[0-9]+--pgup,pgdn---^v---<>---enter---backspace-- */ if(opt & GUI_OPT_UP_DOWN) mvwprintw(dataWinBox, 21,32, "^v"); if(opt & GUI_OPT_PG_UP_DOWN) mvwprintw(dataWinBox, 21,20, "pgup,pgdn"); if(opt & GUI_OPT_LEFT_RIGHT) mvwprintw(dataWinBox, 21,37, "<>"); if(opt & GUI_OPT_ENTER) mvwprintw(dataWinBox, 21,42, "enter"); if(opt & GUI_OPT_BACKSPACE) mvwprintw(dataWinBox, 21,50, "backspace"); if(opt & GUI_OPT_INT) mvwprintw(dataWinBox, 21,1, "[-]?[0-9]+"); else if(opt & GUI_OPT_UINT) mvwprintw(dataWinBox, 21,1, "[0-9]+"); if(opt & GUI_OPT_DOUBLE) mvwprintw(dataWinBox, 21,1, "[-]?[0-9]*.[0-9]+"); else if(opt & GUI_OPT_HEX) mvwprintw(dataWinBox, 21,1, "[0-9,a-z,A-Z]+"); wredrawln(dataWinBox, 21, 1); wrefresh(dataWinBox); }
int redrawwin(WINDOW *win) { PDC_LOG(("redrawwin() - called: win=%p\n", win)); if (!win) return ERR; return wredrawln(win, 0, win->_maxy); }
int main(void) { WINDOW *coffee; initscr(); coffee = newwin(2,40,0,0); waddstr(coffee,"I'm just an innocent little program,\n"); waddstr(coffee,"minding my own business..."); wmove(coffee,0,0); wrefresh(coffee); getch(); system("echo \"RANDOM DATA\" > `tty`"); getch(); wredrawln(coffee,0,1); wrefresh(coffee); getch(); endwin(); return 0; }
WRAP_API int wrap_wredrawln(WINDOW *win, int beg_line, int num_lines) { return wredrawln(win, beg_line, num_lines); }
EIF_INTEGER c_ecurses_wredrawln (EIF_POINTER w, EIF_INTEGER x, EIF_INTEGER y) { return wredrawln ( ((WINDOW *) w), (int) x, (int) y) ; };
static void test_redraw(WINDOW *win) { WINDOW *win1; WINDOW *win2; bool done = FALSE; int ch, y, x; int max_y, max_x; int beg_y, beg_x; assert(win != 0); scrollok(win, TRUE); keypad(win, TRUE); getmaxyx(win, max_y, max_x); getbegyx(win, beg_y, beg_x); while (!done && win != 0) { ch = wgetch(win); getyx(win, y, x); switch (ch) { case 'q': /* FALLTHRU */ case ESCAPE: done = TRUE; break; case 'w': win1 = newwin(max_y, max_x, beg_y, beg_x); win2 = newwin(max_y - 2, max_x - 2, beg_y + 1, beg_x + 1); box(win1, 0, 0); wrefresh(win1); test_redraw(win2); delwin(win2); delwin(win1); touchwin(win); break; case '!': /* * redrawwin() and wredrawln() do not take into account the * possibility that the cursor may have moved. That makes them * cumbersome for using with a shell command. So we simply * trash the current line of the window using backspace/overwrite. */ trash(beg_x, max_x, x + beg_x); break; #ifdef NCURSES_VERSION case '@': /* * For a shell command, we can work around the problem noted above * using mvcur(). It is ifdef'd for NCURSES, since X/Open does * not define the case where the old location is unknown. */ IGNORE_RC(system("date")); mvcur(-1, -1, y, x); break; #endif case CTRL('W'): redrawwin(win); break; case CTRL('L'): wredrawln(win, y, 1); break; case KEY_UP: if (y > 0) wmove(win, y - 1, x); break; case KEY_DOWN: if (y < max_y) wmove(win, y + 1, x); break; case KEY_LEFT: if (x > 0) wmove(win, y, x - 1); break; case KEY_RIGHT: if (x < max_x) wmove(win, y, x + 1); break; default: if (ch > KEY_MIN) { waddstr(win, keyname(ch)); } else { waddstr(win, unctrl(UChar(ch))); } break; } wnoutrefresh(win); doupdate(); } }
static void test_redraw(WINDOW *win) { static const char *help[] = { "Commands:", " ^Q/ESC/q - quit", " w - recur in a new window", " ! - overwrite current line using stdio outside curses.", #ifdef NCURSES_VERSION " @ - run \"date\" command, to put its output on screen.", #endif " ^L - call redrawwin() for current window.", " ^W - call wredrawln() for current line/current window.", " arrow-keys - move cursor on the screen", "", "Other control characters are added to the screen in printable form.", "Other printable characters are added to the screen as is.", 0 }; WINDOW *win1; WINDOW *win2; bool done = FALSE; int ch, y, x; int max_y, max_x; int beg_y, beg_x; assert(win != 0); scrollok(win, TRUE); keypad(win, TRUE); getmaxyx(win, max_y, max_x); getbegyx(win, beg_y, beg_x); while (!done) { ch = wgetch(win); getyx(win, y, x); switch (ch) { case 'q': /* FALLTHRU */ case QUIT: case ESCAPE: done = TRUE; break; case 'w': win1 = newwin(max_y, max_x, beg_y, beg_x); win2 = newwin(max_y - 2, max_x - 2, beg_y + 1, beg_x + 1); box(win1, 0, 0); wrefresh(win1); test_redraw(win2); delwin(win2); delwin(win1); touchwin(win); break; case '!': /* * redrawwin() and wredrawln() do not take into account the * possibility that the cursor may have moved. That makes them * cumbersome for using with a shell command. So we simply * trash the current line of the window using backspace/overwrite. */ trash(beg_x, max_x, x + beg_x); break; #ifdef NCURSES_VERSION case '@': /* * For a shell command, we can work around the problem noted above * using mvcur(). It is ifdef'd for NCURSES, since X/Open does * not define the case where the old location is unknown. */ IGNORE_RC(system("date")); mvcur(-1, -1, y, x); break; #endif case CTRL('W'): redrawwin(win); break; case CTRL('L'): wredrawln(win, y, 1); break; case KEY_UP: if (y > 0) wmove(win, y - 1, x); break; case KEY_DOWN: if (y < max_y) wmove(win, y + 1, x); break; case KEY_LEFT: if (x > 0) wmove(win, y, x - 1); break; case KEY_RIGHT: if (x < max_x) wmove(win, y, x + 1); break; case HELP_KEY_1: popup_msg(win, help); break; default: if (ch > KEY_MIN) { waddstr(win, keyname(ch)); waddch(win, '\n'); } else { waddstr(win, unctrl(UChar(ch))); } break; } wnoutrefresh(win); doupdate(); } }
int main(int argc, char **argv) { int exit_status = 0; char header[HEADER_BUFFER_SIZE]; size_t header_length = snprintf( header, sizeof(header), "%-*s %-*s %-*s %-*s %-*s %-*s %*s %*s %*s " "%*s %*s %*s %*s %*s %*s\n", PID_Column_Width, PID_Column_Name, PPID_Column_Width, PPID_Column_Name, Name_Column_Width, Name_Column_Name, UID_Column_Width, UID_Column_Name, GID_Column_Width, GID_Column_Name, State_Column_Width, State_Column_Name, Nice_Column_Width, Nice_Column_Name, UTime_Column_Width, UTime_Column_Name, KTime_Column_Width, KTime_Column_Name, RSS_Column_Width, RSS_Column_Name, VM_Column_Width, VM_Column_Name, Reads_Column_Width, Reads_Column_Name, Writes_Column_Width, Writes_Column_Name, Read_Column_Width, Read_Column_Name, Written_Column_Width, Written_Column_Name ); pid_t *pid_list = NULL; char total_ram_scaled[FIELD_BUFFER_SIZE]; char used_ram_scaled[FIELD_BUFFER_SIZE]; char free_ram_scaled[FIELD_BUFFER_SIZE]; char total_swap_scaled[FIELD_BUFFER_SIZE]; char used_swap_scaled[FIELD_BUFFER_SIZE]; char free_swap_scaled[FIELD_BUFFER_SIZE]; char user_cpu_time_scaled[FIELD_BUFFER_SIZE]; char kernel_cpu_time_scaled[FIELD_BUFFER_SIZE]; char core_memory_usage_scaled[FIELD_BUFFER_SIZE]; char virtual_memory_usage_scaled[FIELD_BUFFER_SIZE]; char data_read_scaled[FIELD_BUFFER_SIZE]; char data_written_scaled[FIELD_BUFFER_SIZE]; bool show_kernel_threads = false; if (!initscr()) { fprintf( stderr, "Failed to create the program's UI.\n" ); exit_status = EXIT_FAILURE; goto cleanup; } if (has_colors()) { start_color(); use_default_colors(); init_pair(1, COLOR_BLACK, COLOR_WHITE); } noecho(); halfdelay(Input_Delay); WINDOW *header_pad = newpad(1, header_length); if (!header_pad) { fprintf( stderr, "Failed to create a UI pad for a header.\n" ); exit_status = EXIT_FAILURE; goto cleanup; } bool has_attribute = false; if (has_colors()) { wattron(header_pad, COLOR_PAIR(1)); has_attribute = !has_attribute; } waddstr(header_pad, header); if (has_attribute) { wattroff(header_pad, COLOR_PAIR(1)); } WINDOW *pad = NULL; int pad_height = -1; int pad_shift_y = 0; int pad_shift_x = 0; WINDOW *footer_pad = newpad(1, header_length); if (!footer_pad) { fprintf( stderr, "Failed to create a UI pad for a footer.\n" ); exit_status = EXIT_FAILURE; goto cleanup; } wprintw( footer_pad, "Press 't' to %s kernel threads. Press 'q' to exit.", show_kernel_threads ? "hide" : "show" ); for (;;) { pid_t current_pid = getpid(); struct sysinfo system; if (sysinfo(&system)) { fprintf( stderr, "Failed to perform the 'sysinfo' system call.\n" ); exit_status = EXIT_FAILURE; goto cleanup; } long pid_list_length = syscall(__NR_get_pids, 0, NULL); if (pid_list_length <= 0) { fprintf( stderr, "Failed to perform the 'get_pids' system call. " "Ensure that the 'task_info' subsystem was compiled " "into the kernel.\n" ); exit_status = EXIT_FAILURE; goto cleanup; } size_t pid_list_size = pid_list_length * sizeof(*pid_list); if (!(pid_list = realloc(pid_list, pid_list_size))) { fprintf(stderr, "Failed to reserve memory.\n"); exit_status = EXIT_FAILURE; goto cleanup; } memset(pid_list, 0, pid_list_size); if (syscall(__NR_get_pids, pid_list_length, pid_list) <= 0) { fprintf( stderr, "Failed to perform the 'get_pids' system call. " "Ensure that the 'task_info' subsystem was compiled " "into the kernel.\n" ); exit_status = EXIT_FAILURE; goto cleanup; } if (pad_height != pid_list_length + 1) { pad_height = pid_list_length + 1; if (pad) { delwin(pad); } pad = newpad(pad_height, header_length); if (!pad) { fprintf( stderr, "Failed to create a scrollable UI pad.\n" ); exit_status = EXIT_FAILURE; goto cleanup; } keypad(pad, true); } size_t header_height = Header_Height; unsigned long uptime_days = system.uptime / 86400; unsigned long uptime_hours = system.uptime / 3600 - uptime_days * 24; unsigned long uptime_minutes = system.uptime / 60 - uptime_days * 1440 - uptime_hours * 60; unsigned long uptime_seconds = system.uptime % 60; float load_average_scale = 1 << SI_LOAD_SHIFT; float load_average_for_1_minute = system.loads[0] / load_average_scale; float load_average_for_5_minutes = system.loads[1] / load_average_scale; float load_average_for_15_minutes = system.loads[1] / load_average_scale; uint64_t total_ram = system.totalram * system.mem_unit; uint64_t used_ram = (system.totalram - system.freeram) * system.mem_unit; uint64_t free_ram = system.freeram * system.mem_unit; uint64_t total_swap = system.totalswap * system.mem_unit; uint64_t used_swap = (system.totalswap - system.freeswap) * system.mem_unit; uint64_t free_swap = system.freeswap * system.mem_unit; scale_size( total_ram, total_ram_scaled, sizeof(total_ram_scaled) ); scale_size( used_ram, used_ram_scaled, sizeof(used_ram_scaled) ); scale_size( free_ram, free_ram_scaled, sizeof(free_ram_scaled) ); scale_size( total_swap, total_swap_scaled, sizeof(total_swap_scaled) ); scale_size( used_swap, used_swap_scaled, sizeof(used_swap_scaled) ); scale_size( free_swap, free_swap_scaled, sizeof(free_swap_scaled) ); wredrawln(stdscr, 0, header_height); mvprintw( 0, 0, "up for %lu %s %lu:%lu:%lu, tasks: %zu\n" "load average: %.2f, %.2f, %.2f\n" "\n" "total ram: %*s, used ram: %*s, free ram: %*s\n" "total swap: %*s, used swap: %*s, free swap: %*s\n", uptime_days, uptime_days == 1 ? "day" : "days", uptime_hours, uptime_minutes, uptime_seconds, pid_list_length, load_average_for_1_minute, load_average_for_5_minutes, load_average_for_15_minutes, Memory_Column_Width, total_ram_scaled, Memory_Column_Width, used_ram_scaled, Memory_Column_Width, free_ram_scaled, Memory_Column_Width, total_swap_scaled, Memory_Column_Width, used_swap_scaled, Memory_Column_Width, free_swap_scaled ); werase(pad); int real_pad_height = 0; for (size_t i = 0; i < pid_list_length; ++i) { struct task_info task; pid_t pid = pid_list[i]; if (syscall(__NR_get_task_info, pid, &task) == 0) { if (!show_kernel_threads && (task.pid == Kernel_Thread_Daemon_PID || task.ppid == Kernel_Thread_Daemon_PID)) { continue; } const char *task_state = task.state < Task_States_Count - 1 ? Task_States[task.state + 1] : Task_States[0]; scale_time( task.user_cpu_time, user_cpu_time_scaled, sizeof(user_cpu_time_scaled) ); scale_time( task.system_cpu_time, kernel_cpu_time_scaled, sizeof(kernel_cpu_time_scaled) ); scale_size( task.core_memory_bytes_used, core_memory_usage_scaled, sizeof(core_memory_usage_scaled) ); scale_size( task.virtual_memory_bytes_used, virtual_memory_usage_scaled, sizeof(virtual_memory_usage_scaled) ); scale_size( task.bytes_read, data_read_scaled, sizeof(data_read_scaled) ); scale_size( task.bytes_written, data_written_scaled, sizeof(data_written_scaled) ); has_attribute = false; if (has_colors()) { if (task.state == 0 && task.pid != current_pid) { wattron(pad, COLOR_PAIR(1)); has_attribute = !has_attribute; } } wprintw( pad, "%-*d %-*d %-*s %-*d %-*d %-*s %*d " "%*s %*s %*s %*s " "%*"PRIu64" %*"PRIu64" " "%*s %*s\n", PID_Column_Width, (int) pid, PPID_Column_Width, task.ppid, Name_Column_Width, task.name, UID_Column_Width, task.uid, GID_Column_Width, task.gid, State_Column_Width, task_state, Nice_Column_Width, task.nice_level, UTime_Column_Width, user_cpu_time_scaled, KTime_Column_Width, kernel_cpu_time_scaled, RSS_Column_Width, core_memory_usage_scaled, VM_Column_Width, virtual_memory_usage_scaled, Reads_Column_Width, task.read_syscalls_count, Writes_Column_Width, task.write_syscalls_count, Read_Column_Width, data_read_scaled, Written_Column_Width, data_written_scaled ); if (has_attribute) { wattroff(pad, COLOR_PAIR(1)); } ++real_pad_height; } } int window_height, window_width; getmaxyx(stdscr, window_height, window_width); wnoutrefresh(stdscr); prefresh( header_pad, 0, pad_shift_x, header_height, 0, header_height + 1, window_width - 1 ); prefresh( pad, pad_shift_y, pad_shift_x, header_height + 1, 0, window_height - 2, window_width - 1 ); prefresh( footer_pad, 0, 0, window_height - 1, 0, window_height, window_width - 1 ); doupdate(); int key = wgetch(pad); if (key != ERR) { switch (key) { case 'h': case KEY_LEFT: --pad_shift_x; break; case 'j': case KEY_DOWN: ++pad_shift_y; break; case 'k': case KEY_UP: --pad_shift_y; break; case 'l': case KEY_RIGHT: ++pad_shift_x; break; case 't': show_kernel_threads = !show_kernel_threads; werase(footer_pad); wprintw( footer_pad, "Press 't' to %s kernel threads. " "Press 'q' to exit.", show_kernel_threads ? "hide" : "show" ); break; case 'q': goto cleanup; } int pad_height_limit = real_pad_height - 2; if (pad_shift_y < 0) { pad_shift_y = 0; } else if (pad_shift_y > pad_height_limit) { pad_shift_y = pad_height_limit; } int pad_width_limit = header_length - 5; if (pad_shift_x < 0) { pad_shift_x = 0; } else if (pad_shift_x > pad_width_limit) { pad_shift_x = pad_width_limit; } } } cleanup: if (header_pad) { delwin(header_pad); } if (pad) { delwin(pad); } if (footer_pad) { delwin(footer_pad); } endwin(); return exit_status; }
int garbagedlines(WINDOW *win, int start, int finish) { return (wredrawln(win, start, finish)); }
void Messages::display_messages( const catacurses::window &ipk_target, const int left, const int top, const int right, const int bottom ) { if( !size() ) { return; } const int maxlength = right - left; int line = log_from_top ? top : bottom; if( log_from_top ) { for( int i = size() - 1; i >= 0; --i ) { if( line > bottom ) { break; } const game_message &m = player_messages.messages[i]; if( message_exceeds_ttl( m ) ) { break; } const nc_color col = m.get_color( player_messages.curmes ); std::string message_text = m.get_with_count(); if( !m.is_recent( player_messages.curmes ) ) { message_text = remove_color_tags( message_text ); } for( const std::string &folded : foldstring( message_text, maxlength ) ) { if( line > bottom ) { break; } // Redrawing line to ensure new messages similar to previous // messages will not be missed by screen readers wredrawln( ipk_target, line, 1 ); nc_color col_out = col; print_colored_text( ipk_target, line++, left, col_out, col, folded ); } } } else { for( int i = size() - 1; i >= 0; --i ) { if( line < top ) { break; } const game_message &m = player_messages.messages[i]; if( message_exceeds_ttl( m ) ) { break; } const nc_color col = m.get_color( player_messages.curmes ); std::string message_text = m.get_with_count(); if( !m.is_recent( player_messages.curmes ) ) { message_text = remove_color_tags( message_text ); } const auto folded_strings = foldstring( message_text, maxlength ); const auto folded_rend = folded_strings.rend(); for( auto string_iter = folded_strings.rbegin(); string_iter != folded_rend && line >= top; ++string_iter, line-- ) { // Redrawing line to ensure new messages similar to previous // messages will not be missed by screen readers wredrawln( ipk_target, line, 1 ); nc_color col_out = col; print_colored_text( ipk_target, line, left, col_out, col, *string_iter ); } } } player_messages.curmes = calendar::turn; }
/* edit_draw() takes care of the job of actually painting a line into * the edit window. fileptr is the line to be painted, at row line of * the window. converted is the actual string to be written to the * window, with tabs and control characters replaced by strings of * regular characters. start is the column number of the first * character of this page. That is, the first character of converted * corresponds to character number actual_x(fileptr->data, start) of the * line. */ void edit_draw(filestruct *fileptr, const char *converted, int line, size_t start) { size_t startpos = actual_x(fileptr->data, start); /* The position in fileptr->data of the leftmost character * that displays at least partially on the window. */ size_t endpos = actual_x(fileptr->data, start + COLS - 1) + 1; /* The position in fileptr->data of the first character that is * completely off the window to the right. * * Note that endpos might be beyond the null terminator of the * string. */ assert(openfile != openfiles.end() && fileptr != NULL && converted != NULL); assert(strlenpt(converted) <= COLS); /* Just paint the string in any case (we'll add color or reverse on * just the text that needs it). */ mvwaddstr(edit, line, 0, converted); /* Tell ncurses to really redraw the line without trying to optimize * for what it thinks is already there, because it gets it wrong in * the case of a wide character in column zero. */ #ifndef USE_SLANG wredrawln(edit, line, 1); #endif /* If color syntaxes are available and turned on, we need to display * them. */ if (!openfile->colorstrings.empty() && !ISSET(NO_COLOR_SYNTAX)) { /* Set up multi-line color data for this line if it's not yet calculated */ if (fileptr->multidata.empty() && openfile->syntax && openfile->syntax->nmultis > 0) { fileptr->multidata.resize(openfile->syntax->nmultis, -1); // assume that '-1' applies until we know otherwise } for (auto tmpcolor : openfile->colorstrings) { int x_start; /* Starting column for mvwaddnstr. Zero-based. */ int paintlen = 0; /* Number of chars to paint on this line. There are * COLS characters on a whole line. */ size_t index; /* Index in converted where we paint. */ regmatch_t startmatch; /* Match position for start_regex. */ regmatch_t endmatch; /* Match position for end_regex. */ if (tmpcolor->bright) { wattron(edit, A_BOLD); } if (tmpcolor->underline) { wattron(edit, A_UNDERLINE); } wattron(edit, COLOR_PAIR(tmpcolor->pairnum)); /* Two notes about regexec(). A return value of zero means * that there is a match. Also, rm_eo is the first * non-matching character after the match. */ /* First case,tmpcolor is a single-line expression. */ if (tmpcolor->end == NULL) { size_t k = 0; /* We increment k by rm_eo, to move past the end of the * last match. Even though two matches may overlap, we * want to ignore them, so that we can highlight e.g. C * strings correctly. */ while (k < endpos) { /* Note the fifth parameter to regexec(). It says * not to match the beginning-of-line character * unless k is zero. If regexec() returns * REG_NOMATCH, there are no more matches in the * line. */ if (regexec(tmpcolor->start, &fileptr->data[k], 1, &startmatch, (k == 0) ? 0 : REG_NOTBOL) == REG_NOMATCH) { break; } /* Translate the match to the beginning of the * line. */ startmatch.rm_so += k; startmatch.rm_eo += k; /* Skip over a zero-length regex match. */ if (startmatch.rm_so == startmatch.rm_eo) { startmatch.rm_eo++; } else if (startmatch.rm_so < endpos && startmatch.rm_eo > startpos) { x_start = (startmatch.rm_so <= startpos) ? 0 : strnlenpt(fileptr->data, startmatch.rm_so) - start; index = actual_x(converted, x_start); paintlen = actual_x(converted + index, strnlenpt(fileptr->data, startmatch.rm_eo) - start - x_start); assert(0 <= x_start && 0 <= paintlen); mvwaddnstr(edit, line, x_start, converted + index, paintlen); } k = startmatch.rm_eo; } } else if (!fileptr->multidata.empty() && fileptr->multidata[tmpcolor->id] != CNONE) { /* This is a multi-line regex. There are two steps. * First, we have to see if the beginning of the line is * colored by a start on an earlier line, and an end on * this line or later. * * We find the first line before fileptr matching the * start. If every match on that line is followed by an * end, then go to step two. Otherwise, find the next * line after start_line matching the end. If that line * is not before fileptr, then paint the beginning of * this line. */ const filestruct *start_line = fileptr->prev; /* The first line before fileptr matching start. */ regoff_t start_col; /* Where it starts in that line. */ const filestruct *end_line; short md = fileptr->multidata[tmpcolor->id]; if (md == -1) { fileptr->multidata[tmpcolor->id] = CNONE; /* until we find out otherwise */ } else if (md == CNONE) { unset_formatting(tmpcolor); continue; } else if (md == CWHOLELINE) { mvwaddnstr(edit, line, 0, converted, -1); unset_formatting(tmpcolor); continue; } else if (md == CBEGINBEFORE) { regexec(tmpcolor->end, fileptr->data, 1, &endmatch, 0); paintlen = actual_x(converted, strnlenpt(fileptr->data, endmatch.rm_eo) - start); mvwaddnstr(edit, line, 0, converted, paintlen); unset_formatting(tmpcolor); continue; } while (start_line != NULL && regexec(tmpcolor->start, start_line->data, 1, &startmatch, 0) == REG_NOMATCH) { /* If there is an end on this line, there is no need * to look for starts on earlier lines. */ if (regexec(tmpcolor->end, start_line->data, 0, NULL, 0) == 0) { goto step_two; } start_line = start_line->prev; } /* If the found start has been qualified as an end earlier, believe it and skip to the next step. */ if (start_line != NULL && !start_line->multidata.empty() && start_line->multidata[tmpcolor->id] == CBEGINBEFORE) { goto step_two; } /* Skip over a zero-length regex match. */ if (startmatch.rm_so == startmatch.rm_eo) { startmatch.rm_eo++; } else { /* No start found, so skip to the next step. */ if (start_line == NULL) { goto step_two; } /* Now start_line is the first line before fileptr * containing a start match. Is there a start on * this line not followed by an end on this line? */ start_col = 0; while (true) { start_col += startmatch.rm_so; startmatch.rm_eo -= startmatch.rm_so; if (regexec(tmpcolor->end, start_line->data + start_col + startmatch.rm_eo, 0, NULL, (start_col + startmatch.rm_eo == 0) ? 0 : REG_NOTBOL) == REG_NOMATCH) { /* No end found after this start. */ break; } start_col++; if (regexec(tmpcolor->start, start_line->data + start_col, 1, &startmatch, REG_NOTBOL) == REG_NOMATCH) { /* No later start on this line. */ goto step_two; } } /* Indeed, there is a start not followed on this * line by an end. */ /* We have already checked that there is no end * before fileptr and after the start. Is there an * end after the start at all? We don't paint * unterminated starts. */ end_line = fileptr; while (end_line != NULL && regexec(tmpcolor->end, end_line->data, 1, &endmatch, 0) == REG_NOMATCH) { end_line = end_line->next; } /* No end found, or it is too early. */ if (end_line == NULL || (end_line == fileptr && endmatch.rm_eo <= startpos)) { goto step_two; } /* Now paint the start of fileptr. If the start of * fileptr is on a different line from the end, * paintlen is -1, meaning that everything on the * line gets painted. Otherwise, paintlen is the * expanded location of the end of the match minus * the expanded location of the beginning of the * page. */ if (end_line != fileptr) { paintlen = -1; fileptr->multidata[tmpcolor->id] = CWHOLELINE; } else { paintlen = actual_x(converted, strnlenpt(fileptr->data, endmatch.rm_eo) - start); fileptr->multidata[tmpcolor->id] = CBEGINBEFORE; } mvwaddnstr(edit, line, 0, converted, paintlen); /* If the whole line has been painted, don't bother looking for any more starts. */ if (paintlen < 0) { continue; } step_two: /* Second step, we look for starts on this line. */ start_col = 0; while (start_col < endpos) { if (regexec(tmpcolor->start, fileptr->data + start_col, 1, &startmatch, (start_col == 0) ? 0 : REG_NOTBOL) == REG_NOMATCH || start_col + startmatch.rm_so >= endpos) { /* No more starts on this line. */ break; } /* Translate the match to be relative to the * beginning of the line. */ startmatch.rm_so += start_col; startmatch.rm_eo += start_col; x_start = (startmatch.rm_so <= startpos) ? 0 : strnlenpt(fileptr->data, startmatch.rm_so) - start; index = actual_x(converted, x_start); if (regexec(tmpcolor->end, fileptr->data + startmatch.rm_eo, 1, &endmatch, (startmatch.rm_eo == 0) ? 0 : REG_NOTBOL) == 0) { /* Translate the end match to be relative to the beginning of the line. */ endmatch.rm_so += startmatch.rm_eo; endmatch.rm_eo += startmatch.rm_eo; /* There is an end on this line. But does * it appear on this page, and is the match * more than zero characters long? */ if (endmatch.rm_eo > startpos && endmatch.rm_eo > startmatch.rm_so) { paintlen = actual_x(converted + index, strnlenpt(fileptr->data, endmatch.rm_eo) - start - x_start); assert(0 <= x_start && x_start < COLS); mvwaddnstr(edit, line, x_start, converted + index, paintlen); if (paintlen > 0) { fileptr->multidata[tmpcolor->id] = CSTARTENDHERE; } } } else { /* There is no end on this line. But we * haven't yet looked for one on later * lines. */ end_line = fileptr->next; while (end_line != NULL && regexec(tmpcolor->end, end_line->data, 0, NULL, 0) == REG_NOMATCH) { end_line = end_line->next; } if (end_line != NULL) { assert(0 <= x_start && x_start < COLS); mvwaddnstr(edit, line, x_start, converted + index, -1); /* We painted to the end of the line, so * don't bother checking any more * starts. */ fileptr->multidata[tmpcolor->id] = CENDAFTER; break; } } start_col = startmatch.rm_so + 1; } } } unset_formatting(tmpcolor); } } /* If the mark is on, we need to display it. */ if (openfile->mark_set && (fileptr->lineno <= openfile->mark_begin->lineno || fileptr->lineno <= openfile->current->lineno) && (fileptr->lineno >= openfile->mark_begin->lineno || fileptr->lineno >= openfile->current->lineno)) { /* fileptr is at least partially selected. */ const filestruct *top; /* Either current or mark_begin, whichever is first. */ size_t top_x; /* current_x or mark_begin_x, corresponding to top. */ const filestruct *bot; size_t bot_x; int x_start; /* Starting column for mvwaddnstr(). Zero-based. */ int paintlen; /* Number of characters to paint on this line. There are * COLS characters on a whole line. */ size_t index; /* Index in converted where we paint. */ mark_order(&top, &top_x, &bot, &bot_x, NULL); if (top->lineno < fileptr->lineno || top_x < startpos) { top_x = startpos; } if (bot->lineno > fileptr->lineno || bot_x > endpos) { bot_x = endpos; } /* The selected bit of fileptr is on this page. */ if (top_x < endpos && bot_x > startpos) { assert(startpos <= top_x); /* x_start is the expanded location of the beginning of the * mark minus the beginning of the page. */ x_start = strnlenpt(fileptr->data, top_x) - start; /* If the end of the mark is off the page, paintlen is -1, * meaning that everything on the line gets painted. * Otherwise, paintlen is the expanded location of the end * of the mark minus the expanded location of the beginning * of the mark. */ if (bot_x >= endpos) { paintlen = -1; } else paintlen = strnlenpt(fileptr->data, bot_x) - (x_start + start); /* If x_start is before the beginning of the page, shift * paintlen x_start characters to compensate, and put * x_start at the beginning of the page. */ if (x_start < 0) { paintlen += x_start; x_start = 0; } assert(x_start >= 0 && x_start <= strlen(converted)); index = actual_x(converted, x_start); if (paintlen > 0) { paintlen = actual_x(converted + index, paintlen); } set_color(edit, interface_colors[FUNCTION_TAG]); mvwaddnstr(edit, line, x_start, converted + index, paintlen); clear_color(edit, interface_colors[FUNCTION_TAG]); } } }
static long int dir_aff_ncurses(disk_t *disk, const partition_t *partition, dir_data_t *dir_data, file_data_t*dir_list, const unsigned long int inode, const unsigned int depth) { /* Return value * -1: quit * 1: back * other: new inode * */ int quit=0; WINDOW *window=(WINDOW*)dir_data->display; do { int offset=0; int pos_num=0; file_data_t *pos=dir_list; int old_LINES=LINES; unsigned int status=FILE_STATUS_MARKED; aff_copy(window); wmove(window,3,0); aff_part(window, AFF_PART_ORDER|AFF_PART_STATUS, disk, partition); wmove(window,4,0); wprintw(window,"Directory %s\n",dir_data->current_directory); do { int i; int car; const file_data_t *current_file; for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++); for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_DIR);i++,current_file=current_file->next) { char str[11]; char datestr[80]; wmove(window, 6+i-offset, 0); wclrtoeol(window); /* before addstr for BSD compatibility */ if(current_file==pos) { wattrset(window, A_REVERSE); waddstr(window, ">"); } else waddstr(window, " "); if((current_file->status&FILE_STATUS_DELETED)!=0 && has_colors()) wbkgdset(window,' ' | COLOR_PAIR(1)); else if((current_file->status&FILE_STATUS_MARKED)!=0 && has_colors()) wbkgdset(window,' ' | COLOR_PAIR(2)); if(current_file->td_mtime!=0) { struct tm *tm_p; tm_p = localtime(¤t_file->td_mtime); snprintf(datestr, sizeof(datestr),"%2d-%s-%4d %02d:%02d", tm_p->tm_mday, monstr[tm_p->tm_mon], 1900 + tm_p->tm_year, tm_p->tm_hour, tm_p->tm_min); /* May have to use %d instead of %e */ } else { strncpy(datestr, " ",sizeof(datestr)); } mode_string(current_file->st_mode, str); wprintw(window, "%s %5u %5u ", str, (unsigned int)current_file->st_uid, (unsigned int)current_file->st_gid); wprintw(window, "%9llu", (long long unsigned int)current_file->st_size); /* screen may overlap due to long filename */ wprintw(window, " %s %s", datestr, current_file->name); if(((current_file->status&FILE_STATUS_DELETED)!=0 || (current_file->status&FILE_STATUS_MARKED)!=0) && has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); if(current_file==pos) wattroff(window, A_REVERSE); } wmove(window, 6-1, 51); wclrtoeol(window); if(offset>0) wprintw(window, "Previous"); /* Clear the last line, useful if overlapping */ wmove(window,6+i-offset,0); wclrtoeol(window); wmove(window, 6+INTER_DIR, 51); wclrtoeol(window); if(current_file!=NULL) wprintw(window, "Next"); if(dir_list==NULL) { wmove(window,6,0); wprintw(window,"No file found, filesystem may be damaged."); } /* Redraw the bottom of the screen everytime because very long filenames may have corrupt it*/ mvwaddstr(window,LINES-3,0,"Use "); if(depth>0) { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window, "Left"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," arrow to go back, "); } if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"Right"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to change directory"); if((dir_data->capabilities&CAPA_LIST_DELETED)!=0) { waddstr(window,", "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"h"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); if((dir_data->param&FLAG_LIST_DELETED)==0) waddstr(window," to unhide deleted files"); else waddstr(window," to hide deleted files"); } wmove(window,LINES-2,4); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"q"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to quit"); if(dir_data->copy_file!=NULL) { waddstr(window,", "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,":"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to select the current file, "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"a"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); if((status&FILE_STATUS_MARKED)==FILE_STATUS_MARKED) waddstr(window," to select all files "); else waddstr(window," to deselect all files"); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); mvwaddstr(window,LINES-1,4,"C"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to copy the selected files, "); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(0)); waddstr(window,"c"); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); waddstr(window," to copy the current file"); } wrefresh(window); /* Using gnome terminal under FC3, TERM=xterm, the screen is not always correct */ wredrawln(window,0,getmaxy(window)); /* redrawwin def is boggus in pdcur24 */ car=wgetch(window); wmove(window,5,0); wclrtoeol(window); switch(car) { case key_ESC: case 'q': case 'M': quit=1; break; case '-': case KEY_LEFT: case '4': if(depth>0) return 1; break; case 'h': if((dir_data->capabilities&CAPA_LIST_DELETED)!=0) dir_data->param^=FLAG_LIST_DELETED; return inode; } if(dir_list!=NULL) { switch(car) { case KEY_UP: case '8': if(pos->prev!=NULL) { pos=pos->prev; pos_num--; } break; case KEY_DOWN: case '2': if(pos->next!=NULL) { pos=pos->next; pos_num++; } break; case ':': if(!(pos->name[0]=='.' && pos->name[1]=='\0') && !(pos->name[0]=='.' && pos->name[1]=='.' && pos->name[2]=='\0')) pos->status^=FILE_STATUS_MARKED; if(pos->next!=NULL) { pos=pos->next; pos_num++; } break; case 'a': { file_data_t *tmp; for(tmp=dir_list; tmp!=NULL; tmp=tmp->next) { if((tmp->name[0]=='.' && tmp->name[1]=='\0') || (tmp->name[0]=='.' && tmp->name[1]=='.' && tmp->name[2]=='\0')) { tmp->status&=~FILE_STATUS_MARKED; } else { if((tmp->status & FILE_STATUS_MARKED)!=status) tmp->status^=FILE_STATUS_MARKED; } } status^=FILE_STATUS_MARKED; } break; case 'p': case 'P': case '+': case ' ': case KEY_RIGHT: case '\r': case '\n': case '6': case KEY_ENTER: #ifdef PADENTER case PADENTER: #endif if((pos!=NULL) && (LINUX_S_ISDIR(pos->st_mode)!=0)) { unsigned long int new_inode=pos->st_ino; if((new_inode!=inode) &&(strcmp(pos->name,".")!=0)) { if(strcmp(pos->name,"..")==0) return 1; if(strlen(dir_data->current_directory)+1+strlen(pos->name)+1<=sizeof(dir_data->current_directory)) { if(strcmp(dir_data->current_directory,"/")) strcat(dir_data->current_directory,"/"); strcat(dir_data->current_directory,pos->name); return (long int)new_inode; } } } break; case KEY_PPAGE: for(i=0;(i<INTER_DIR-1)&&(pos->prev!=NULL);i++) { pos=pos->prev; pos_num--; } break; case KEY_NPAGE: for(i=0;(i<INTER_DIR-1)&&(pos->next!=NULL);i++) { pos=pos->next; pos_num++; } break; case 'c': if(dir_data->copy_file!=NULL) { const unsigned int current_directory_namelength=strlen(dir_data->current_directory); if(strcmp(pos->name,"..")!=0 && current_directory_namelength+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1) { if(strcmp(dir_data->current_directory,"/")) strcat(dir_data->current_directory,"/"); if(strcmp(pos->name,".")!=0) strcat(dir_data->current_directory,pos->name); if(dir_data->local_dir==NULL) { if(LINUX_S_ISDIR(pos->st_mode)!=0) dir_data->local_dir=ask_location("Please select a destination where %s and any files below will be copied.", dir_data->current_directory, NULL); else dir_data->local_dir=ask_location("Please select a destination where %s will be copied.", dir_data->current_directory, NULL); } if(dir_data->local_dir!=NULL) { int res=-1; wmove(window,5,0); wclrtoeol(window); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copying, please wait..."); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); wrefresh(window); if(LINUX_S_ISDIR(pos->st_mode)!=0) { res=copy_dir(disk, partition, dir_data, pos); } else if(LINUX_S_ISREG(pos->st_mode)!=0) { res=dir_data->copy_file(disk, partition, dir_data, pos); } wmove(window,5,0); wclrtoeol(window); if(res < -1) { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copy failed!"); } else { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2)); if(res < 0) wprintw(window,"Copy done! (Failed to copy some files)"); else wprintw(window,"Copy done!"); } if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); } dir_data->current_directory[current_directory_namelength]='\0'; } } break; case 'C': if(dir_data->copy_file!=NULL) { if(dir_data->local_dir==NULL) { dir_data->local_dir=ask_location("Please select a destination where the marked files will be copied.", NULL, NULL); } if(dir_data->local_dir!=NULL) { file_data_t *tmp; int copy_bad=0; int copy_ok=0; const unsigned int current_directory_namelength=strlen(dir_data->current_directory); wmove(window,5,0); wclrtoeol(window); if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copying, please wait..."); if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); wrefresh(window); for(tmp=dir_list; tmp!=NULL; tmp=tmp->next) { if((tmp->status&FILE_STATUS_MARKED)!=0 && current_directory_namelength + 1 + strlen(tmp->name) < sizeof(dir_data->current_directory)-1) { if(strcmp(dir_data->current_directory,"/")) strcat(dir_data->current_directory,"/"); if(strcmp(tmp->name,".")!=0) strcat(dir_data->current_directory,tmp->name); if(LINUX_S_ISDIR(tmp->st_mode)!=0) { const int res=copy_dir(disk, partition, dir_data, tmp); if(res >=-1) { tmp->status&=~FILE_STATUS_MARKED; copy_ok=1; } else if(res < 0) copy_bad=1; } else if(LINUX_S_ISREG(tmp->st_mode)!=0) { if(dir_data->copy_file(disk, partition, dir_data, tmp) == 0) { tmp->status&=~FILE_STATUS_MARKED; copy_ok=1; } else copy_bad=1; } } dir_data->current_directory[current_directory_namelength]='\0'; } wmove(window,5,0); wclrtoeol(window); if(copy_bad > 0 && copy_ok==0) { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(1)); wprintw(window,"Copy failed!"); } else { if(has_colors()) wbkgdset(window,' ' | A_BOLD | COLOR_PAIR(2)); if(copy_bad > 0) wprintw(window,"Copy done! (Failed to copy some files)"); else if(copy_ok == 0) wprintw(window,"No file selected"); else wprintw(window,"Copy done!"); } if(has_colors()) wbkgdset(window,' ' | COLOR_PAIR(0)); } } break; case 'f': { const char *needle=ask_string_ncurses("Filename to find ? "); if(needle!=NULL && needle[0]!='\0') { file_data_t *pos_org=pos; const int pos_num_org=pos_num; while(strcmp(pos->name, needle)!=0 && pos->next!=NULL) { pos=pos->next; pos_num++; } if(strcmp(pos->name, needle)!=0) { pos=pos_org; pos_num=pos_num_org; } } } break; } if(pos_num<offset) offset=pos_num; if(pos_num>=offset+INTER_DIR) offset=pos_num-INTER_DIR+1; } } while(quit==0 && old_LINES==LINES); } while(quit==0); return -1; }
NCURSES_EXPORT(int) (redrawwin) (WINDOW * z) { T((T_CALLED("redrawwin(%p)"), (const void *)z)); returnCode(wredrawln(z, 0, (z)->_maxy+1)); }