#ident "@(#)status.c 1.11"
/*
* status.c: handles the status line updating, etc for IRCII
*
* Written By Michael Sandrof
*
* Copyright(c) 1990
*
* See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "irc.h"
#include "ircterm.h"
#include "status.h"
#include "server.h"
#include "vars.h"
#include "hook.h"
#include "input.h"
#include "commands.h"
#include "window.h"
#include "screen.h"
#include "output.h"
#include "names.h"
#include "ircaux.h"
#include "misc.h"
#include "hash.h"
#include "fset.h"
#define MY_BUFFER 150
extern time_t start_time;
extern char *DCC_get_current_transfer(void);
extern char *ltoa(long);
extern int get_count_stat, send_count_stat;
static char *convert_format(char *, int);
static char *status_nickname(Window *);
static char *status_query_nick(Window *);
static char *status_right_justify(Window *);
static char *status_chanop(Window *);
static char *status_channel(Window *);
static char *status_server(Window *);
static char *status_mode(Window *);
static char *status_umode(Window *);
static char *status_insert_mode(Window *);
static char *status_overwrite_mode(Window *);
static char *status_away(Window *);
static char *status_oper(Window *);
static char *status_lag(Window *);
static char *status_dcc(Window *);
static char *status_msgcount(Window *);
static char *status_hold(Window *);
static char *status_version(Window *);
static char *status_clock(Window *);
static char *status_hold_lines(Window *);
static char *status_window(Window *);
static char *status_refnum(Window *);
static char *status_topic(Window *);
static char *status_null_function(Window *);
static char *status_notify_windows(Window *);
static char *convert_sub_format(char *, char);
static char *status_voice(Window *);
static char *status_dcccount(Window *);
static char *status_position(Window *);
#define cparse(format, str) convert_output_format(get_fset_var(format), "%s", str)
char *time_format = NULL; /* XXX Bogus XXX */
char *strftime_24hour = "%R";
char *strftime_12hour = "%I:%M%p";
/*----------------------------*/
/* New stuff */
static char *mode_format;
static char *umode_format;
static char *topic_format;
static char *query_format;
static char *clock_format;
static char *hold_lines_format;
static char *channel_format;
static char *server_format;
static char *notify_format;
static char *status_lag_format;
static char *msgcount_format;
static char *dcccount_format;
static char *status_format[2];
#define MAX_FUNCTIONS 33
static char *(*status_func[2][MAX_FUNCTIONS]) _((Window *));
static int func_cnt[3];
static char *status_format[2];
/*-----------------------------*/
/* update_clock: figures out the current time and returns it in a nice format */
char *update_clock(int flag)
{
static char time_str[61];
static int min = -1, hour = -1;
time_t t;
struct tm *time_val;
t = time(NULL);
time_val = localtime(&t);
if (flag == RESET_TIME || time_val->tm_min != min || time_val->tm_hour != hour) {
int server = from_server;
from_server = primary_server;
if (time_format) /* XXXX Bogus XXXX */
strftime(time_str, 60, time_format, time_val);
else if (get_int_var(CLOCK_24HOUR_VAR))
strftime(time_str, 60, strftime_24hour, time_val);
else
strftime(time_str, 60, strftime_12hour, time_val);
if ((time_val->tm_min != min) || (time_val->tm_hour != hour)) {
hour = time_val->tm_hour;
min = time_val->tm_min;
do_hook(TIMER_LIST, "%02d:%02d", hour, min);
}
if ((t - start_time) > 20)
check_serverlag(get_server_itsname(from_server));
from_server = server;
return (time_str);
}
if (flag == GET_TIME)
return (time_str);
else
return (NULL);
}
void reset_clock(Window * win, char *unused, int unused1)
{
update_clock(RESET_TIME);
update_all_status(curr_scr_win, NULL, 0);
}
/*
* convert_sub_format: This is used to convert the formats of the
* sub-portions of the status line to a format statement specially designed
* for that sub-portions. convert_sub_format looks for a single occurence of
* %c (where c is passed to the function). When found, it is replaced by "%s"
* for use is a sprintf. All other occurences of % followed by any other
* character are left unchanged. Only the first occurence of %c is
* converted, all subsequence occurences are left unchanged. This routine
* mallocs the returned string.
*/
static char *convert_sub_format(char *format, char c)
{
char buffer[BIG_BUFFER_SIZE + 1];
static char bletch[] = "%% ";
char *ptr = NULL;
int dont_got_it = 1;
if (format == NULL)
return (NULL);
*buffer = (char) 0;
memset(buffer, 0, sizeof(buffer));
while (format) {
if ((ptr = (char *) strchr(format, '%')) != NULL) {
*ptr = (char) 0;
strmcat(buffer, format, BIG_BUFFER_SIZE);
*(ptr++) = '%';
if ((*ptr == c) /* && dont_got_it */ ) {
dont_got_it = 0;
strmcat(buffer, "%s", BIG_BUFFER_SIZE);
} else {
bletch[2] = *ptr;
strmcat(buffer, bletch, BIG_BUFFER_SIZE);
}
ptr++;
} else
strmcat(buffer, format, BIG_BUFFER_SIZE);
format = ptr;
}
malloc_strcpy(&ptr, buffer);
return (ptr);
}
static char *convert_format(char *format, int k)
{
char buffer[BIG_BUFFER_SIZE + 1];
char *ptr;
int *cp;
int doit = 1;
memset(buffer, 0, sizeof(buffer));
while (format) {
if ((ptr = (char *) strchr(format, '%')) != NULL) {
*ptr = (char) 0;
strmcat(buffer, format, BIG_BUFFER_SIZE);
*(ptr++) = '%';
cp = &func_cnt[k];
if (*cp < MAX_FUNCTIONS) {
switch (*(ptr++)) {
case '&':
new_free(&dcccount_format);
status_func[k][(*cp)++] = status_dcccount;
dcccount_format = convert_sub_format(get_string_var(STATUS_DCCCOUNT_VAR), '&');
break;
case '%':
strmcat(buffer, "%", BIG_BUFFER_SIZE);
doit = 0;
break;
case '>':
status_func[k][(*cp)++] = status_right_justify;
break;
case '^':
new_free(&msgcount_format);
msgcount_format = convert_sub_format(get_string_var(STATUS_MSGCOUNT_VAR), '^');
strmcat(buffer, "%s", BIG_BUFFER_SIZE);
status_func[k][(*cp)++] = status_msgcount;
break;
case '@':
status_func[k][(*cp)++] = status_chanop;
break;
case '+':
new_free(&mode_format);
mode_format = convert_sub_format(get_string_var(STATUS_MODE_VAR), '+');
status_func[k][(*cp)++] = status_mode;
break;
case '-':
new_free(&topic_format);
topic_format = convert_sub_format(get_string_var(STATUS_TOPIC_VAR), '-');
status_func[k][(*cp)++] = status_topic;
break;
case 'L':
new_free(&umode_format);
umode_format = convert_sub_format(get_string_var(STATUS_UMODE_VAR), '#');
status_func[k][(*cp)++] = status_umode;
break;
case '=':
status_func[k][(*cp)++] = status_voice;
break;
case '*':
status_func[k][(*cp)++] = status_oper;
break;
case 'A':
status_func[k][(*cp)++] = status_away;
break;
case 'B':
new_free(&hold_lines_format);
hold_lines_format = convert_sub_format(get_string_var(STATUS_HOLD_LINES_VAR), 'B');
status_func[k][(*cp)++] = status_hold_lines;
break;
case 'C':
new_free(&channel_format);
channel_format = convert_sub_format(get_string_var(STATUS_CHANNEL_VAR), 'C');
status_func[k][(*cp)++] = status_channel;
break;
case 'D':
status_func[k][(*cp)++] = status_dcc;
break;
case 'E':
break;
case 'F':
new_free(¬ify_format);
notify_format = convert_sub_format(get_string_var(STATUS_NOTIFY_VAR), 'F');
status_func[k][(*cp)++] = status_notify_windows;
break;
case 'G':
break;
case 'H':
status_func[k][(*cp)++] = status_hold;
break;
case 'I':
status_func[k][(*cp)++] = status_insert_mode;
break;
case '#':
new_free(&status_lag_format);
status_lag_format = convert_sub_format(get_string_var(STATUS_LAG_VAR), 'L');
status_func[k][(*cp)++] = status_lag;
break;
case 'N':
status_func[k][(*cp)++] = status_nickname;
break;
case 'O':
status_func[k][(*cp)++] = status_overwrite_mode;
break;
case 'P':
status_func[k][(*cp)++] = status_position;
break;
case 'Q':
new_free(&query_format);
query_format = convert_sub_format(get_string_var(STATUS_QUERY_VAR), 'Q');
status_func[k][(*cp)++] = status_query_nick;
break;
case 'R':
status_func[k][(*cp)++] = status_refnum;
break;
case 'S':
new_free(&server_format);
server_format = convert_sub_format(get_string_var(STATUS_SERVER_VAR), 'S');
status_func[k][(*cp)++] = status_server;
break;
case 'T':
new_free(&clock_format);
clock_format = convert_sub_format(get_string_var(STATUS_CLOCK_VAR), 'T');
status_func[k][(*cp)++] = status_clock;
break;
case 'V':
status_func[k][(*cp)++] = status_version;
break;
case 'W':
status_func[k][(*cp)++] = status_window;
break;
}
if (doit)
strmcat(buffer, "%s", BIG_BUFFER_SIZE);
else
doit = 1;
} else
ptr++;
} else
strmcat(buffer, format, BIG_BUFFER_SIZE);
format = ptr;
}
return m_strdup(buffer);
}
char *alias_special_char(char **, char *, char *, char *, int *);
static void fix_status_buffer(char *buffer, int ansi)
{
char rhs_buffer[3 * BIG_BUFFER_SIZE + 1];
int in_rhs = 0, ch_lhs = 0, ch_rhs = 0, pr_lhs = 0, pr_rhs = 0, start_rhs = -1, i;
int len = 0;
if (ansi)
len = count_ansi(buffer, -1);
/*
* Count out the characters.
* Walk the entire string, looking for nonprintable
* characters. We count all the printable characters
* on both sides of the %> tag.
*/
for (i = 0; buffer[i]; i++) {
/*
* The FIRST such %> tag is used.
* Using multiple %>s is bogus.
*/
if (buffer[i] == '\f' && start_rhs == -1) {
start_rhs = i;
in_rhs = 1;
}
/*
* Is it NOT a printable character?
*/
else if (buffer[i] == REV_TOG ||
buffer[i] == UND_TOG || buffer[i] == ALL_OFF || buffer[i] == BOLD_TOG || (ansi && vt100_decode(buffer[i]))) {
if (!in_rhs)
ch_lhs++;
else
ch_rhs++;
}
/*
* So it is a printable character.
*/
else {
if (!in_rhs)
ch_lhs++, pr_lhs++;
else
ch_rhs++, pr_rhs++;
}
/*
* Dont allow more than CO printable characters
*/
if (pr_lhs + pr_rhs >= term_cols + len) {
buffer[i] = 0;
break;
}
}
/*
* Now if we have a rhs, then we have to adjust it.
*/
if (start_rhs != -1) {
strcpy(rhs_buffer, buffer + start_rhs + 1);
/*
* now we put it back.
*/
if (pr_lhs + pr_rhs < term_cols)
sprintf(buffer + start_rhs, "%*s%s", term_cols - 1 - pr_lhs - pr_rhs, empty_str, rhs_buffer);
else
strcpy(buffer + start_rhs, rhs_buffer);
} else {
int chars = term_cols - pr_lhs - 1;
int count;
char c;
if (get_int_var(STATUS_NO_REPEAT_VAR))
c = ' ';
else
c = buffer[ch_lhs - 1];
for (count = 0; count <= chars; count++)
buffer[ch_lhs + count] = c;
buffer[ch_lhs + chars] = 0;
}
}
void build_status(Window * win, char *format, int unused)
{
int i, k;
char *f = NULL;
if (!win)
return;
for (k = 0; k < 2; k++) {
new_free(&(status_format[k]));
func_cnt[k] = 0;
for (i = 0; i < MAX_FUNCTIONS; i++)
status_func[k][i] = status_null_function;
switch (k) {
case 0:
f = get_string_var(STATUS_FORMAT_VAR);
break;
case 1:
f = get_string_var(STATUS_FORMAT2_VAR);
break;
}
if (f)
status_format[k] = convert_format(f, k);
for (i = func_cnt[k]; i < MAX_FUNCTIONS; i++)
status_func[k][i] = status_null_function;
}
update_all_status(win, NULL, 0);
}
void make_status(Window * win)
{
char buffer[3 * BIG_BUFFER_SIZE + 1];
char *func_value[MAX_FUNCTIONS + 10] = { NULL };
char **output;
int len = 1, status_line, ansi = get_int_var(DISPLAY_ANSI_VAR);
/* The second status line is only displayed in the bottom window and should always be displayed, no matter what SHOW_STATUS_ALL is
* set to - krys */
for (status_line = 0; status_line < win->w_status_size; status_line++) {
int position = 0;
int line = status_line, i;
if (!status_format[line])
continue;
for (i = 0; i < MAX_FUNCTIONS; i++)
func_value[i] = (status_func[line][i]) (win);
len = 1;
if (get_int_var(REVERSE_STATUS_VAR))
buffer[0] = get_int_var(REVERSE_STATUS_VAR) ? REV_TOG : ' ';
else
len = 0;
snprintf(buffer + len, BIG_BUFFER_SIZE * 3,
status_format[line],
func_value[0], func_value[1], func_value[2],
func_value[3], func_value[4], func_value[5],
func_value[6], func_value[7], func_value[8],
func_value[9], func_value[10], func_value[11],
func_value[12], func_value[13], func_value[14],
func_value[15], func_value[16], func_value[17],
func_value[18], func_value[19], func_value[20],
func_value[21], func_value[22], func_value[23],
func_value[24], func_value[25], func_value[26],
func_value[27], func_value[28], func_value[29],
func_value[30], func_value[31], func_value[32],
func_value[33], func_value[34], func_value[35], func_value[36], func_value[37], func_value[38]);
/* Patched 26-Mar-93 by Aiken make_window now right-justifies everything after a %> it's also more efficient. */
fix_status_buffer(buffer, ansi);
output = split_up_line(buffer);
if (!win->status_line[status_line] || strcmp(output[0], win->status_line[status_line]))
{
Screen *old_current_screen;
char *st = NULL;
malloc_strcpy(&win->status_line[status_line], buffer);
old_current_screen = current_screen;
set_current_screen(win->screen);
if (ansi)
st = cparse((line == 1) ? FORMAT_STATUS2_FSET : FORMAT_STATUS_FSET, output[0]);
term_move_cursor(position, win->bottom + status_line);
output_line(st ? st : output[0]);
cursor_in_display();
set_current_screen(old_current_screen);
}
}
cursor_to_input();
}
static char *status_nickname(Window * window)
{
if ((connected_to_server) && !get_int_var(SHOW_STATUS_ALL_VAR)
&& (!window->current_channel) && (window->screen->current_window != window))
return empty_str;
else
return (get_server_nickname(window->server));
}
static char *status_server(Window * window)
{
char *name;
static char my_buffer[MY_BUFFER + 1] = "\0";
if (connected_to_server) {
if (window->server != -1) {
if (server_format) {
name = get_server_name(window->server);
snprintf(my_buffer, MY_BUFFER, server_format, name);
} else
*my_buffer = 0;
} else
strcpy(my_buffer, " No Server");
} else
*my_buffer = 0;
return (my_buffer);
}
static char *status_query_nick(Window * window)
{
static char my_buffer[MY_BUFFER + 1] = "\0";
if (window->query_nick && query_format) {
snprintf(my_buffer, MY_BUFFER, query_format, window->query_nick);
return my_buffer;
} else
return (empty_str);
}
static char *status_right_justify(Window * window)
{
static char my_buffer[] = "\f";
return (my_buffer);
}
static char *status_notify_windows(Window * window)
{
int doneone = 0;
char buf2[MY_BUFFER + 2];
static char my_buffer[MY_BUFFER + 1] = "\0";
Window *old_window;
if (get_int_var(SHOW_STATUS_ALL_VAR) || window == window->screen->current_window) {
old_window = window;
*buf2 = '\0';
#ifdef NEW_NOTIFY
strcat(buf2, "[");
#endif
window = NULL;
while (traverse_all_windows(&window)) {
#ifdef NEW_NOTIFY
doneone++;
if (window->visible)
strmcat(buf2, "*", MY_BUFFER);
else if (window->miscflags & WINDOW_NOTIFIED) {
if (who_level & window->notify_level) {
strmcat(buf2, "%G", MY_BUFFER);
strmcat(buf2, ltoa(window->refnum), MY_BUFFER);
} else {
strmcat(buf2, "%R", MY_BUFFER);
strmcat(buf2, ltoa(window->refnum), MY_BUFFER);
}
} else
strmcat(buf2, ltoa(window->refnum), MY_BUFFER);
#else
if (window->miscflags & WINDOW_NOTIFIED) {
if (doneone++)
strmcat(buf2, ",", MY_BUFFER);
strmcat(buf2, ltoa(window->refnum), MY_BUFFER);
}
#endif
}
window = old_window;
}
#ifdef NEW_NOTIFY
strmcat(buf2, "]", MY_BUFFER);
#endif
if (doneone && notify_format) {
#ifdef NEW_NOTIFY
char *p;
p = convert_output_format(buf2, NULL, NULL);
chop(p, 4);
snprintf(my_buffer, MY_BUFFER, notify_format, p);
#else
snprintf(my_buffer, MY_BUFFER, notify_format, buf2);
#endif
return (my_buffer);
}
return empty_str;
}
static char *status_clock(Window * window)
{
static char my_buf[MY_BUFFER + 1] = "\0";
if ((get_int_var(CLOCK_VAR) && clock_format) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window == window->screen->current_window)))
snprintf(my_buf, MY_BUFFER, clock_format, update_clock(GET_TIME));
else
*my_buf = 0;
return (my_buf);
}
static char *status_mode(Window * window)
{
char *mode = NULL;
static char my_buffer[MY_BUFFER + 1] = "\0";
if (window->current_channel) {
mode = get_channel_mode(window->current_channel, window->server);
if (mode && *mode && mode_format)
snprintf(my_buffer, MY_BUFFER, mode_format, mode);
else
*my_buffer = 0;
} else
*my_buffer = 0;
return (my_buffer);
}
static char *status_umode(Window * window)
{
char localbuf[MY_BUFFER + 1];
static char my_buffer[MY_BUFFER + 1] = "\0";
if ((connected_to_server) && !get_int_var(SHOW_STATUS_ALL_VAR)
&& (window->screen->current_window != window))
*localbuf = 0;
else {
if (window->server >= 0)
strmcpy(localbuf, get_umode(window->server), MY_BUFFER);
else
*localbuf = 0;
}
if (*localbuf != '\0' && umode_format)
snprintf(my_buffer, MY_BUFFER, umode_format, localbuf);
else
*my_buffer = 0;
return (my_buffer);
}
static char *status_chanop(Window * window)
{
char *text;
if (window->current_channel && get_channel_oper(window->current_channel, window->server) &&
(text = get_string_var(STATUS_CHANOP_VAR)))
return (text);
else
return (empty_str);
}
static char *status_hold_lines(Window * window)
{
int num;
static char my_buffer[MY_BUFFER + 1] = "\0";
if ((num = (window->lines_held / 10) * 10)) {
snprintf(my_buffer, MY_BUFFER, hold_lines_format, ltoa(num));
return (my_buffer);
} else
return (empty_str);
}
static char *status_msgcount(Window * window)
{
static char my_buffer[MY_BUFFER + 1] = "\0";
if (get_int_var(MSGCOUNT_VAR) && msgcount_format) {
snprintf(my_buffer, MY_BUFFER, msgcount_format, ltoa(get_int_var(MSGCOUNT_VAR)));
return (my_buffer);
} else
return (empty_str);
}
static char *status_channel(Window * window)
{
char channel[IRCD_BUFFER_SIZE + 1];
static char my_buffer[IRCD_BUFFER_SIZE + 1] = "\0";
if (window->current_channel /* && chan_is_connected(s, window->server) */ ) {
int num;
if (get_int_var(HIDE_PRIVATE_CHANNELS_VAR) &&
is_channel_mode(window->current_channel, MODE_PRIVATE | MODE_SECRET, window->server))
strmcpy(channel, "*private*", IRCD_BUFFER_SIZE);
else
strmcpy(channel, window->current_channel, IRCD_BUFFER_SIZE);
if ((num = get_int_var(CHANNEL_NAME_WIDTH_VAR)) && ((int) strlen(channel) > num))
channel[num] = (char) 0;
snprintf(my_buffer, IRCD_BUFFER_SIZE, channel_format, channel);
return (my_buffer);
}
return (empty_str);
}
static char *status_insert_mode(Window * window)
{
char *text;
if (get_int_var(INSERT_MODE_VAR) && (get_int_var(SHOW_STATUS_ALL_VAR)
|| (window->screen->current_window == window)))
if ((text = get_string_var(STATUS_INSERT_VAR)))
return text;
return (empty_str);
}
static char *status_overwrite_mode(Window * window)
{
char *text;
if (!get_int_var(INSERT_MODE_VAR) && (get_int_var(SHOW_STATUS_ALL_VAR)
|| (window->screen->current_window == window))) {
if ((text = get_string_var(STATUS_OVERWRITE_VAR)))
return text;
}
return (empty_str);
}
static char *status_away(Window * window)
{
char *text;
if (window && connected_to_server && !get_int_var(SHOW_STATUS_ALL_VAR)
&& (window->screen->current_window != window))
return empty_str;
else if (window) {
if (window->server != -1 && server_list[window->server].away && (text = get_string_var(STATUS_AWAY_VAR)))
return text;
else
return empty_str;
}
return empty_str;
}
static char *status_hold(Window * window)
{
char *text;
if (window->holding_something && (text = get_string_var(STATUS_HOLD_VAR)))
return (text);
return (empty_str);
}
static char *status_lag(Window * window)
{
static char my_buffer[MY_BUFFER + 1] = "\0";
char *p = NULL;
if ((window->server > -1) && status_lag_format) {
if (get_server_lag(window->server) > -1) {
p = m_sprintf("%2d", get_server_lag(window->server));
snprintf(my_buffer, MY_BUFFER, status_lag_format, p);
new_free(&p);
} else
snprintf(my_buffer, MY_BUFFER, status_lag_format, "??");
return (my_buffer);
}
return empty_str;
}
static char *status_topic(Window * window)
{
static char my_buffer[MY_BUFFER + 1] = "\0";
char tmp_buffer[MY_BUFFER + 1];
struct channel *chan;
if (window && window->current_channel && topic_format) {
if ((chan = lookup_channel(window->current_channel, window->server, 0))) {
strmcpy(tmp_buffer, chan->topic ? chan->topic : "No Topic", MY_BUFFER - strlen(topic_format));
snprintf(my_buffer, MY_BUFFER, topic_format, stripansicodes(tmp_buffer));
return (my_buffer);
}
}
return empty_str;
}
static char *status_oper(Window * window)
{
char *text;
if (get_server_operator(window->server) &&
(text = get_string_var(STATUS_OPER_VAR)) &&
(get_int_var(SHOW_STATUS_ALL_VAR) || connected_to_server || (window->screen->current_window == window)))
return (text);
return (empty_str);
}
static char *status_voice(Window * window)
{
char *text;
if (window->current_channel &&
get_channel_voice(window->current_channel, window->server) &&
!get_channel_oper(window->current_channel, window->server) && (text = get_string_var(STATUS_VOICE_VAR)))
return text;
return empty_str;
}
static char *status_window(Window * window)
{
char *text;
if ((text = get_string_var(STATUS_WINDOW_VAR)) && (number_of_windows() > 1) && (window->screen->current_window == window))
return (text);
return (empty_str);
}
static char *status_refnum(Window * window)
{
static char my_buffer[MY_BUFFER + 1];
strcpy(my_buffer, window->name ? window->name : ltoa(window->refnum));
return (my_buffer);
}
static char *status_version(Window * window)
{
if ((connected_to_server) && !get_int_var(SHOW_STATUS_ALL_VAR)
&& (window->screen->current_window != window))
return (empty_str);
return ((char *) PACKAGE_VERSION);
}
static char *status_dcccount(Window * window)
{
static char my_buffer[MY_BUFFER + 1];
if (dcccount_format) {
char tmp[30];
strcpy(tmp, ltoa(send_count_stat));
snprintf(my_buffer, MY_BUFFER, dcccount_format, ltoa(get_count_stat), tmp);
return my_buffer;
}
return empty_str;
}
static char *status_null_function(Window * window)
{
return empty_str;
}
static char *status_dcc(Window * window)
{
return DCC_get_current_transfer();
}
static char *status_position(Window * window)
{
static char my_buffer[81];
snprintf(my_buffer, 80, "(%d-%d)", window->lines_scrolled_back, window->distance_from_display);
return my_buffer;
}
syntax highlighted by Code2HTML, v. 0.9.1