1
0
mirror of https://github.com/Tha14/toxic.git synced 2025-06-28 00:06:45 +02:00

Compare commits

..

8 Commits

Author SHA1 Message Date
8fa3f6fd8c Greatly reduce redundant window refreshing
This should substantially reduce CPU usage and possibly fix some
issues with interface jittering/flashing
2021-11-19 15:03:08 -05:00
13337041ce Show friend connection type (UDP/TCP) in friend status bar 2021-11-10 13:27:11 -05:00
41e93adbdb game_chess.c: always use "%s"-style format for printf()-style functions
`ncuses-6.3` added printf-style function attributes and now makes
it easier to catch cases when user input is used in palce of format
string when built with CFLAGS=-Werror=format-security:

    toxic/src/game_chess.c:1633:63: error:
      format not a string literal and no format arguments [-Werror=format-security]
     1633 |         mvwprintw(win, board->y_bottom_bound + 2, x_mid, state->status_message);
          |                                                          ~~~~~^~~~~~~~~~~~~~~~

Let's wrap all the missing places with "%s" format.
2021-11-04 09:44:33 +00:00
34b7c0a0d8 Options parsing code cleanup 2021-11-03 16:23:38 -04:00
bcdec5d624 Improve installation instructions 2021-09-12 16:58:28 +02:00
9e353443c2 Fix outdated help message 2021-08-16 11:14:09 -04:00
d02f3b4acb Fix a graphical bug with the game border on some terminal emulators 2021-07-27 14:15:36 -04:00
f2b1c81279 Fix static build script and update libcurl version 2021-06-28 23:07:03 -04:00
13 changed files with 174 additions and 82 deletions

View File

