364 lines
8.8 KiB
C
364 lines
8.8 KiB
C
/* 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 <config.h>
|
|
#endif /*
|
|
* HAVE_CONFIG_H
|
|
*/
|
|
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
|
|
#ifdef HAVE_NCURSES_H
|
|
#include <ncurses.h>
|
|
#else
|
|
#include <curses.h>
|
|
#endif /*
|
|
* HAVE_CURSES
|
|
*/
|
|
|
|
#include <ctype.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#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;
|
|
|
|
|
|
/* because of different args for different ncurses, I had to write these
|
|
* my self
|
|
*/
|
|
|
|
#define kwattr_get(win, a, p, opts) ((void)((a) != 0 && (*(a) = (win)->_attrs)), (void)((p) != 0 && (*(p) = PAIR_NUMBER((win)->_attrs))), OK)
|
|
|
|
#define kwattr_set(win, a, p, opts) ((win)->_attrs = (((a) & ~A_COLOR) | COLOR_PAIR(p)), OK)
|
|
|
|
|
|
/* 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);
|
|
kwattr_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();
|
|
kwattr_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;
|
|
int i;
|
|
|
|
va_start(vp, args);
|
|
vsnprintf(p, sizeof(p), args, vp);
|
|
va_end(vp);
|
|
getyx(stdscr, y, x);
|
|
kwattr_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();
|
|
kwattr_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), _("Connection Server Status Received"));
|
|
mvprintw(line++, 1, 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, 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 = %lldK"), download->main_file_size / 1024);
|
|
else
|
|
mvprintw(line++, 1, _("File Size = UNKNOWN"));
|
|
|
|
snprintf(buf, sizeof(buf), _("Total Bytes received %lld Kb (%.2f%%)"),
|
|
total_bytes_got,
|
|
(((float)total_bytes_got * 100) / ((float)download->main_file_size / 1024)));
|
|
line++;
|
|
mvprintw(line++, 1, 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, 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, buf);
|
|
clrtoeol();
|
|
line++;
|
|
|
|
attrset(COLOR_PAIR(HIGHLIGHT_PAIR) | A_BOLD);
|
|
if (download->resume_support)
|
|
mvprintw(line++, 1, _("Resume Supported"));
|
|
else
|
|
mvprintw(line++, 1, _("Resume NOT Supported"));
|
|
}
|
|
attrset(COLOR_PAIR(NULL_PAIR));
|
|
refresh();
|
|
}
|