/* The file contins routines for managing curses Copyright (C) 2000 Kalum Somaratna This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef HAVE_CONFIG_H # include #endif /* * HAVE_CONFIG_H */ #include #include #include #include #include #ifdef HAVE_NCURSES_H #include #else #include #endif /* * HAVE_CURSES */ #include #include #include #include #include "interface.h" #include "misc.h" #include "main.h" //#include "ftpsearch_win.h" /* This is used to convert the connection.status enums to a user * friendly text message */ /* the enums are defined in connection.h and are as belor *typedef enum { * IDLE = 0, * CONNECTING, * LOGGININ, * DOWNLOADING, * COMPLETED, * LOGINFAIL, * CONREJECTED, * REMOTEFATAL, * LOCALFATAL **} dl_status; * * And here are the texts for the above enums. */ const char *dl_status_txt[] = { "Idle", "Connecting", "Logging in", "Downloading", "Completed", /* I have decided to change the login failed message * to something else like "login rejected" because people * might get alarmed and abort the download rather than * letting prozilla handle it */ "Login Denied", "Connect Refused", "Remote Fatal", "Local Fatal", "Timed Out", "Max attempts reached", }; #define CTRL(x) ((x) & 0x1F) //static int top_con = 0; // the connection that is on the top of the display #define MAX_CON_VIEWS 4 /* * needed for the message(...) function */ pthread_mutex_t curses_msg_mutex = PTHREAD_MUTEX_INITIALIZER; char message_buffer[MAX_MSG_SIZE]; /* Added for current_dl_speed */ time_t time_stamp; off_t bytes_got_last_time; int start = 1; float current_dl_speed = 0.0; off_t total_bytes_got; int maxRow = 0; int maxCol = 0; int messageRow = 0; int messageCol = 0; /* Message: prints a message to the screen */ void curses_message(char *message) { short i; int x, y; attr_t attrs; /* * Lock the mutex */ pthread_mutex_lock(&curses_msg_mutex); /* * get the cursor position */ getyx(stdscr, y, x); wattr_get(stdscr, &attrs, &i, NULL); move(messageRow - 1, 0); clrtoeol(); move(messageRow, 0); clrtoeol(); move(messageRow + 1, 0); clrtoeol(); attrset(COLOR_PAIR(MSG_PAIR) | A_BOLD); mvprintw(messageRow, 0, "%s", message); attrset(COLOR_PAIR(NULL_PAIR)); /* * Unlock the mutex */ refresh(); wattr_set(stdscr, attrs, i, NULL); /* * set the cursor to whhere it was */ move(y, x); pthread_mutex_unlock(&curses_msg_mutex); } /* Displays the mesasge and gets the users input for overwriting files*/ int curses_query_user_input(const char *args, ...) { char p[MAX_MSG_SIZE + 1]; va_list vp; attr_t attrs; int x, y; int ch; short i; va_start(vp, args); vsnprintf(p, sizeof(p), args, vp); va_end(vp); getyx(stdscr, y, x); wattr_get(stdscr, &attrs, &i, NULL); attrset(COLOR_PAIR(PROMPT_PAIR) | A_BOLD); move(19, 0); clrtoeol(); move(20, 0); clrtoeol(); move(21, 0); clrtoeol(); mvprintw(19, 0, "%s", p); echo(); refresh(); do { napms(20); ch = getch(); } while (ch == ERR); refresh(); noecho(); wattr_set(stdscr, attrs, i, NULL); /* * set the cursor to where it was */ move(y, x); /* * the following strange line is for compatibility */ return islower(ch) ? toupper(ch) : ch; } void initCurses() { initscr(); keypad(stdscr, TRUE); start_color(); noecho(); nodelay(stdscr, TRUE); init_pair(HIGHLIGHT_PAIR, COLOR_GREEN, COLOR_BLACK); init_pair(MSG_PAIR, COLOR_YELLOW, COLOR_BLUE); init_pair(WARN_PAIR, COLOR_RED, COLOR_BLACK); init_pair(PROMPT_PAIR, COLOR_RED, COLOR_BLACK); init_pair(SELECTED_PAIR, COLOR_WHITE, COLOR_BLUE); getmaxyx(stdscr, maxRow, maxCol); messageRow = maxRow - 2; messageCol = 1; } void shutdownCurses() { endwin(); } void PrintMessage(const char *format, ...) { va_list args; char message[MAX_MSG_SIZE + 1 + 1]; va_start(args, format); vsnprintf((char *)&message, MAX_MSG_SIZE, format, args); va_end(args); if (rt.display_mode == DISP_CURSES) { curses_message(message); } else { if (fwrite(message, 1, strlen(message), stdout) != strlen(message)) { return; } } delay_ms(500); } void DisplayInfo(int row, int col, const char *format, ...) { va_list args; char message[MAX_MSG_SIZE + 1 + 1]; va_start(args, format); vsnprintf((char *)&message, MAX_MSG_SIZE, format, args); va_end(args); if (rt.display_mode == DISP_CURSES) { attrset(COLOR_PAIR(NULL_PAIR) | A_BOLD); mvaddstr(row, col, message); attrset(COLOR_PAIR(NULL_PAIR)); refresh(); } else { if (fwrite(message, 1, strlen(message), stdout) != strlen(message)) { return; } } // delay_ms(300); } void DisplayCursesInfo(download_t * download) { char buf[1000]; int i = 0; int line = 1; int secs_left; // erase(); refresh(); attrset(COLOR_PAIR(HIGHLIGHT_PAIR) | A_BOLD); snprintf(buf, sizeof(buf), "%s", _("Connection Server Status Received")); mvprintw(line++, 1, "%s", buf); attrset(COLOR_PAIR(NULL_PAIR)); total_bytes_got = proz_download_get_total_bytes_got(download) / 1024; if (start == 1) { time_stamp = time(NULL); bytes_got_last_time = total_bytes_got; start = 0; } if (time_stamp + 1 == time(NULL)) { current_dl_speed = total_bytes_got - bytes_got_last_time; time_stamp = time(NULL); bytes_got_last_time = total_bytes_got; } for (i = 0; i < download->num_connections; i++) { snprintf(buf, sizeof(buf), _(" %2d %-25.25s %-15.15s %10.1fK of %.1fK"), i + 1, download->pconnections[i]->u.host, proz_connection_get_status_string(download->pconnections[i]), (float)proz_connection_get_total_bytes_got(download-> pconnections[i]) / 1024, ((float)download->pconnections[i]->main_file_size / 1024) / download->num_connections); mvprintw(line++, 1, "%s", buf); } line = line + 2; attrset(COLOR_PAIR(HIGHLIGHT_PAIR) | A_BOLD); mvprintw(line++, 1, "%s", download->u.url); line++; attrset(COLOR_PAIR(HIGHLIGHT_PAIR)); if (download->main_file_size > 0) mvprintw(line++, 1, _("File Size = %jdK"), (intmax_t) (download->main_file_size / 1024)); else mvprintw(line++, 1, "%s", _("File Size = UNKNOWN")); snprintf(buf, sizeof(buf), _("Total Bytes received %jd Kb (%.2f%%)"), (intmax_t) total_bytes_got, (((float)total_bytes_got * 100) / ((float)download->main_file_size / 1024))); line++; mvprintw(line++, 1, "%s", buf); snprintf(buf, sizeof(buf), _("Current speed = %1.2fKb/s, Average D/L speed = %1.2fKb/s"), current_dl_speed, proz_download_get_average_speed(download) / 1024); mvprintw(line++, 1, "%s", buf); clrtoeol(); if ((secs_left = proz_download_get_est_time_left(download)) != -1) { if (secs_left < 60) snprintf(buf, sizeof(buf), _("Time Remaining %d Seconds"), secs_left); else if (secs_left < 3600) snprintf(buf, sizeof(buf), _("Time Remaining %d Minutes %d Seconds"), secs_left / 60, secs_left % 60); else snprintf(buf, sizeof(buf), _("Time Remaining %d Hours %d minutes"), secs_left / 3600, (secs_left % 3600) / 60); mvprintw(line++, 1, "%s", buf); clrtoeol(); line++; attrset(COLOR_PAIR(HIGHLIGHT_PAIR) | A_BOLD); if (download->resume_support) mvprintw(line++, 1, "%s", _("Resume Supported")); else mvprintw(line++, 1, "%s", _("Resume NOT Supported")); } attrset(COLOR_PAIR(NULL_PAIR)); refresh(); }