@ -10,7 +10,7 @@
## Dependencies ## Dependencies
| Name | Needed by | Debian package | | Name | Needed by | Debian package |
|------------------------------------------------------|----------------------------|---------------------| |------------------------------------------------------|----------------------------|---------------------|
| [Tox Core](https://github.com/toktok/c-toxcore) | BASE | *None* | | [Tox Core](https://github.com/toktok/c-toxcore) | BASE | libtoxcore-dev |
| [NCurses](https://www.gnu.org/software/ncurses) | BASE | libncursesw5-dev | | [NCurses](https://www.gnu.org/software/ncurses) | BASE | libncursesw5-dev |
| [LibConfig](http://www.hyperrealm.com/libconfig) | BASE | libconfig-dev | | [LibConfig](http://www.hyperrealm.com/libconfig) | BASE | libconfig-dev |
| [GNUmake](https://www.gnu.org/software/make) | BASE | make | | [GNUmake](https://www.gnu.org/software/make) | BASE | make |
@ -55,8 +55,8 @@ Run `make doc` in the build directory after editing the asciidoc files to regene
* `DISABLE_X11=1` → Disable X11 support (needed for focus tracking) * `DISABLE_X11=1` → Disable X11 support (needed for focus tracking)
* `DISABLE_AV=1` → Disable audio call support * `DISABLE_AV=1` → Disable audio call support
* `DISABLE_SOUND_NOTIFY=1` → Disable sound notifications support * `DISABLE_SOUND_NOTIFY=1` → Disable sound notifications support
* `DISABLE_QRCODE` → Disable QR exporting support * `DISABLE_QRCODE=1` → Disable QR exporting support
* `DISABLE_QRPNG` → Disable support for exporting QR as PNG * `DISABLE_QRPNG=1` → Disable support for exporting QR as PNG
* `DISABLE_DESKTOP_NOTIFY=1` → Disable desktop notifications support * `DISABLE_DESKTOP_NOTIFY=1` → Disable desktop notifications support
* `DISABLE_GAMES=1` → Disable support for games * `DISABLE_GAMES=1` → Disable support for games
* `ENABLE_PYTHON=1` → Build toxic with Python scripting support * `ENABLE_PYTHON=1` → Build toxic with Python scripting support

View File

@ -131,11 +131,15 @@ mkdir -p "$BUILD_DIR"
# Build Toxcore # Build Toxcore
cd "$BUILD_DIR" cd "$BUILD_DIR"
# The git hash of the c-toxcore version we're using
TOXCORE_VERSION="25a56c354937e9c8c4c50a64c3b4cfc099c34e29" TOXCORE_VERSION="25a56c354937e9c8c4c50a64c3b4cfc099c34e29"
TOXCORE_HASH="78749dccfd2e6ec95d59d7a07c882aa034754a9ff62113b95281927e71b42574"
# The sha256sum of the c-toxcore tarball for TOXCORE_VERSION
TOXCORE_HASH="8448752e6286c747130254571fde2db8e2fc073a8116f9fff489ed53af546c0a"
TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.tar.gz" TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.tar.gz"
wget --timeout=10 -O "$TOXCORE_FILENAME" "https://github.com/TokTok/c-toxcore/archive/master.tar.gz" wget --timeout=10 -O "$TOXCORE_FILENAME" "https://github.com/TokTok/c-toxcore/archive/$TOXCORE_VERSION.tar.gz"
check_sha256 "$TOXCORE_HASH" "$TOXCORE_FILENAME" check_sha256 "$TOXCORE_HASH" "$TOXCORE_FILENAME"
tar -o -xf "$TOXCORE_FILENAME" tar -o -xf "$TOXCORE_FILENAME"
rm "$TOXCORE_FILENAME" rm "$TOXCORE_FILENAME"
@ -160,8 +164,8 @@ cmake --build _build --target install
# location with SSL_CERT_FILE env variable. # location with SSL_CERT_FILE env variable.
cd "$BUILD_DIR" cd "$BUILD_DIR"
CURL_VERSION="7.74.0" CURL_VERSION="7.77.0"
CURL_HASH="e56b3921eeb7a2951959c02db0912b5fcd5fdba5aca071da819e1accf338bbd7" CURL_HASH="b0a3428acb60fa59044c4d0baae4e4fc09ae9af1d8a3aa84b2e3fbcd99841f77"
CURL_FILENAME="curl-$CURL_VERSION.tar.gz" CURL_FILENAME="curl-$CURL_VERSION.tar.gz"
wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME" wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME"
@ -178,7 +182,8 @@ cd curl*
--without-ca-path \ --without-ca-path \
--with-ca-fallback \ --with-ca-fallback \
--with-nghttp2 \ --with-nghttp2 \
--with-brotli --with-brotli \
--with-openssl
make make
make install make install
sed -i 's|-lbrotlidec |-lbrotlidec-static -lbrotlicommon-static |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc sed -i 's|-lbrotlidec |-lbrotlidec-static -lbrotlicommon-static |g' $BUILD_DIR/prefix-curl/lib/pkgconfig/libcurl.pc

View File

@ -1072,13 +1072,12 @@ static void draw_infobox(ToxWindow *self)
time_t curtime = get_unix_time(); time_t curtime = get_unix_time();
/* update elapsed time string once per second */ /* update interface once per second */
if (curtime > infobox->lastupdate) { if (timed_out(infobox->lastupdate, 1)) {
get_elapsed_time_str(infobox->timestr, sizeof(infobox->timestr), curtime - infobox->starttime); get_elapsed_time_str(infobox->timestr, sizeof(infobox->timestr), curtime - infobox->starttime);
infobox->lastupdate = curtime;
} }
infobox->lastupdate = curtime;
const char *in_is_muted = infobox->in_is_muted ? "yes" : "no"; const char *in_is_muted = infobox->in_is_muted ? "yes" : "no";
const char *out_is_muted = infobox->out_is_muted ? "yes" : "no"; const char *out_is_muted = infobox->out_is_muted ? "yes" : "no";
@ -1307,12 +1306,14 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
break; break;
} }
const char *connection_status_s = statusbar->connection == TOX_CONNECTION_TCP ? "TCP" : "UDP";
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, " ["); wprintw(statusbar->topline, " [");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
wprintw(statusbar->topline, "%s", ONLINE_CHAR); wprintw(statusbar->topline, "%s", connection_status_s);
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
@ -1342,7 +1343,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT)); wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wprintw(statusbar->topline, "%s", OFFLINE_CHAR); wprintw(statusbar->topline, "Offline");
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT)); wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT)); wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));

View File

@ -540,20 +540,20 @@ static void game_draw_border(const GameData *game, const int max_x, const int ma
const int x = (max_x - game_max_x) / 2; const int x = (max_x - game_max_x) / 2;
const int y = (max_y - game_max_y) / 2; const int y = (max_y - game_max_y) / 2;
wattron(win, A_BOLD | COLOR_PAIR(GAME_BORDER_COLOUR)); wattron(win, COLOR_PAIR(GAME_BORDER_COLOUR));
mvwaddch(win, y, x, ' '); mvwaddch(win, y, x, ACS_ULCORNER);
mvwhline(win, y, x + 1, ' ', game_max_x - 1); mvwhline(win, y, x + 1, ACS_HLINE, game_max_x - 1);
mvwvline(win, y + 1, x, ' ', game_max_y - 1); mvwvline(win, y + 1, x, ACS_VLINE, game_max_y - 1);
mvwvline(win, y, x - 1, ' ', game_max_y + 1); mvwvline(win, y, x - 1, ACS_VLINE, game_max_y + 1);
mvwaddch(win, y, x + game_max_x, ' '); mvwaddch(win, y, x + game_max_x, ACS_URCORNER);
mvwvline(win, y + 1, x + game_max_x, ' ', game_max_y - 1); mvwvline(win, y + 1, x + game_max_x, ACS_VLINE, game_max_y - 1);
mvwvline(win, y, x + game_max_x + 1, ' ', game_max_y + 1); mvwvline(win, y, x + game_max_x + 1, ACS_VLINE, game_max_y + 1);
mvwaddch(win, y + game_max_y, x, ' '); mvwaddch(win, y + game_max_y, x, ACS_LLCORNER);
mvwhline(win, y + game_max_y, x + 1, ' ', game_max_x - 1); mvwhline(win, y + game_max_y, x + 1, ACS_HLINE, game_max_x - 1);
mvwaddch(win, y + game_max_y, x + game_max_x, ' '); mvwaddch(win, y + game_max_y, x + game_max_x, ACS_LRCORNER);
wattroff(win, A_BOLD | COLOR_PAIR(GAME_BORDER_COLOUR)); wattroff(win, COLOR_PAIR(GAME_BORDER_COLOUR));
} }
static void game_draw_status(const GameData *game, const int max_x, const int max_y) static void game_draw_status(const GameData *game, const int max_x, const int max_y)
@ -561,7 +561,7 @@ static void game_draw_status(const GameData *game, const int max_x, const int ma
WINDOW *win = game->window; WINDOW *win = game->window;
int x = ((max_x - game->game_max_x) / 2) - 1; int x = ((max_x - game->game_max_x) / 2) - 1;
int y = ((max_y - game->game_max_y) / 2) - 1; const int y = ((max_y - game->game_max_y) / 2) - 1;
wattron(win, A_BOLD); wattron(win, A_BOLD);

View File

@ -31,7 +31,7 @@
#include "game_util.h" #include "game_util.h"
#include "windows.h" #include "windows.h"
#define GAME_BORDER_COLOUR BAR_TEXT #define GAME_BORDER_COLOUR BAR_SOLID
/* Max size of a default square game window */ /* Max size of a default square game window */

View File

@ -1626,11 +1626,11 @@ static void chess_print_status(WINDOW *win, ChessState *state)
} }
int x_mid = (board->x_left_bound + (CHESS_TILE_SIZE_X * (CHESS_BOARD_COLUMNS / 2))) - (strlen(message) / 2); int x_mid = (board->x_left_bound + (CHESS_TILE_SIZE_X * (CHESS_BOARD_COLUMNS / 2))) - (strlen(message) / 2);
mvwprintw(win, board->y_top_bound - 2, x_mid, message); mvwprintw(win, board->y_top_bound - 2, x_mid, "%s", message);
if (state->message_length > 0) { if (state->message_length > 0) {
x_mid = (board->x_left_bound + (CHESS_TILE_SIZE_X * (CHESS_BOARD_COLUMNS / 2))) - (state->message_length / 2); x_mid = (board->x_left_bound + (CHESS_TILE_SIZE_X * (CHESS_BOARD_COLUMNS / 2))) - (state->message_length / 2);
mvwprintw(win, board->y_bottom_bound + 2, x_mid, state->status_message); mvwprintw(win, board->y_bottom_bound + 2, x_mid, "%s", state->status_message);
} }
wattroff(win, A_BOLD); wattroff(win, A_BOLD);

View File

@ -174,7 +174,7 @@ static void help_draw_global(ToxWindow *self)
wprintw(win, " /decline <id> : Decline friend request\n"); wprintw(win, " /decline <id> : Decline friend request\n");
wprintw(win, " /requests : List pending friend requests\n"); wprintw(win, " /requests : List pending friend requests\n");
wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n"); wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n");
wprintw(win, " /status <type> <msg> : Set status with optional note\n"); wprintw(win, " /status <type> : Set status (Online, Busy, Away)\n");
wprintw(win, " /note <msg> : Set a personal note\n"); wprintw(win, " /note <msg> : Set a personal note\n");
wprintw(win, " /nick <nick> : Set your nickname\n"); wprintw(win, " /nick <nick> : Set your nickname\n");
wprintw(win, " /nospam <value> : Change part of your Tox ID to stop spam\n"); wprintw(win, " /nospam <value> : Change part of your Tox ID to stop spam\n");

View File

@ -346,5 +346,9 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int mx_x)
} }
} }
if (match) {
flag_interface_change(1);
}
return match; return match;
} }

View File

@ -444,6 +444,8 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
hst->queue[hst->queue_size++] = new_line; hst->queue[hst->queue_size++] = new_line;
flag_interface_change(1);
return new_line->id; return new_line->id;
} }
@ -454,6 +456,7 @@ static void line_info_check_queue(ToxWindow *self)
struct line_info *line = line_info_ret_queue(hst); struct line_info *line = line_info_ret_queue(hst);
if (line == NULL) { if (line == NULL) {
flag_interface_change(0);
return; return;
} }
@ -469,6 +472,8 @@ static void line_info_check_queue(ToxWindow *self)
if (!self->scroll_pause) { if (!self->scroll_pause) {
line_info_reset_start(self, hst); line_info_reset_start(self, hst);
} }
flag_interface_change(1);
} }
#define NOREAD_FLAG_TIMEOUT 5 /* seconds before a sent message with no read receipt is flagged as unread */ #define NOREAD_FLAG_TIMEOUT 5 /* seconds before a sent message with no read receipt is flagged as unread */
@ -763,6 +768,8 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg)
line = line->prev; line = line->prev;
} }
flag_interface_change(1);
} }
static void line_info_scroll_up(ToxWindow *self, struct history *hst) static void line_info_scroll_up(ToxWindow *self, struct history *hst)
@ -771,6 +778,8 @@ static void line_info_scroll_up(ToxWindow *self, struct history *hst)
hst->line_start = hst->line_start->prev; hst->line_start = hst->line_start->prev;
self->scroll_pause = true; self->scroll_pause = true;
} }
flag_interface_change(1);
} }
static void line_info_scroll_down(ToxWindow *self, struct history *hst) static void line_info_scroll_down(ToxWindow *self, struct history *hst)
@ -786,6 +795,8 @@ static void line_info_scroll_down(ToxWindow *self, struct history *hst)
} else { } else {
line_info_reset_start(self, hst); line_info_reset_start(self, hst);
} }
flag_interface_change(1);
} }
static void line_info_page_up(ToxWindow *self, struct history *hst) static void line_info_page_up(ToxWindow *self, struct history *hst)
@ -805,6 +816,8 @@ static void line_info_page_up(ToxWindow *self, struct history *hst)
} }
self->scroll_pause = true; self->scroll_pause = true;
flag_interface_change(1);
} }
static void line_info_page_down(ToxWindow *self, struct history *hst) static void line_info_page_down(ToxWindow *self, struct history *hst)
@ -834,6 +847,8 @@ static void line_info_page_down(ToxWindow *self, struct history *hst)
hst->line_start = next; hst->line_start = next;
next = hst->line_start->next; next = hst->line_start->next;
} }
flag_interface_change(1);
} }
bool line_info_onKey(ToxWindow *self, wint_t key) bool line_info_onKey(ToxWindow *self, wint_t key)
@ -855,6 +870,10 @@ bool line_info_onKey(ToxWindow *self, wint_t key)
match = false; match = false;
} }
if (match) {
flag_interface_change(1);
}
return match; return match;
} }
@ -862,4 +881,6 @@ void line_info_clear(struct history *hst)
{ {
hst->line_start = hst->line_end; hst->line_start = hst->line_end;
hst->start_id = hst->line_start->id; hst->start_id = hst->line_start->id;
flag_interface_change(1);
} }

View File

@ -383,6 +383,7 @@ static void init_term(void)
init_pair(BLACK_BG, COLOR_BLACK, bar_bg_color); init_pair(BLACK_BG, COLOR_BLACK, bar_bg_color);
init_pair(PURPLE_BG, COLOR_MAGENTA, bar_bg_color); init_pair(PURPLE_BG, COLOR_MAGENTA, bar_bg_color);
init_pair(BAR_TEXT, bar_fg_color, bar_bg_color); init_pair(BAR_TEXT, bar_fg_color, bar_bg_color);
init_pair(BAR_SOLID, bar_bg_color, bar_bg_color);
init_pair(BAR_ACCENT, bar_accent_color, bar_bg_color); init_pair(BAR_ACCENT, bar_accent_color, bar_bg_color);
init_pair(BAR_NOTIFY, bar_notify_color, bar_bg_color); init_pair(BAR_NOTIFY, bar_notify_color, bar_bg_color);
init_pair(STATUS_ONLINE, COLOR_GREEN, bar_bg_color); init_pair(STATUS_ONLINE, COLOR_GREEN, bar_bg_color);
@ -1071,8 +1072,24 @@ static void do_toxic(Tox *m)
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
} }
/* How often we refresh windows that aren't focused */
#define INACTIVE_WIN_REFRESH_RATE 10 #define INACTIVE_WIN_REFRESH_RATE 10
/* Set interface change flag. This should be called whenever the interface changes.
*
* `flag` should be a non-zero value if we need to redraw the window or 0 if we want to idle.
*/
void flag_interface_change(unsigned int flag)
{
if (flag == 0 && timed_out(Winthread.flag_refresh_timeout, 1)) {
Winthread.flag_refresh = flag;
} else if (flag != 0) {
Winthread.flag_refresh = 1;
}
Winthread.flag_refresh_timeout = get_unix_time();
}
void *thread_winref(void *data) void *thread_winref(void *data)
{ {
Tox *m = (Tox *) data; Tox *m = (Tox *) data;
@ -1081,8 +1098,8 @@ void *thread_winref(void *data)
init_signal_catchers(); init_signal_catchers();
while (true) { while (true) {
draw_active_window(m);
draw_count++; draw_count++;
draw_active_window(m);
if (Winthread.flag_resize) { if (Winthread.flag_resize) {
on_window_resize(); on_window_resize();
@ -1203,21 +1220,23 @@ static void parse_args(int argc, char *argv[])
}; };
const char *opts_str = "4bdehLotuxvc:f:l:n:r:p:P:T:"; const char *opts_str = "4bdehLotuxvc:f:l:n:r:p:P:T:";
int opt, indexptr; int opt = 0;
long int port = 0; int indexptr = 0;
while ((opt = getopt_long(argc, argv, opts_str, long_opts, &indexptr)) != -1) { while ((opt = getopt_long(argc, argv, opts_str, long_opts, &indexptr)) != -1) {
switch (opt) { switch (opt) {
case '4': case '4': {
arg_opts.use_ipv4 = 1; arg_opts.use_ipv4 = 1;
break; break;
}
case 'b': case 'b': {
arg_opts.debug = 1; arg_opts.debug = 1;
queue_init_message("stderr enabled"); queue_init_message("stderr enabled");
break; break;
}
case 'c': case 'c': {
if (optarg == NULL) { if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt); queue_init_message("Invalid argument for option: %d", opt);
break; break;
@ -1230,17 +1249,20 @@ static void parse_args(int argc, char *argv[])
} }
break; break;
}
case 'd': case 'd': {
arg_opts.default_locale = 1; arg_opts.default_locale = 1;
queue_init_message("Using default POSIX locale"); queue_init_message("Using default POSIX locale");
break; break;
}
case 'e': case 'e': {
arg_opts.encrypt_data = 1; arg_opts.encrypt_data = 1;
break; break;
}
case 'f': case 'f': {
if (optarg == NULL) { if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt); queue_init_message("Invalid argument for option: %d", opt);
break; break;
@ -1278,8 +1300,9 @@ static void parse_args(int argc, char *argv[])
queue_init_message("Using '%s' data file", DATA_FILE); queue_init_message("Using '%s' data file", DATA_FILE);
break; break;
}
case 'l': case 'l': {
if (optarg) { if (optarg) {
arg_opts.logging = true; arg_opts.logging = true;
@ -1299,13 +1322,15 @@ static void parse_args(int argc, char *argv[])
} }
break; break;
}
case 'L': case 'L': {
arg_opts.disable_local_discovery = 1; arg_opts.disable_local_discovery = 1;
queue_init_message("Local discovery disabled"); queue_init_message("Local discovery disabled");
break; break;
}
case 'n': case 'n': {
if (optarg == NULL) { if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt); queue_init_message("Invalid argument for option: %d", opt);
break; break;
@ -1313,48 +1338,38 @@ static void parse_args(int argc, char *argv[])
snprintf(arg_opts.nodes_path, sizeof(arg_opts.nodes_path), "%s", optarg); snprintf(arg_opts.nodes_path, sizeof(arg_opts.nodes_path), "%s", optarg);
break; break;
}
case 'o': case 'o': {
arg_opts.no_connect = 1; arg_opts.no_connect = 1;
queue_init_message("DHT disabled"); queue_init_message("DHT disabled");
break; break;
}
case 'p': case 'p': {
if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt);
break;
}
arg_opts.proxy_type = TOX_PROXY_TYPE_SOCKS5; arg_opts.proxy_type = TOX_PROXY_TYPE_SOCKS5;
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg); }
if (++optind > argc || argv[optind - 1][0] == '-') { // Intentional fallthrough
exit_toxic_err("Proxy error", FATALERR_PROXY);
}
port = strtol(argv[optind - 1], NULL, 10); case 'P': {
if (port <= 0 || port > MAX_PORT_RANGE) {
exit_toxic_err("Proxy error", FATALERR_PROXY);
}
arg_opts.proxy_port = port;
break;
case 'P':
if (optarg == NULL) { if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt); queue_init_message("Invalid argument for option: %d", opt);
arg_opts.proxy_type = TOX_PROXY_TYPE_NONE;
break; break;
} }
arg_opts.proxy_type = TOX_PROXY_TYPE_HTTP; if (arg_opts.proxy_type == TOX_PROXY_TYPE_NONE) {
arg_opts.proxy_type = TOX_PROXY_TYPE_HTTP;
}
snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg); snprintf(arg_opts.proxy_address, sizeof(arg_opts.proxy_address), "%s", optarg);
if (++optind > argc || argv[optind - 1][0] == '-') { if (++optind > argc || argv[optind - 1][0] == '-') {
exit_toxic_err("Proxy error", FATALERR_PROXY); exit_toxic_err("Proxy error", FATALERR_PROXY);
} }
port = strtol(argv[optind - 1], NULL, 10); long int port = strtol(argv[optind - 1], NULL, 10);
if (port <= 0 || port > MAX_PORT_RANGE) { if (port <= 0 || port > MAX_PORT_RANGE) {
exit_toxic_err("Proxy error", FATALERR_PROXY); exit_toxic_err("Proxy error", FATALERR_PROXY);
@ -1362,8 +1377,9 @@ static void parse_args(int argc, char *argv[])
arg_opts.proxy_port = port; arg_opts.proxy_port = port;
break; break;
}
case 'r': case 'r': {
if (optarg == NULL) { if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt); queue_init_message("Invalid argument for option: %d", opt);
break; break;
@ -1376,18 +1392,20 @@ static void parse_args(int argc, char *argv[])
} }
break; break;
}
case 't': case 't': {
arg_opts.force_tcp = 1; arg_opts.force_tcp = 1;
break; break;
}
case 'T': case 'T': {
if (optarg == NULL) { if (optarg == NULL) {
queue_init_message("Invalid argument for option: %d", opt); queue_init_message("Invalid argument for option: %d", opt);
break; break;
} }
port = strtol(optarg, NULL, 10); long int port = strtol(optarg, NULL, 10);
if (port <= 0 || port > MAX_PORT_RANGE) { if (port <= 0 || port > MAX_PORT_RANGE) {
port = MAX_PORT_RANGE; port = MAX_PORT_RANGE;
@ -1395,21 +1413,25 @@ static void parse_args(int argc, char *argv[])
arg_opts.tcp_port = port; arg_opts.tcp_port = port;
break; break;
}
case 'u': case 'u': {
arg_opts.unencrypt_data = 1; arg_opts.unencrypt_data = 1;
break; break;
}
case 'v': case 'v': {
print_version(); print_version();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
}
case 'h': case 'h':
// Intentional fallthrough // Intentional fallthrough
default: default: {
print_usage(); print_usage();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
}
} }
} }
} }
@ -1464,6 +1486,8 @@ int main(int argc, char **argv)
/* Make sure all written files are read/writeable only by the current user. */ /* Make sure all written files are read/writeable only by the current user. */
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
flag_interface_change(1);
srand(time(NULL)); // We use rand() for trivial/non-security related things srand(time(NULL)); // We use rand() for trivial/non-security related things
parse_args(argc, argv); parse_args(argc, argv);

View File

@ -102,6 +102,8 @@ typedef enum _FATAL_ERRS {
void lock_status(void); void lock_status(void);
void unlock_status(void); void unlock_status(void);
void flag_interface_change(unsigned int flag);
void exit_toxic_success(Tox *m); void exit_toxic_success(Tox *m);
void exit_toxic_err(const char *errmsg, int errcode); void exit_toxic_err(const char *errmsg, int errcode);

View File

@ -77,6 +77,8 @@ void on_friend_connection_status(Tox *m, uint32_t friendnumber, Tox_Connection c
windows[i]->onConnectionChange(windows[i], m, friendnumber, connection_status); windows[i]->onConnectionChange(windows[i], m, friendnumber, connection_status);
} }
} }
flag_interface_change(1);
} }
void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata) void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata)
@ -92,6 +94,8 @@ void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userd
windows[i]->onTypingChange(windows[i], m, friendnumber, is_typing); windows[i]->onTypingChange(windows[i], m, friendnumber, is_typing);
} }
} }
flag_interface_change(1);
} }
void on_friend_message(Tox *m, uint32_t friendnumber, Tox_Message_Type type, const uint8_t *string, size_t length, void on_friend_message(Tox *m, uint32_t friendnumber, Tox_Message_Type type, const uint8_t *string, size_t length,
@ -123,6 +127,8 @@ void on_friend_name(Tox *m, uint32_t friendnumber, const uint8_t *string, size_t
} }
} }
flag_interface_change(1);
store_data(m, DATA_FILE); store_data(m, DATA_FILE);
} }
@ -140,6 +146,8 @@ void on_friend_status_message(Tox *m, uint32_t friendnumber, const uint8_t *stri
windows[i]->onStatusMessageChange(windows[i], friendnumber, msg, length); windows[i]->onStatusMessageChange(windows[i], friendnumber, msg, length);
} }
} }
flag_interface_change(1);
} }
void on_friend_status(Tox *m, uint32_t friendnumber, Tox_User_Status status, void *userdata) void on_friend_status(Tox *m, uint32_t friendnumber, Tox_User_Status status, void *userdata)
@ -151,6 +159,8 @@ void on_friend_status(Tox *m, uint32_t friendnumber, Tox_User_Status status, voi
windows[i]->onStatusChange(windows[i], m, friendnumber, status); windows[i]->onStatusChange(windows[i], m, friendnumber, status);
} }
} }
flag_interface_change(1);
} }
void on_friend_added(Tox *m, uint32_t friendnumber, bool sort) void on_friend_added(Tox *m, uint32_t friendnumber, bool sort)
@ -200,6 +210,8 @@ void on_conference_peer_list_changed(Tox *m, uint32_t conferencenumber, void *us
windows[i]->onConferenceNameListChange(windows[i], m, conferencenumber); windows[i]->onConferenceNameListChange(windows[i], m, conferencenumber);
} }
} }
flag_interface_change(1);
} }
void on_conference_peer_name(Tox *m, uint32_t conferencenumber, uint32_t peernumber, const uint8_t *name, void on_conference_peer_name(Tox *m, uint32_t conferencenumber, uint32_t peernumber, const uint8_t *name,
@ -423,11 +435,13 @@ void set_active_window_index(uint8_t index)
*/ */
void set_next_window(int ch) void set_next_window(int ch)
{ {
uint8_t index = 0;
if (ch == user_settings->key_next_tab) { if (ch == user_settings->key_next_tab) {
for (uint8_t i = active_window_index + 1; i < MAX_WINDOWS_NUM; ++i) { for (uint8_t i = active_window_index + 1; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL) { if (windows[i] != NULL) {
set_active_window_index(i); index = i;
return; break;
} }
} }
} else { } else {
@ -435,13 +449,15 @@ void set_next_window(int ch)
for (uint8_t i = start; i > 0; --i) { for (uint8_t i = start; i > 0; --i) {
if (windows[i] != NULL) { if (windows[i] != NULL) {
set_active_window_index(i); index = i;
return; break;
} }
} }
} }
set_active_window_index(0); set_active_window_index(index);
flag_interface_change(1);
} }
/* Deletes window w and cleans up */ /* Deletes window w and cleans up */
@ -784,21 +800,33 @@ void draw_active_window(Tox *m)
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
a->alert = WINDOW_ALERT_NONE; a->alert = WINDOW_ALERT_NONE;
a->pending_messages = 0; a->pending_messages = 0;
bool flag_refresh = Winthread.flag_refresh;
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
touchwin(a->window); if (flag_refresh || (a->is_call && timed_out(a->chatwin->infobox.lastupdate, 1))) {
a->onDraw(a, m); touchwin(a->window);
wrefresh(a->window); a->onDraw(a, m);
wrefresh(a->window);
}
#ifdef GAMES #ifdef GAMES
if (a->type == WINDOW_TYPE_GAME) { if (a->type == WINDOW_TYPE_GAME) {
if (!flag_refresh) { // we always want to be continously refreshing game windows
touchwin(a->window);
a->onDraw(a, m);
wrefresh(a->window);
}
int ch = getch(); int ch = getch();
if (ch == ERR) { if (ch == ERR) {
return; return;
} }
pthread_mutex_lock(&Winthread.lock);
flag_interface_change(1);
pthread_mutex_unlock(&Winthread.lock);
if (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab) { if (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab) {
set_next_window(ch); set_next_window(ch);
} }
@ -817,6 +845,10 @@ void draw_active_window(Tox *m)
return; return;
} }
pthread_mutex_lock(&Winthread.lock);
flag_interface_change(1);
pthread_mutex_unlock(&Winthread.lock);
if (printable == 0 && (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab)) { if (printable == 0 && (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab)) {
set_next_window((int) ch); set_next_window((int) ch);
return; return;

View File

@ -72,6 +72,7 @@ typedef enum {
STATUS_BUSY, STATUS_BUSY,
STATUS_AWAY, STATUS_AWAY,
BAR_NOTIFY, BAR_NOTIFY,
BAR_SOLID,
} C_COLOURS; } C_COLOURS;
/* tab alert types: lower types take priority (this relies on the order of C_COLOURS) */ /* tab alert types: lower types take priority (this relies on the order of C_COLOURS) */
@ -102,6 +103,8 @@ struct Winthread {
pthread_mutex_t lock; pthread_mutex_t lock;
volatile sig_atomic_t sig_exit_toxic; volatile sig_atomic_t sig_exit_toxic;
volatile sig_atomic_t flag_resize; volatile sig_atomic_t flag_resize;
volatile sig_atomic_t flag_refresh;
volatile sig_atomic_t flag_refresh_timeout;
}; };
struct cqueue_thread { struct cqueue_thread {