1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-06-26 20:57:48 +02:00

Compare commits

..

No commits in common. "master" and "v0.11.2" have entirely different histories.

62 changed files with 463 additions and 4899 deletions

View File

@ -1,12 +0,0 @@
---
bazel-opt_task:
container:
image: toxchat/toktok-stack:latest-release
cpu: 2
memory: 2G
configure_script:
- /src/workspace/tools/inject-repo toxic
test_all_script:
- cd /src/workspace && bazel test -k
--remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
//toxic/...

View File

@ -11,9 +11,7 @@ branches:
protection:
required_status_checks:
contexts:
- build
- build-static
- bazel-opt
- Codacy Static Code Analysis
- Codacy/PR Quality Review
- CodeFactor
- Travis CI - Pull Request
- code-review/reviewable
- infer

View File

@ -1,125 +0,0 @@
name: ci
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run:
sudo apt-get update &&
sudo apt-get install -y --no-install-recommends
libalut-dev
libconfig-dev
libcurl4-gnutls-dev
libmsgpack-dev
libnotify-dev
libopenal-dev
libopus-dev
libqrencode-dev
libsodium-dev
libvpx-dev
libx11-dev
python3-dev
pkg-config &&
git clone --depth=1 --recursive https://github.com/TokTok/c-toxcore &&
cd c-toxcore &&
cmake . -B_build -DBOOTSTRAP_DAEMON=OFF &&
cd _build &&
make -j4 &&
sudo make install
- name: Build toxic
run: make -j4
build-static:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Build minimal static toxic binary
run: docker run --rm
-v /tmp/artifact:/artifact
-v $PWD:/toxic
amd64/alpine:latest
sh -c 'yes | /toxic/script/build-minimal-static-toxic.sh'
- name: Display binary checksum
run: |
tar Jxf /tmp/artifact/toxic-minimal-static-musl_linux_x86-64.tar.xz
sha256sum toxic-minimal-static-musl_linux_x86-64/toxic
infer:
runs-on: ubuntu-latest
container: toxchat/infer
steps:
- name: Install git
run:
apt-get update &&
DEBIAN_FRONTEND=noninteractive
apt-get install -y --no-install-recommends
git
- name: Install dependencies
run:
apt-get update &&
apt-get install -y --no-install-recommends
cmake
g++
libalut-dev
libconfig-dev
libcurl4-gnutls-dev
libmsgpack-dev
libncurses-dev
libnotify-dev
libopenal-dev
libopus-dev
libqrencode-dev
libsodium-dev
libvpx-dev
libx11-dev
make
python3-dev
pkg-config &&
git clone --depth=1 --recursive https://github.com/TokTok/c-toxcore &&
cd c-toxcore &&
cmake . -B_build -DBOOTSTRAP_DAEMON=OFF &&
cd _build &&
make -j4 &&
make install
- uses: actions/checkout@v2
- name: Run infer
run:
infer --no-progress-bar -- cc src/*.c
-fsyntax-only
$(python3-config --includes --ldflags)
$(pkg-config --cflags --libs
freealut
libconfig
libcurl
libnotify
libpng
libqrencode
msgpack
ncurses
openal
python3
toxcore
vpx
x11)
-DAUDIO
-DBOX_NOTIFY
-DGAMES
-DPACKAGE_DATADIR='""'
-DPYTHON
-DQRCODE
-DSOUND_NOTIFY
-DVIDEO
- name: Print log
run:
cat /__w/toxic/toxic/infer-out/report.txt

60
.travis.yml Normal file
View File

@ -0,0 +1,60 @@
---
language: python
python: nightly
dist: xenial
os: linux
jobs:
include:
- env: JOB=linux
addons:
apt:
packages:
- libalut-dev
- libconfig-dev
- libnotify-dev
- libopenal-dev
- libopus-dev
- libqrencode-dev
- libvpx-dev
cache:
directories:
- $HOME/cache
install:
# Where to find libraries.
- export LD_LIBRARY_PATH=$HOME/cache/usr/lib
- export PKG_CONFIG_PATH=$HOME/cache/usr/lib/pkgconfig
# c-sodium
- git clone --depth=1 --branch=stable https://github.com/jedisct1/libsodium ../libsodium
- test -f $HOME/cache/usr/lib/libsodium.so || (cd ../libsodium && ./configure --prefix=$HOME/cache/usr && make install -j$(nproc))
# c-toxcore
- git clone --depth=1 https://github.com/TokTok/c-toxcore ../c-toxcore
- test -f $HOME/cache/usr/lib/libtoxcore.so || (cd ../c-toxcore && cmake -B_build -H. -DCMAKE_INSTALL_PREFIX:PATH=$HOME/cache/usr && make -C_build install -j$(nproc))
script:
- make ENABLE_PYTHON=1 -j$(nproc)
- env: JOB=macos
os: macos
language: c
cache:
directories:
- $HOME/cache
install:
- brew install
freealut
libconfig
libqrencode
libsodium
openal-soft
- export LDFLAGS="-L/usr/local/Cellar/openal-soft/1.21.0/lib"
- git clone --depth=1 https://github.com/TokTok/c-toxcore ../c-toxcore
- test -f /usr/local/lib/libtoxcore.dylib || (cd ../c-toxcore && cmake -B_build -H. && make -C_build install -j$(nproc))
script:
- make ENABLE_PYTHON=1 DISABLE_DESKTOP_NOTIFY=1 DISABLE_X11=1 DISABLE_AV=1 DISABLE_SOUND_NOTIFY=1 -j$(nproc)

View File

@ -1,8 +1,6 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("//tools/project:build_defs.bzl", "project")
package(features = ["layering_check"])
project()
cc_binary(
@ -20,8 +18,6 @@ cc_binary(
copts = [
"-std=gnu99",
"-DAUDIO",
"-DGAMES",
"-DHAVE_WIDECHAR",
"-DPACKAGE_DATADIR='\"data\"'",
"-DPYTHON",
"-DQRCODE",
@ -43,10 +39,3 @@ cc_binary(
"//tools/config:osx": [],
}),
)
sh_test(
name = "toxic_test",
size = "small",
srcs = [":toxic"],
args = ["--help"],
)

View File

@ -12,9 +12,9 @@ CFLAGS += ${USER_CFLAGS}
LDFLAGS ?=
LDFLAGS += ${USER_LDFLAGS}
OBJ = autocomplete.o avatars.o bootstrap.o chat.o chat_commands.o conference.o configdir.o curl_util.o execute.o
OBJ += file_transfers.o friendlist.o global_commands.o conference_commands.o groupchats.o groupchat_commands.o help.o
OBJ += input.o line_info.o log.o message_queue.o misc_tools.o name_lookup.o notify.o prompt.o qr_code.o settings.o
OBJ = autocomplete.o avatars.o bootstrap.o chat.o chat_commands.o configdir.o curl_util.o execute.o
OBJ += file_transfers.o friendlist.o global_commands.o conference_commands.o conference.o help.o input.o line_info.o
OBJ += log.o message_queue.o misc_tools.o name_lookup.o notify.o prompt.o qr_code.o settings.o
OBJ += term_mplex.o toxic.o toxic_strings.o windows.o
# Check if debug build is enabled

View File

@ -55,9 +55,9 @@ author = 'Jakob Kreuze'
# built documents.
#
# The short X.Y version.
version = '0.12.0'
version = '0.11.2'
# The full version, including alpha/beta/rc tags.
release = '0.12.0'
release = '0.11.2'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@ -151,4 +151,4 @@ texinfo_documents = [
(master_doc, 'toxic_api', 'toxic_api Documentation',
author, 'toxic_api', 'One line description of project.',
'Miscellaneous'),
]
]

View File

@ -1,5 +1,5 @@
# Version
TOXIC_VERSION = 0.12.0
TOXIC_VERSION = 0.11.2
REV = $(shell git rev-list HEAD --count 2>/dev/null || echo -n "error")
ifneq (, $(findstring error, $(REV)))
VERSION = $(TOXIC_VERSION)

View File

@ -1,13 +1,13 @@
'\" t
.\" Title: toxic
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
.\" Date: 2021-12-05
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 2021-05-24
.\" Manual: Toxic Manual
.\" Source: toxic __VERSION__
.\" Language: English
.\"
.TH "TOXIC" "1" "2021\-12\-05" "toxic __VERSION__" "Toxic Manual"
.TH "TOXIC" "1" "2021\-05\-24" "toxic __VERSION__" "Toxic Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -156,14 +156,14 @@ Configuration example\&.
\-Screen flickering sometimes occurs on certain terminals\&.
.sp
\-Resizing the terminal window when a game window is open will break things\&.
.SH "LINKS"
.sp
Project page: https://github\&.com/JFreegman/toxic
.sp
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
.SH "AUTHORS"
.sp
JFreegman <JFreegman@gmail\&.com>
.SH "SEE ALSO"
.sp
\fBtoxic\&.conf\fR(5)
.SH "LINKS"
.sp
Project page: https://github\&.com/JFreegman/toxic
.sp
IRC channel: irc\&.libera\&.chat#tox

View File

@ -93,12 +93,6 @@ behaviour.
-Resizing the terminal window when a game window is open will break things.
LINKS
-----
Project page: <https://github.com/JFreegman/toxic>
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
AUTHORS
-------
JFreegman <JFreegman@gmail.com>
@ -106,3 +100,9 @@ JFreegman <JFreegman@gmail.com>
SEE ALSO
--------
*toxic.conf*(5)
LINKS
-----
Project page: <https://github.com/JFreegman/toxic>
IRC channel: irc.libera.chat#tox

View File

@ -1,13 +1,13 @@
'\" t
.\" Title: toxic.conf
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
.\" Date: 2022-06-27
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 2021-05-24
.\" Manual: Toxic Manual
.\" Source: toxic __VERSION__
.\" Language: English
.\"
.TH "TOXIC\&.CONF" "5" "2022\-06\-27" "toxic __VERSION__" "Toxic Manual"
.TH "TOXIC\&.CONF" "5" "2021\-05\-24" "toxic __VERSION__" "Toxic Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -138,11 +138,6 @@ Show welcome message on startup\&. true or false
Enable friend connection change notifications\&. true or false
.RE
.PP
\fBshow_group_connection_msg\fR
.RS 4
Enable group connection change notifications (does not include quit messages)\&. true or false
.RE
.PP
\fBnodelist_update_freq\fR
.RS 4
How often in days to update the DHT nodes list\&. (integer; 0 to disable)
@ -191,11 +186,6 @@ Set user status when attaching and detaching from GNU screen or tmux\&. true or
\fBmplex_away_note\fR
.RS 4
Status message to set when status is set to away due to screen/tmux detach\&. When attaching, the status message is set back to the original value\&.
.RE
.PP
\fBgroup_part_message\fR
.RS 4
Parting message that will be sent to all groupchat peers when you leave the group\&.
.sp
.if n \{\
.RS 4
@ -417,14 +407,14 @@ __DATADIR__/toxic\&.conf\&.example
.RS 4
Configuration example\&.
.RE
.SH "SEE ALSO"
.sp
\fBtoxic\fR(1)
.SH "RESOURCES"
.sp
Project page: https://github\&.com/JFreegman/toxic
.sp
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
IRC channel: irc\&.libera\&.chat#tox
.SH "AUTHORS"
.sp
JFreegman <JFreegman@gmail\&.com>
.SH "SEE ALSO"
.sp
\fBtoxic\fR(1)

View File

@ -87,9 +87,6 @@ OPTIONS
*show_connection_msg*;;
Enable friend connection change notifications. true or false
*show_group_connection_msg*;;
Enable group connection change notifications (does not include quit messages). true or false
*nodelist_update_freq*;;
How often in days to update the DHT nodes list. (integer; 0 to disable)
@ -124,9 +121,6 @@ OPTIONS
detach. When attaching, the status message is set back to the original
value.
*group_part_message*;;
Parting message that will be sent to all groupchat peers when you leave the group.
The following options control whether to output a terminal bell on certain events.
Some terminals mark the window as urgent when a bell is received. Urgent windows are usually highlighted in the taskbar and some window managers even provide shortcuts to jump to the next urgent window.
These options don't affect the "alerts" option.
@ -263,19 +257,19 @@ FILES
{datadir}/toxic.conf.example::
Configuration example.
RESOURCES
---------
Project page: <https://github.com/JFreegman/toxic>
Tox development group public key: 360497DA684BCE2A500C1AF9B3A5CE949BBB9F6FB1F91589806FB04CA039E313
AUTHORS
-------
JFreegman <JFreegman@gmail.com>
SEE ALSO
--------
*toxic*(1)
RESOURCES
---------
Project page: <https://github.com/JFreegman/toxic>
IRC channel: irc.libera.chat#tox
AUTHORS
-------
JFreegman <JFreegman@gmail.com>

View File

@ -0,0 +1 @@
toxme.io 1A39E7A5D5FA9CF155C751570A32E625698A60A55F6D88028F949F66144F4F25

View File

@ -56,9 +56,6 @@ ui = {
// true to show friend connection change messages on the home screen
show_connection_msg=true;
// true to show peer connection change messages in groups (setting to false does not include user quit messages)
show_group_connection_msg=true;
// How often in days to update the DHT nodes list. (0 to disable updates)
nodeslist_update_freq=7;
@ -83,17 +80,11 @@ ui = {
// Indicator for normal messages.
line_normal="-";
// Indicator for special messages.
line_special=">";
// true to change status based on screen/tmux attach/detach, false to disable
mplex_away=true;
// Status message to use when status set to away due to screen/tmux detach
mplex_away_note="Away from keyboard, be back soon!"
// Parting message that will be sent to all groupchat peers when you leave the group
group_part_message="Toxic user signing out"
};
audio = {

View File

@ -2,7 +2,7 @@
# MIT License
#
# Copyright (c) 2021-2022 Maxim Biro <nurupo.contributions@gmail.com>
# Copyright (c) 2021 Maxim Biro <nurupo.contributions@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@ -36,19 +36,8 @@
#
# that would use Toxic code from /home/jfreegman/git/toxic and place the build
# artifact at /tmp/artifact.
#
# You can change between:
# amd64/alpine:latest,
# i386/alpine:latest,
# arm64v8/alpine:latest,
# arm32v7/alpine:latest,
# arm32v6/alpine:latest,
# ppc64le/alpine:latest,
# s390x/alpine:latest,
# etc.
# as long as your system can run foreign architecture binaries, e.g. via qemu
# static bins and binfmt (install qemu-user-static package on Debian/Ubuntu).
#
# You can change between amd64/alpine:latest and i386/alpine:latest, for 64-bit
# and 32-bit builds.
#
# To debug, run:
#
@ -64,6 +53,13 @@ set -eu
ARTIFACT_DIR="/artifact"
TOXIC_SRC_DIR="/toxic"
# Make sure we run in the expected environment
if ! grep -q 'docker' /proc/1/cgroup
then
echo "Error: This script should be run inside a disposable Docker container as it might modify system files in ways that would break a real system."
exit 1
fi
if [ ! -f /etc/os-release ] || ! grep -qi 'Alpine Linux' /etc/os-release
then
echo "Error: This script expects to be run on Alpine Linux."
@ -136,32 +132,20 @@ mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# The git hash of the c-toxcore version we're using
TOXCORE_VERSION="172f279dc0647a538b30e62c96bab8bb1b0c8960"
TOXCORE_VERSION="25a56c354937e9c8c4c50a64c3b4cfc099c34e29"
# The sha256sum of the c-toxcore tarball for TOXCORE_VERSION
TOXCORE_HASH="9884d4ad9b80917e22495c2ebe7a76c509fb98c61031824562883225e66684ae"
TOXCORE_HASH="8448752e6286c747130254571fde2db8e2fc073a8116f9fff489ed53af546c0a"
TOXCORE_FILENAME="c-toxcore-$TOXCORE_VERSION.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"
tar -o -xf "$TOXCORE_FILENAME"
rm "$TOXCORE_FILENAME"
cd c-toxcore*
mkdir -p "third_party" && cd "third_party"
CMP_VERSION="074e0df43e8a61ea938c4f77f65d1fbccc0c3bf9"
CMP_FILENAME="cmp-$CMP_VERSION.tar.gz"
wget --timeout=10 -O "$CMP_FILENAME" "https://github.com/TokTok/cmp/archive/$CMP_VERSION.tar.gz"
tar -o -xf "$CMP_FILENAME"
mv cmp-*/* 'cmp/'
cd ..
cmake -B_build -H. \
-DUSE_TEST_NETWORK=OFF \
-DENABLE_STATIC=ON \
-DENABLE_SHARED=OFF \
-DCMAKE_BUILD_TYPE=Release \
@ -180,8 +164,8 @@ cmake --build _build --target install
# location with SSL_CERT_FILE env variable.
cd "$BUILD_DIR"
CURL_VERSION="7.88.1"
CURL_HASH="cdb38b72e36bc5d33d5b8810f8018ece1baa29a8f215b4495e495ded82bbf3c7"
CURL_VERSION="7.77.0"
CURL_HASH="b0a3428acb60fa59044c4d0baae4e4fc09ae9af1d8a3aa84b2e3fbcd99841f77"
CURL_FILENAME="curl-$CURL_VERSION.tar.gz"
wget --timeout=10 -O "$CURL_FILENAME" "https://curl.haxx.se/download/$CURL_FILENAME"
@ -202,8 +186,7 @@ cd curl*
--with-openssl
make
make install
sed -i 's|-lbrotlidec |-lbrotlidec -lbrotlicommon |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
# Build Toxic
cd "$BUILD_DIR"
@ -318,3 +301,4 @@ mv "$PREPARE_ARTIFACT_DIR" "$PREPARE_ARTIFACT_DIR/../$ARTIFACT_NAME"
tar -cJf "$ARTIFACT_NAME.tar.xz" "$ARTIFACT_NAME"
mv "$ARTIFACT_NAME.tar.xz" "$ARTIFACT_DIR"
chmod 777 -R "$ARTIFACT_DIR"

View File

@ -41,6 +41,9 @@ Tox *user_tox;
static WINDOW *cur_window;
static ToxWindow *self_window;
extern FriendsList Friends;
extern struct user_settings *user_settings;
void api_display(const char *const msg)
{
if (msg == NULL) {

View File

@ -60,8 +60,14 @@
#endif /* ALC_ALL_DEVICES_SPECIFIER */
#endif /* __APPLE__ */
extern FriendsList Friends;
extern ToxWindow *windows[MAX_WINDOWS_NUM];
struct CallControl CallControl;
extern struct user_settings *user_settings;
extern struct Winthread Winthread;
void on_call(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled,
void *user_data);
void on_call_state(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data);

View File

@ -530,7 +530,7 @@ static DeviceError open_device(DeviceType type, uint32_t *device_idx, DataHandle
device->cb_data = cb_data;
#ifdef AUDIO
if (user_settings->VAD_threshold >= 0.0) {
if (user_settings->VAD_threshold >= 0.0f) {
device->VAD_threshold = user_settings->VAD_threshold;
}

View File

@ -56,7 +56,7 @@ static void print_ac_matches(ToxWindow *self, Tox *m, char **list, size_t n_matc
*
* Returns the length of the match.
*/
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, const char *const *matches, size_t n_items,
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, const char **matches, size_t n_items,
size_t max_size)
{
UNUSED_VAR(self);
@ -96,7 +96,7 @@ static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, const
*
* Note: This function should not be called directly. Use complete_line() and complete_path() instead.
*/
static int complete_line_helper(ToxWindow *self, const char *const *list, const size_t n_items, bool dir_search)
static int complete_line_helper(ToxWindow *self, const char **list, const size_t n_items, bool dir_search)
{
ChatContext *ctx = self->chatwin;
@ -181,7 +181,7 @@ static int complete_line_helper(ToxWindow *self, const char *const *list, const
}
char match[MAX_STR_SIZE];
size_t match_len = get_str_match(self, match, sizeof(match), (const char *const *) matches, n_matches, MAX_STR_SIZE);
size_t match_len = get_str_match(self, match, sizeof(match), (const char **) matches, n_matches, MAX_STR_SIZE);
free_ptr_array((void **) matches);
@ -259,12 +259,12 @@ static int complete_line_helper(ToxWindow *self, const char *const *list, const
return diff;
}
int complete_line(ToxWindow *self, const char *const *list, size_t n_items)
int complete_line(ToxWindow *self, const char **list, size_t n_items)
{
return complete_line_helper(self, list, n_items, false);
}
static int complete_path(ToxWindow *self, const char *const *list, const size_t n_items)
static int complete_path(ToxWindow *self, const char **list, const size_t n_items)
{
return complete_line_helper(self, list, n_items, true);
}
@ -385,7 +385,7 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
print_ac_matches(self, m, dirnames, dircount);
}
int ret = complete_path(self, (const char *const *) dirnames, dircount);
int ret = complete_path(self, (const char **) dirnames, dircount);
free_ptr_array((void **) dirnames);

View File

@ -39,7 +39,9 @@
#include "settings.h"
#include "windows.h"
extern struct arg_opts arg_opts;
extern struct user_settings *user_settings;
extern struct Winthread Winthread;
/* URL that we get the JSON encoded nodes list from. */
#define NODES_LIST_URL "https://nodes.tox.chat/json"
@ -57,6 +59,7 @@ extern struct user_settings *user_settings;
#define IP_MAX_SIZE 45
#define IP_MIN_SIZE 7
#define PORT_MAX_SIZE 5
#define LAST_SCAN_JSON_KEY "\"last_scan\":"
#define LAST_SCAN_JSON_KEY_LEN (sizeof(LAST_SCAN_JSON_KEY) - 1)
@ -79,6 +82,7 @@ extern struct user_settings *user_settings;
/* Maximum allowable size of the nodes list */
#define MAX_NODELIST_SIZE (MAX_RECV_CURL_DATA_SIZE)
static struct Thread_Data {
pthread_t tid;
pthread_attr_t attr;

View File

@ -58,6 +58,12 @@
#endif /* VIDEO */
#endif /* AUDIO */
extern char *DATA_FILE;
extern FriendsList Friends;
extern struct Winthread Winthread;
extern struct user_settings *user_settings;
#ifdef AUDIO
static void init_infobox(ToxWindow *self);
static void kill_infobox(ToxWindow *self);
@ -69,15 +75,11 @@ static const char *chat_cmd_list[] = {
"/add",
"/avatar",
"/cancel",
"/cinvite",
"/cjoin",
"/clear",
"/close",
"/connect",
"/exit",
"/gaccept",
"/conference",
"/group",
#ifdef GAMES
"/game",
"/play",
@ -134,7 +136,7 @@ static void set_self_typingstatus(ToxWindow *self, Tox *m, bool is_typing)
ChatContext *ctx = self->chatwin;
Tox_Err_Set_Typing err;
TOX_ERR_SET_TYPING err;
tox_self_set_typing(m, self->num, is_typing, &err);
if (err != TOX_ERR_SET_TYPING_OK) {
@ -252,7 +254,6 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, Tox_C
if (prev_status == TOX_CONNECTION_NONE) {
chat_resume_file_senders(self, m, num);
file_send_queue_check(self, m, self->num);
msg = "has come online";
line_info_add(self, true, nick, NULL, CONNECTION, 0, GREEN, msg);
@ -680,10 +681,8 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_
FILE *filecheck = NULL;
int count = 1;
while ((filecheck = fopen(file_path, "r")) || file_transfer_recv_path_exists(file_path)) {
if (filecheck) {
fclose(filecheck);
}
while ((filecheck = fopen(file_path, "r"))) {
fclose(filecheck);
file_path[path_len] = '\0';
char d[5];
@ -761,46 +760,8 @@ static void chat_onConferenceInvite(ToxWindow *self, Tox *m, int32_t friendnumbe
"invites you to join %s", description);
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a conference.", name);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Type \"/cjoin\" to join the chat.");
}
static void chat_onGroupInvite(ToxWindow *self, Tox *m, uint32_t friendnumber, const char *invite_data, size_t length,
const char *group_name, size_t group_name_length)
{
UNUSED_VAR(group_name_length);
if (self->num != friendnumber) {
return;
}
if (Friends.list[friendnumber].group_invite.data) {
free(Friends.list[friendnumber].group_invite.data);
}
Friends.list[friendnumber].group_invite.data = malloc(length * sizeof(uint8_t));
if (Friends.list[friendnumber].group_invite.data == NULL) {
return;
}
memcpy(Friends.list[friendnumber].group_invite.data, invite_data, length);
Friends.list[friendnumber].group_invite.length = length;
sound_notify(self, generic_message, NT_WNDALERT_2 | user_settings->bell_on_invite, NULL);
char name[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, name, friendnumber);
if (self->active_box != -1) {
box_silent_notify2(self, NT_WNDALERT_2 | NT_NOFOCUS, self->active_box, "invites you to join group chat");
} else {
box_silent_notify(self, NT_WNDALERT_2 | NT_NOFOCUS, &self->active_box, name, "invites you to join group chat");
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to join group chat \"%s\"", name, group_name);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,
"Type \"/gaccept <password>\" to join the chat (password is optional).");
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to %s.", name, description);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat.");
}
#ifdef GAMES
@ -837,7 +798,12 @@ void chat_onGameInvite(ToxWindow *self, Tox *m, uint32_t friend_number, const ui
return;
}
Friends.list[friend_number].game_invite.type = type;
Friends.list[friend_number].game_invite.id = id;
Friends.list[friend_number].game_invite.pending = true;
uint32_t data_length = length - GAME_PACKET_HEADER_SIZE;
Friends.list[friend_number].game_invite.data_length = data_length;
if (data_length > 0) {
free(Friends.list[friend_number].game_invite.data);
@ -852,11 +818,6 @@ void chat_onGameInvite(ToxWindow *self, Tox *m, uint32_t friend_number, const ui
Friends.list[friend_number].game_invite.data = buf;
}
Friends.list[friend_number].game_invite.type = type;
Friends.list[friend_number].game_invite.id = id;
Friends.list[friend_number].game_invite.pending = true;
Friends.list[friend_number].game_invite.data_length = data_length;
char name[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, name, friend_number);
@ -1309,16 +1270,9 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
}
ChatContext *ctx = self->chatwin;
StatusBar *statusbar = self->stb;
pthread_mutex_lock(&Winthread.lock);
line_info_print(self);
Tox_Connection connection = statusbar->connection;
Tox_User_Status status = statusbar->status;
const bool is_typing = Friends.list[self->num].is_typing;
pthread_mutex_unlock(&Winthread.lock);
wclear(ctx->linewin);
@ -1329,6 +1283,14 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
curs_set(1);
/* Draw status bar */
StatusBar *statusbar = self->stb;
pthread_mutex_lock(&Winthread.lock);
Tox_Connection connection = statusbar->connection;
Tox_User_Status status = statusbar->status;
pthread_mutex_unlock(&Winthread.lock);
wmove(statusbar->topline, 0, 0);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
@ -1356,13 +1318,13 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
}
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "] ");
wprintw(statusbar->topline, "]");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
const char *status_text = "ERROR";
int colour = BAR_TEXT;
if (status != TOX_USER_STATUS_NONE) {
const char *status_text = "ERROR";
int colour = MAGENTA;
if (connection != TOX_CONNECTION_NONE) {
switch (status) {
case TOX_USER_STATUS_AWAY:
colour = STATUS_AWAY;
@ -1377,11 +1339,9 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
default:
break;
}
}
if (colour != BAR_TEXT) {
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "[");
wprintw(statusbar->topline, " [");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
@ -1391,23 +1351,30 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "] ");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
}
if (is_typing) {
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
pthread_mutex_lock(&Winthread.lock);
const bool is_typing = Friends.list[self->num].is_typing;
pthread_mutex_unlock(&Winthread.lock);
if (is_typing) {
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
} else {
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
}
wprintw(statusbar->topline, "%s", statusbar->nick);
if (is_typing) {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
} else {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_TEXT));
}
} else {
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wprintw(statusbar->topline, " %s", statusbar->nick);
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
}
wprintw(statusbar->topline, "%s", statusbar->nick);
if (is_typing) {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_NOTIFY));
} else {
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(BAR_TEXT));
}
/* Reset statusbar->statusmsg on window resize */
if (x2 != self->x) {
char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH] = {'\0'};
@ -1427,7 +1394,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
self->x = x2;
/* Truncate note if it doesn't fit in statusbar */
size_t maxlen = x2 - getcurx(statusbar->topline) - KEY_IDENT_BYTES - 6;
size_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 6;
pthread_mutex_lock(&Winthread.lock);
size_t statusmsg_len = statusbar->statusmsg_len;
@ -1458,10 +1425,10 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
int s_x;
getyx(statusbar->topline, s_y, s_x);
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - KEY_IDENT_BYTES - 3);
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x - (KEY_IDENT_DIGITS * 2) - 3);
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wmove(statusbar->topline, 0, x2 - KEY_IDENT_BYTES - 3);
wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "{");
@ -1469,7 +1436,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
for (size_t i = 0; i < KEY_IDENT_BYTES / 2; ++i) {
for (size_t i = 0; i < KEY_IDENT_DIGITS; ++i) {
wprintw(statusbar->topline, "%02X", Friends.list[self->num].pub_key[i] & 0xff);
}
@ -1623,7 +1590,6 @@ ToxWindow *new_chat(Tox *m, uint32_t friendnum)
ret->onFileControl = &chat_onFileControl;
ret->onFileRecv = &chat_onFileRecv;
ret->onReadReceipt = &chat_onReadReceipt;
ret->onGroupInvite = &chat_onGroupInvite;
#ifdef AUDIO
ret->onInvite = &chat_onInvite;

View File

@ -29,7 +29,6 @@
#include "file_transfers.h"
#include "friendlist.h"
#include "line_info.h"
#include "groupchats.h"
#include "misc_tools.h"
#include "toxic.h"
#include "windows.h"
@ -55,13 +54,7 @@ void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
return;
}
// first check transfer queue
if (file_send_queue_remove(self->num, idx) == 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Pending file transfer removed from queue");
return;
}
FileTransfer *ft = NULL;
struct FileTransfer *ft = NULL;
/* cancel an incoming file transfer */
if (strcasecmp(inoutstr, "in") == 0) {
@ -179,77 +172,6 @@ void cmd_conference_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char
#endif
}
void cmd_group_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open.");
return;
}
if (Friends.list[self->num].group_invite.length == 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending group invite");
return;
}
const char *passwd = NULL;
uint16_t passwd_len = 0;
if (argc > 0) {
passwd = argv[1];
passwd_len = strlen(passwd);
}
size_t nick_len = tox_self_get_name_size(m);
char self_nick[TOX_MAX_NAME_LENGTH + 1];
tox_self_get_name(m, (uint8_t *) self_nick);
self_nick[nick_len] = '\0';
Tox_Err_Group_Invite_Accept err;
uint32_t groupnumber = tox_group_invite_accept(m, self->num, Friends.list[self->num].group_invite.data,
Friends.list[self->num].group_invite.length, (const uint8_t *) self_nick, nick_len,
(const uint8_t *) passwd, passwd_len, &err);
if (err != TOX_ERR_GROUP_INVITE_ACCEPT_OK) {
if (err == TOX_ERR_GROUP_INVITE_ACCEPT_TOO_LONG) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to join group: Password too long.");
} else {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to join group (error %d).", err);
}
return;
}
if (init_groupchat_win(m, groupnumber, NULL, 0, Group_Join_Type_Join) == -1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
tox_group_leave(m, groupnumber, NULL, 0, NULL);
return;
}
}
void cmd_group_invite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group number required.");
return;
}
int groupnumber = atoi(argv[1]);
if (groupnumber == 0 && strcmp(argv[1], "0")) { /* atoi returns 0 value on invalid input */
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid group number.");
return;
}
Tox_Err_Group_Invite_Friend err;
if (!tox_group_invite_friend(m, groupnumber, self->num, &err)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group (error %d).", err);
return;
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Group %d.", groupnumber);
}
#ifdef GAMES
void cmd_game_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -317,7 +239,7 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
return;
}
FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
struct FileTransfer *ft = get_file_transfer_struct_index(self->num, idx, FILE_TRANSFER_RECV);
if (!ft) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "No pending file transfers with that ID.");
@ -402,7 +324,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
FILE *file_to_send = fopen(path, "r");
if (file_to_send == NULL) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File `%s` not found.", path);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "File not found.");
return;
}
@ -425,7 +347,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
goto on_send_error;
}
FileTransfer *ft = new_file_transfer(self, self->num, filenum, FILE_TRANSFER_SEND, TOX_FILE_KIND_DATA);
struct FileTransfer *ft = new_file_transfer(self, self->num, filenum, FILE_TRANSFER_SEND, TOX_FILE_KIND_DATA);
if (!ft) {
err = TOX_ERR_FILE_SEND_TOO_MANY;
@ -445,62 +367,29 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
on_send_error:
fclose(file_to_send);
switch (err) {
case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND: {
case TOX_ERR_FILE_SEND_FRIEND_NOT_FOUND:
errmsg = "File transfer failed: Invalid friend.";
break;
}
case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED: {
int queue_idx = file_send_queue_add(self->num, path, path_len);
case TOX_ERR_FILE_SEND_FRIEND_NOT_CONNECTED:
errmsg = "File transfer failed: Friend is offline.";
break;
char msg[MAX_STR_SIZE];
switch (queue_idx) {
case -1: {
snprintf(msg, sizeof(msg), "Invalid file name: path is null or length is zero.");
break;
}
case -2: {
snprintf(msg, sizeof(msg), "File name is too long.");
break;
}
case -3: {
snprintf(msg, sizeof(msg), "File send queue is full.");
break;
}
default: {
snprintf(msg, sizeof(msg), "File transfer queued. Type \"/cancel out %d\" to cancel.", queue_idx);
break;
}
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", msg);
return;
}
case TOX_ERR_FILE_SEND_NAME_TOO_LONG: {
case TOX_ERR_FILE_SEND_NAME_TOO_LONG:
errmsg = "File transfer failed: Filename is too long.";
break;
}
case TOX_ERR_FILE_SEND_TOO_MANY: {
case TOX_ERR_FILE_SEND_TOO_MANY:
errmsg = "File transfer failed: Too many concurrent file transfers.";
break;
}
default: {
default:
errmsg = "File transfer failed.";
break;
}
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", errmsg);
tox_file_control(m, self->num, filenum, TOX_FILE_CONTROL_CANCEL, NULL);
fclose(file_to_send);
}

View File

@ -29,8 +29,6 @@
void cmd_cancelfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_invite(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference_join(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_invite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_game_join(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_savefile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_sendfile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);

View File

@ -63,6 +63,8 @@
#include "toxic_strings.h"
#include "windows.h"
extern char *DATA_FILE;
#define MAX_CONFERENCE_NUM (MAX_WINDOWS_NUM - 2)
#define CONFERENCE_EVENT_WAIT 30
@ -85,13 +87,11 @@ static const char *conference_cmd_list[] = {
"/connect",
"/decline",
"/exit",
"/group",
"/conference",
#ifdef GAMES
"/game",
#endif
"/help",
"/join",
"/log",
#ifdef AUDIO
"/mute",

View File

@ -1,7 +1,7 @@
/* conference_commands.h
*
*
* Copyright (C) 2020 Toxic All Rights Reserved.
* Copyright (C) 2014 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
@ -33,4 +33,3 @@ void cmd_conference_sense(WINDOW *window, ToxWindow *self, Tox *m, int argc, cha
void cmd_conference_push_to_talk(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
#endif /* CONFERENCE_COMMANDS_H */

View File

@ -29,7 +29,6 @@
#include "execute.h"
#include "global_commands.h"
#include "conference_commands.h"
#include "groupchat_commands.h"
#include "line_info.h"
#include "misc_tools.h"
#include "notify.h"
@ -50,12 +49,10 @@ static struct cmd_func global_commands[] = {
{ "/decline", cmd_decline },
{ "/exit", cmd_quit },
{ "/conference", cmd_conference },
{ "/group", cmd_groupchat },
#ifdef GAMES
{ "/game", cmd_game },
#endif
{ "/help", cmd_prompt_help },
{ "/join", cmd_join },
{ "/log", cmd_log },
{ "/myid", cmd_myid },
#ifdef QRCODE
@ -84,10 +81,8 @@ static struct cmd_func global_commands[] = {
static struct cmd_func chat_commands[] = {
{ "/cancel", cmd_cancelfile },
{ "/cinvite", cmd_conference_invite },
{ "/cjoin", cmd_conference_join },
{ "/gaccept", cmd_group_accept },
{ "/invite", cmd_group_invite },
{ "/invite", cmd_conference_invite },
{ "/join", cmd_conference_join },
#ifdef GAMES
{ "/play", cmd_game_join },
#endif
@ -122,54 +117,25 @@ static struct cmd_func conference_commands[] = {
{ NULL, NULL },
};
static struct cmd_func groupchat_commands[] = {
{ "/chatid", cmd_chatid },
{ "/disconnect", cmd_disconnect },
{ "/ignore", cmd_ignore },
{ "/kick", cmd_kick },
{ "/list", cmd_list },
{ "/locktopic", cmd_set_topic_lock },
{ "/mod", cmd_mod },
{ "/nick", cmd_group_nick },
{ "/passwd", cmd_set_passwd },
{ "/peerlimit", cmd_set_peerlimit },
{ "/privacy", cmd_set_privacy },
{ "/rejoin", cmd_rejoin },
{ "/silence", cmd_silence },
{ "/topic", cmd_set_topic },
{ "/unignore", cmd_unignore },
{ "/unmod", cmd_unmod },
{ "/unsilence", cmd_unsilence },
{ "/voice", cmd_set_voice },
{ "/whois", cmd_whois },
{ NULL, NULL },
};
#ifdef PYTHON
#define SPECIAL_COMMANDS 8
#else
#define SPECIAL_COMMANDS 7
#endif /* PYTHON */
/* Special commands are commands that only take one argument even if it contains spaces */
static const char special_commands[][MAX_CMDNAME_SIZE] = {
static const char special_commands[SPECIAL_COMMANDS][MAX_CMDNAME_SIZE] = {
"/add",
"/avatar",
"/gaccept",
"/group",
"/ignore",
"/kick",
"/mod",
"/nick",
"/note",
"/passwd",
"/silence",
"/topic",
"/unignore",
"/unmod",
"/unsilence",
"/whois",
#ifdef PYTHON
"/run",
#endif /* PYTHON */
"/sendfile",
"/title",
"/mute",
"",
};
/* Returns true if input command is in the special_commands array. */
@ -177,7 +143,7 @@ static bool is_special_command(const char *input)
{
const int s = char_find(0, input, ' ');
for (int i = 0; special_commands[i][0] != '\0'; ++i) {
for (int i = 0; i < SPECIAL_COMMANDS; ++i) {
if (strncmp(input, special_commands[i], s) == 0) {
return true;
}
@ -283,29 +249,19 @@ void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)
* Note: Global commands must come last in case of duplicate command names
*/
switch (mode) {
case CHAT_COMMAND_MODE: {
case CHAT_COMMAND_MODE:
if (do_command(w, self, m, num_args, chat_commands, args) == 0) {
return;
}
break;
}
case CONFERENCE_COMMAND_MODE: {
case CONFERENCE_COMMAND_MODE:
if (do_command(w, self, m, num_args, conference_commands, args) == 0) {
return;
}
break;
}
case GROUPCHAT_COMMAND_MODE: {
if (do_command(w, self, m, num_args, groupchat_commands, args) == 0) {
return;
}
break;
}
}
if (do_command(w, self, m, num_args, global_commands, args) == 0) {

View File

@ -32,7 +32,6 @@ enum {
GLOBAL_COMMAND_MODE,
CHAT_COMMAND_MODE,
CONFERENCE_COMMAND_MODE,
GROUPCHAT_COMMAND_MODE,
};
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode);

View File

@ -25,7 +25,6 @@
#include <time.h>
#include <unistd.h>
#include "execute.h"
#include "file_transfers.h"
#include "friendlist.h"
#include "line_info.h"
@ -45,8 +44,9 @@ extern FriendsList Friends;
void init_progress_bar(char *progline)
{
strcpy(progline, "0% [");
int i;
for (size_t i = 0; i < NUM_PROG_MARKS; ++i) {
for (i = 0; i < NUM_PROG_MARKS; ++i) {
strcat(progline, "-");
}
@ -98,7 +98,7 @@ void print_progress_bar(ToxWindow *self, double bps, double pct_done, uint32_t l
free(full_line);
}
static void refresh_progress_helper(ToxWindow *self, FileTransfer *ft)
static void refresh_progress_helper(ToxWindow *self, struct FileTransfer *ft)
{
if (ft->state == FILE_TRANSFER_INACTIVE) {
return;
@ -126,8 +126,8 @@ bool refresh_file_transfer_progress(ToxWindow *self, uint32_t friendnumber)
bool active = false;
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft_r = &Friends.list[friendnumber].file_receiver[i];
FileTransfer *ft_s = &Friends.list[friendnumber].file_sender[i];
struct FileTransfer *ft_r = &Friends.list[friendnumber].file_receiver[i];
struct FileTransfer *ft_s = &Friends.list[friendnumber].file_sender[i];
refresh_progress_helper(self, ft_r);
refresh_progress_helper(self, ft_s);
@ -140,9 +140,9 @@ bool refresh_file_transfer_progress(ToxWindow *self, uint32_t friendnumber)
return active;
}
static void clear_file_transfer(FileTransfer *ft)
static void clear_file_transfer(struct FileTransfer *ft)
{
*ft = (FileTransfer) {
*ft = (struct FileTransfer) {
0
};
}
@ -150,16 +150,16 @@ static void clear_file_transfer(FileTransfer *ft)
/* Returns a pointer to friendnumber's FileTransfer struct associated with filenumber.
* Returns NULL if filenumber is invalid.
*/
FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t filenumber)
struct FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t filenumber)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft_send = &Friends.list[friendnumber].file_sender[i];
struct FileTransfer *ft_send = &Friends.list[friendnumber].file_sender[i];
if (ft_send->state != FILE_TRANSFER_INACTIVE && ft_send->filenumber == filenumber) {
return ft_send;
}
FileTransfer *ft_recv = &Friends.list[friendnumber].file_receiver[i];
struct FileTransfer *ft_recv = &Friends.list[friendnumber].file_receiver[i];
if (ft_recv->state != FILE_TRANSFER_INACTIVE && ft_recv->filenumber == filenumber) {
return ft_recv;
@ -172,7 +172,7 @@ FileTransfer *get_file_transfer_struct(uint32_t friendnumber, uint32_t filenumbe
/* Returns a pointer to the FileTransfer struct associated with index with the direction specified.
* Returns NULL on failure.
*/
FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t index,
struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t index,
FILE_TRANSFER_DIRECTION direction)
{
if (direction != FILE_TRANSFER_RECV && direction != FILE_TRANSFER_SEND) {
@ -180,9 +180,9 @@ FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t ind
}
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft = direction == FILE_TRANSFER_SEND ?
&Friends.list[friendnumber].file_sender[i] :
&Friends.list[friendnumber].file_receiver[i];
struct FileTransfer *ft = direction == FILE_TRANSFER_SEND ?
&Friends.list[friendnumber].file_sender[i] :
&Friends.list[friendnumber].file_receiver[i];
if (ft->state != FILE_TRANSFER_INACTIVE && ft->index == index) {
return ft;
@ -195,10 +195,10 @@ FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint32_t ind
/* Returns a pointer to an unused file sender.
* Returns NULL if all file senders are in use.
*/
static FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber, uint8_t type)
static struct FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber, uint8_t type)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
struct FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
if (ft->state == FILE_TRANSFER_INACTIVE) {
clear_file_transfer(ft);
@ -218,11 +218,11 @@ static FileTransfer *new_file_sender(ToxWindow *window, uint32_t friendnumber, u
/* Returns a pointer to an unused file receiver.
* Returns NULL if all file receivers are in use.
*/
static FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
uint8_t type)
static struct FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
uint8_t type)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
struct FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
if (ft->state == FILE_TRANSFER_INACTIVE) {
clear_file_transfer(ft);
@ -242,8 +242,8 @@ static FileTransfer *new_file_receiver(ToxWindow *window, uint32_t friendnumber,
/* Initializes an unused file transfer and returns its pointer.
* Returns NULL on failure.
*/
FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
FILE_TRANSFER_DIRECTION direction, uint8_t type)
struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
FILE_TRANSFER_DIRECTION direction, uint8_t type)
{
if (direction == FILE_TRANSFER_RECV) {
return new_file_receiver(window, friendnumber, filenumber, type);
@ -256,83 +256,13 @@ FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32
return NULL;
}
int file_send_queue_add(uint32_t friendnumber, const char *file_path, size_t length)
{
if (length == 0 || file_path == NULL) {
return -1;
}
if (length > TOX_MAX_FILENAME_LENGTH) {
return -2;
}
for (size_t i = 0; i < MAX_FILES; ++i) {
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[i];
if (pending_slot->pending) {
continue;
}
pending_slot->pending = true;
memcpy(pending_slot->file_path, file_path, length);
pending_slot->file_path[length] = 0;
pending_slot->length = length;
return i;
}
return -3;
}
#define FILE_TRANSFER_SEND_CMD "/sendfile "
#define FILE_TRANSFER_SEND_LEN (sizeof(FILE_TRANSFER_SEND_CMD) - 1)
void file_send_queue_check(ToxWindow *self, Tox *m, uint32_t friendnumber)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[i];
if (!pending_slot->pending) {
continue;
}
char command[TOX_MAX_FILENAME_LENGTH + FILE_TRANSFER_SEND_LEN + 1];
snprintf(command, sizeof(command), "%s%s", FILE_TRANSFER_SEND_CMD, pending_slot->file_path);
execute(self->window, self, m, command, CHAT_COMMAND_MODE);
*pending_slot = (PendingFileTransfer) {
0,
};
}
}
int file_send_queue_remove(uint32_t friendnumber, size_t index)
{
if (index >= MAX_FILES) {
return -1;
}
PendingFileTransfer *pending_slot = &Friends.list[friendnumber].file_send_queue[index];
if (!pending_slot->pending) {
return -1;
}
*pending_slot = (PendingFileTransfer) {
0,
};
return 0;
}
/* Closes file transfer ft.
*
* Set CTRL to -1 if we don't want to send a control signal.
* Set message or self to NULL if we don't want to display a message.
*/
void close_file_transfer(ToxWindow *self, Tox *m, FileTransfer *ft, int CTRL, const char *message,
void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int CTRL, const char *message,
Notification sound_type)
{
if (!ft) {
@ -348,11 +278,7 @@ void close_file_transfer(ToxWindow *self, Tox *m, FileTransfer *ft, int CTRL, co
}
if (CTRL >= 0) {
Tox_Err_File_Control err;
if (!tox_file_control(m, ft->friendnumber, ft->filenumber, (Tox_File_Control) CTRL, &err)) {
fprintf(stderr, "Failed to cancel file transfer: %d\n", err);
}
tox_file_control(m, ft->friendnumber, ft->filenumber, (Tox_File_Control) CTRL, NULL);
}
if (message && self) {
@ -372,7 +298,7 @@ void close_file_transfer(ToxWindow *self, Tox *m, FileTransfer *ft, int CTRL, co
void kill_avatar_file_transfers_friend(Tox *m, uint32_t friendnumber)
{
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
struct FileTransfer *ft = &Friends.list[friendnumber].file_sender[i];
if (ft->file_type == TOX_FILE_KIND_AVATAR) {
close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent);
@ -386,7 +312,6 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnumber)
for (size_t i = 0; i < MAX_FILES; ++i) {
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_sender[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
close_file_transfer(NULL, m, &Friends.list[friendnumber].file_receiver[i], TOX_FILE_CONTROL_CANCEL, NULL, silent);
file_send_queue_remove(friendnumber, i);
}
}
@ -396,26 +321,3 @@ void kill_all_file_transfers(Tox *m)
kill_all_file_transfers_friend(m, Friends.list[i].num);
}
}
bool file_transfer_recv_path_exists(const char *path)
{
for (size_t friendnumber = 0; friendnumber < Friends.max_idx; ++friendnumber) {
if (!Friends.list[friendnumber].active) {
continue;
}
for (size_t i = 0; i < MAX_FILES; ++i) {
FileTransfer *ft = &Friends.list[friendnumber].file_receiver[i];
if (ft->state == FILE_TRANSFER_INACTIVE) {
continue;
}
if (strcmp(path, ft->file_path) == 0) {
return true;
}
}
}
return false;
}

View File

@ -29,9 +29,9 @@
#include "toxic.h"
#include "windows.h"
#define KiB (uint32_t) 1024
#define MiB (uint32_t) (1024 << 10) /* 1024^2 */
#define GiB (uint32_t) (1024 << 20) /* 1024^3 */
#define KiB 1024
#define MiB 1048576 /* 1024^2 */
#define GiB 1073741824 /* 1024^3 */
#define MAX_FILES 32
@ -47,7 +47,7 @@ typedef enum FILE_TRANSFER_DIRECTION {
FILE_TRANSFER_RECV
} FILE_TRANSFER_DIRECTION;
typedef struct FileTransfer {
struct FileTransfer {
ToxWindow *window;
FILE *file;
FILE_TRANSFER_STATE state;
@ -63,15 +63,7 @@ typedef struct FileTransfer {
time_t last_line_progress; /* The last time we updated the progress bar */
uint32_t line_id;
uint8_t file_id[TOX_FILE_ID_LENGTH];
} FileTransfer;
typedef struct PendingFileTransfer {
char file_path[TOX_MAX_FILENAME_LENGTH + 1];
size_t length;
uint32_t friendnumber;
bool pending;
} PendingFileTransfer;
};
/* creates initial progress line that will be updated during file transfer.
progline must be at lesat MAX_STR_SIZE bytes */
@ -104,31 +96,6 @@ struct FileTransfer *get_file_transfer_struct_index(uint32_t friendnumber, uint3
struct FileTransfer *new_file_transfer(ToxWindow *window, uint32_t friendnumber, uint32_t filenumber,
FILE_TRANSFER_DIRECTION direction, uint8_t type);
/* Adds a file designated by `file_path` of length `length` to the file transfer queue.
*
* Items in this queue will be automatically sent to the contact designated by `friendnumber`
* as soon as they appear online. The item will then be removed from the queue whether
* or not the transfer successfully initiates.
*
* If the ToxWindow associated with this friend is closed, all queued items will be
* discarded.
*
* Return the queue index on success.
* Return -1 if the length is invalid.
* Return -2 if the send queue is full.
*/
int file_send_queue_add(uint32_t friendnumber, const char *file_path, size_t length);
/* Initiates all file transfers from the file send queue for friend designated by `friendnumber`. */
void file_send_queue_check(ToxWindow *self, Tox *m, uint32_t friendnumber);
/* Removes the `index`-th item from the file send queue for `friendnumber`.
*
* Return 0 if a pending transfer was successfully removed
* Return -1 if index does not designate a pending file transfer.
*/
int file_send_queue_remove(uint32_t friendnumber, size_t index);
/* Closes file transfer ft.
*
* Set CTRL to -1 if we don't want to send a control signal.
@ -145,7 +112,4 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnumber);
void kill_all_file_transfers(Tox *m);
/* Return true if any pending or active file receiver has the path `path`. */
bool file_transfer_recv_path_exists(const char *path);
#endif /* FILE_TRANSFERS_H */

View File

@ -37,7 +37,6 @@
#include "log.h"
#include "misc_tools.h"
#include "notify.h"
#include "prompt.h"
#include "settings.h"
#include "toxic.h"
#include "windows.h"
@ -47,6 +46,13 @@
#endif
extern char *DATA_FILE;
extern char *BLOCK_FILE;
extern ToxWindow *prompt;
extern struct Winthread Winthread;
extern struct user_settings *user_settings;
extern struct arg_opts arg_opts;
static uint8_t blocklist_view = 0; /* 0 if we're in friendlist view, 1 if we're in blocklist view */
FriendsList Friends;
@ -116,10 +122,6 @@ void kill_friendlist(ToxWindow *self)
free(Friends.list[i].game_invite.data);
#endif
}
if (Friends.list[i].group_invite.data != NULL) {
free(Friends.list[i].group_invite.data);
}
}
realloc_blocklist(0);
@ -319,11 +321,11 @@ int load_blocklist(char *path)
#define S_WEIGHT 100000
static int index_name_cmp(const void *n1, const void *n2)
{
int res = qsort_strcasecmp_hlpr(Friends.list[*(const int *) n1].name, Friends.list[*(const int *) n2].name);
int res = qsort_strcasecmp_hlpr(Friends.list[*(int *) n1].name, Friends.list[*(int *) n2].name);
/* Use weight to make qsort always put online friends before offline */
res = Friends.list[*(const int *) n1].connection_status ? (res - S_WEIGHT) : (res + S_WEIGHT);
res = Friends.list[*(const int *) n2].connection_status ? (res + S_WEIGHT) : (res - S_WEIGHT);
res = Friends.list[*(int *) n1].connection_status ? (res - S_WEIGHT) : (res + S_WEIGHT);
res = Friends.list[*(int *) n2].connection_status ? (res + S_WEIGHT) : (res - S_WEIGHT);
return res;
}
@ -347,7 +349,7 @@ void sort_friendlist_index(void)
static int index_name_cmp_block(const void *n1, const void *n2)
{
return qsort_strcasecmp_hlpr(Blocked.list[*(const int *) n1].name, Blocked.list[*(const int *) n2].name);
return qsort_strcasecmp_hlpr(Blocked.list[*(int *) n1].name, Blocked.list[*(int *) n2].name);
}
static void sort_blocklist_index(void)
@ -678,35 +680,6 @@ static void friendlist_onConferenceInvite(ToxWindow *self, Tox *m, int32_t num,
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
}
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, uint32_t num, const char *data, size_t length,
const char *group_name, size_t group_name_length)
{
UNUSED_VAR(self);
UNUSED_VAR(data);
UNUSED_VAR(length);
if (num >= Friends.max_idx) {
return;
}
if (Friends.list[num].chatwin != -1) {
return;
}
if (get_num_active_windows() < MAX_WINDOWS_NUM) {
Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num));
return;
}
char nick[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, nick, num);
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED,
"* Group chat invite from %s failed: too many windows are open.", nick);
sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
}
/* move friendlist/blocklist cursor up and down */
static void select_friend(wint_t key, int *selected, int num)
{
@ -725,9 +698,6 @@ static void select_friend(wint_t key, int *selected, int num)
static void delete_friend(Tox *m, uint32_t f_num)
{
kill_all_file_transfers_friend(m, f_num);
kill_avatar_file_transfers_friend(m, f_num);
Tox_Err_Friend_Delete err;
if (tox_friend_delete(m, f_num, &err) != true) {
@ -876,7 +846,9 @@ void block_friend(Tox *m, uint32_t fnum)
realloc_blocklist(Blocked.max_idx + 1);
clear_blocklist_index(Blocked.max_idx);
for (int i = 0; i <= Blocked.max_idx; ++i) {
int i;
for (i = 0; i <= Blocked.max_idx; ++i) {
if (Blocked.list[i].active) {
continue;
}
@ -1141,14 +1113,14 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
/* Determine which portion of friendlist to draw based on current position */
pthread_mutex_lock(&Winthread.lock);
const int page = Friends.num_selected / (y2 - FLIST_OFST);
int page = Friends.num_selected / (y2 - FLIST_OFST);
pthread_mutex_unlock(&Winthread.lock);
const int start = (y2 - FLIST_OFST) * page;
const int end = y2 - FLIST_OFST + start;
int start = (y2 - FLIST_OFST) * page;
int end = y2 - FLIST_OFST + start;
pthread_mutex_lock(&Winthread.lock);
const size_t num_friends = Friends.num_friends;
size_t num_friends = Friends.num_friends;
pthread_mutex_unlock(&Winthread.lock);
int i;
@ -1431,7 +1403,6 @@ ToxWindow *new_friendlist(void)
ret->onStatusMessageChange = &friendlist_onStatusMessageChange;
ret->onFileRecv = &friendlist_onFileRecv;
ret->onConferenceInvite = &friendlist_onConferenceInvite;
ret->onGroupInvite = &friendlist_onGroupInvite;
#ifdef AUDIO
ret->onInvite = &friendlist_onAV;

View File

@ -46,11 +46,6 @@ struct ConferenceInvite {
bool pending;
};
struct GroupInvite {
uint8_t *data;
uint16_t length;
};
#ifdef GAMES
struct GameInvite {
@ -78,17 +73,14 @@ typedef struct {
Tox_User_Status status;
struct LastOnline last_online;
struct ConferenceInvite conference_invite;
#ifdef GAMES
struct GameInvite game_invite;
#endif
struct ConferenceInvite conference_invite;
struct GroupInvite group_invite;
struct FileTransfer file_receiver[MAX_FILES];
struct FileTransfer file_sender[MAX_FILES];
PendingFileTransfer file_send_queue[MAX_FILES];
} ToxicFriend;
typedef struct {
@ -109,8 +101,6 @@ typedef struct {
ToxicFriend *list;
} FriendsList;
extern FriendsList Friends;
ToxWindow *new_friendlist(void);
void friendlist_onInit(ToxWindow *self, Tox *m);
void disable_chatwin(uint32_t f_num);

View File

@ -517,10 +517,10 @@ static void game_draw_help_bar(const GameData *game, WINDOW *win)
{
int max_x;
int max_y;
getmaxyx(win, max_y, max_x);
UNUSED_VAR(max_x);
getmaxyx(win, max_y, max_x);
wmove(win, max_y - 1, 1);
if (!game->is_multiplayer) {
@ -937,10 +937,10 @@ int game_y_bottom_bound(const GameData *game)
{
int max_x;
int max_y;
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_x);
getmaxyx(game->window, max_y, max_x);
return ((max_y + game->game_max_y) / 2) - 1;
}
@ -948,10 +948,10 @@ int game_y_top_bound(const GameData *game)
{
int max_x;
int max_y;
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_x);
getmaxyx(game->window, max_y, max_x);
return ((max_y - game->game_max_y) / 2) + 1;
}
@ -959,10 +959,10 @@ int game_x_right_bound(const GameData *game)
{
int max_x;
int max_y;
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_y);
getmaxyx(game->window, max_y, max_x);
return ((max_x + game->game_max_x) / 2) - 1;
}
@ -970,10 +970,10 @@ int game_x_left_bound(const GameData *game)
{
int max_x;
int max_y;
getmaxyx(game->window, max_y, max_x);
UNUSED_VAR(max_y);
getmaxyx(game->window, max_y, max_x);
return ((max_x - game->game_max_x) / 2) + 1;
}
@ -1129,7 +1129,7 @@ int game_packet_send(const GameData *game, const uint8_t *data, size_t length, G
memcpy(packet + 1 + GAME_PACKET_HEADER_SIZE, data, length);
packet_length += length;
Tox_Err_Friend_Custom_Packet err;
TOX_ERR_FRIEND_CUSTOM_PACKET err;
if (!tox_friend_send_lossless_packet(game->tox, game->friend_number, packet, packet_length, &err)) {
fprintf(stderr, "failed to send game packet: error %d\n", err);

View File

@ -436,11 +436,7 @@ static bool chess_path_line_clear(Board *board, const Tile *from, const Tile *to
return false;
}
ChessCoords chess_coords = (ChessCoords) {
0,
0
};
ChessCoords chess_coords;
size_t start;
size_t end;
@ -804,13 +800,11 @@ static bool chess_mock_move_valid(ChessState *state, const Player *player, Tile
{
Board *board = &state->board;
const bool en_passant = player->en_passant_move_number == -1;
bool in_check = false;
Tile *ep_tile = NULL;
Piece ep_piece;
memset(&ep_piece, 0, sizeof(ep_piece));
if (en_passant) { // remove piece that was captured via en passant
if (player->en_passant_move_number == -1) { // remove piece that was captured via en passant
ChessCoords ep_coords;
ep_coords.N = player->colour == White ? to->chess_coords.N - 1 : to->chess_coords.N + 1;
ep_coords.L = to->chess_coords.L;
@ -821,7 +815,7 @@ static bool chess_mock_move_valid(ChessState *state, const Player *player, Tile
}
chess_copy_piece(&ep_piece, &ep_tile->piece);
ep_tile->piece.type = NoPiece; // temporarily remove piece
ep_tile->piece.type = NoPiece;
}
Piece from_piece;
@ -837,8 +831,8 @@ static bool chess_mock_move_valid(ChessState *state, const Player *player, Tile
from->piece.type = from_piece.type;
chess_copy_piece(&to->piece, &to_piece);
if (en_passant) {
ep_tile->piece.type = ep_piece.type; // reset piece to original state
if (player->en_passant_move_number == -1) {
ep_tile->piece.type = ep_piece.type;
}
return !in_check;

View File

@ -26,7 +26,6 @@
#include "avatars.h"
#include "conference.h"
#include "friendlist.h"
#include "groupchats.h"
#include "help.h"
#include "line_info.h"
#include "log.h"
@ -43,6 +42,11 @@
#include "game_base.h"
#endif
extern char *DATA_FILE;
extern ToxWindow *prompt;
extern FriendsList Friends;
extern FriendRequests FrndRequests;
/* command functions */
void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
@ -157,12 +161,18 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
const char *id = argv[1];
const size_t arg_length = strlen(id);
const int space_idx = char_find(0, id, ' ');
const bool is_tox_id = arg_length >= (2 * TOX_ADDRESS_SIZE);
// we have to manually parse the message due to this command being a special case
if (space_idx > 0 && space_idx < arg_length - 1) {
snprintf(msg, sizeof(msg), "%s", &id[space_idx + 1]);
} else {
if (is_tox_id) {
// we have to manually parse the message due to this command being a special case
int idx = char_find(0, id, ' ');
if (idx > 0 && idx < arg_length - 1) {
snprintf(msg, sizeof(msg), "%s", &id[idx + 1]);
}
}
if (!msg[0]) {
char selfname[TOX_MAX_NAME_LENGTH];
tox_self_get_name(m, (uint8_t *) selfname);
@ -173,40 +183,34 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
char id_bin[TOX_ADDRESS_SIZE] = {0};
const bool is_domain = char_find(0, id, '@') != arg_length;
const bool valid_id_size = arg_length >= TOX_ADDRESS_SIZE * 2; // arg_length may include invite message
/* try to add tox ID */
if (is_tox_id) {
size_t i;
char xx[3];
uint32_t x;
if (is_domain) {
if (!name_lookup(self, m, id_bin, id, msg)) {
return;
for (i = 0; i < TOX_ADDRESS_SIZE; ++i) {
xx[0] = id[2 * i];
xx[1] = id[2 * i + 1];
xx[2] = 0;
if (sscanf(xx, "%02x", &x) != 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID.");
return;
}
id_bin[i] = x;
}
} else if (!valid_id_size) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID.");
return;
}
char xx[3];
uint32_t x = 0;
for (size_t i = 0; i < TOX_ADDRESS_SIZE; ++i) {
xx[0] = id[2 * i];
xx[1] = id[2 * i + 1];
xx[2] = 0;
if (sscanf(xx, "%02x", &x) != 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid Tox ID.");
if (friend_is_blocked(id_bin)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Friend is in your block list.");
return;
}
id_bin[i] = x;
cmd_add_helper(self, m, id_bin, msg);
} else { /* assume id is a username@domain address and do http name server lookup */
name_lookup(self, m, id_bin, id, msg);
}
if (friend_is_blocked(id_bin)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Friend is in your block list.");
return;
}
cmd_add_helper(self, m, id_bin, msg);
}
void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -466,146 +470,6 @@ void cmd_conference(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Conference [%d] created.", conferencenum);
}
void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open.");
return;
}
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group name required");
return;
}
const char *tmp_name = argv[1];
int len = strlen(tmp_name);
if (len == 0 || len > TOX_GROUP_MAX_GROUP_NAME_LENGTH) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid group name.");
return;
}
char name[TOX_GROUP_MAX_GROUP_NAME_LENGTH];
snprintf(name, sizeof(name), "%s", argv[1]);
size_t nick_length = tox_self_get_name_size(m);
char self_nick[TOX_MAX_NAME_LENGTH + 1];
tox_self_get_name(m, (uint8_t *) self_nick);
self_nick[nick_length] = '\0';
Tox_Err_Group_New err;
uint32_t groupnumber = tox_group_new(m, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *) name, len,
(const uint8_t *) self_nick, nick_length, &err);
if (err != TOX_ERR_GROUP_NEW_OK) {
switch (err) {
case TOX_ERR_GROUP_NEW_TOO_LONG: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group name length cannot exceed %d.",
TOX_GROUP_MAX_GROUP_NAME_LENGTH);
break;
}
case TOX_ERR_GROUP_NEW_EMPTY: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group name cannot be empty.");
break;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize (error %d).", err);
break;
}
}
return;
}
int init = init_groupchat_win(m, groupnumber, name, len, Group_Join_Type_Create);
if (init == -1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
tox_group_leave(m, groupnumber, NULL, 0, NULL);
} else if (init == -2) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,
"You have been kicked from a group. Close the window and try again.");
tox_group_leave(m, groupnumber, NULL, 0, NULL);
}
}
void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, " * Warning: Too many windows are open.");
return;
}
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Chat ID is required.");
return;
}
const char *chat_id = argv[1];
if (strlen(chat_id) != TOX_GROUP_CHAT_ID_SIZE * 2) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid chat ID");
return;
}
char id_bin[TOX_GROUP_CHAT_ID_SIZE] = {0};
size_t i;
char xch[3];
uint32_t x;
for (i = 0; i < TOX_GROUP_CHAT_ID_SIZE; ++i) {
xch[0] = chat_id[2 * i];
xch[1] = chat_id[2 * i + 1];
xch[2] = '\0';
if (sscanf(xch, "%02x", &x) != 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid chat ID.");
return;
}
id_bin[i] = x;
}
const char *passwd = NULL;
uint16_t passwd_len = 0;
if (argc > 1) {
passwd = argv[2];
passwd_len = strlen(passwd);
}
size_t nick_length = tox_self_get_name_size(m);
char self_nick[TOX_MAX_NAME_LENGTH + 1];
tox_self_get_name(m, (uint8_t *) self_nick);
self_nick[nick_length] = '\0';
Tox_Err_Group_Join err;
uint32_t groupnumber = tox_group_join(m, (uint8_t *) id_bin, (const uint8_t *) self_nick, nick_length,
(const uint8_t *) passwd, passwd_len, &err);
if (err != TOX_ERR_GROUP_JOIN_OK) {
if (err == TOX_ERR_GROUP_JOIN_TOO_LONG) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password length cannot exceed %d.", TOX_GROUP_MAX_PASSWORD_SIZE);
} else {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to join group (error %d).", err);
}
return;
}
int init = init_groupchat_win(m, groupnumber, NULL, 0, Group_Join_Type_Join);
if (init == -1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Group chat window failed to initialize.");
tox_group_leave(m, groupnumber, NULL, 0, NULL);
}
}
void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
UNUSED_VAR(window);
@ -909,8 +773,6 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
tox_self_set_status(m, status);
prompt_update_status(prompt, status);
set_status_all_groups(m, status);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Your status has been changed to %s.", status_str);

View File

@ -30,11 +30,9 @@ void cmd_accept(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZ
void cmd_add(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_clear(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_connect(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_groupchat(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_conference(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
#ifdef QRCODE

View File

@ -1,942 +0,0 @@
/* groupchat_commands.c
*
*
* Copyright (C) 2020 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic 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 3 of the License, or
* (at your option) any later version.
*
* Toxic 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 Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <string.h>
#include <stdlib.h>
#include "toxic.h"
#include "windows.h"
#include "line_info.h"
#include "misc_tools.h"
#include "log.h"
#include "groupchats.h"
extern GroupChat groupchats[MAX_GROUPCHAT_NUM];
void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
char chatid[TOX_GROUP_CHAT_ID_SIZE * 2 + 1] = {0};
char chat_public_key[TOX_GROUP_CHAT_ID_SIZE];
Tox_Err_Group_State_Queries err;
if (!tox_group_get_chat_id(m, self->num, (uint8_t *) chat_public_key, &err)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve the Chat ID (error %d).", err);
return;
}
for (size_t i = 0; i < TOX_GROUP_CHAT_ID_SIZE; ++i) {
char xx[3];
snprintf(xx, sizeof(xx), "%02X", chat_public_key[i] & 0xff);
strcat(chatid, xx);
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s", chatid);
}
void cmd_disconnect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
Tox_Err_Group_Disconnect err;
tox_group_disconnect(m, self->num, &err);
switch (err) {
case TOX_ERR_GROUP_DISCONNECT_OK: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Disconnected from group. Type '/rejoin' to reconnect.");
return;
}
case TOX_ERR_GROUP_DISCONNECT_ALREADY_DISCONNECTED: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Already disconnected. Type '/rejoin' to connect.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to disconnect from group. Error: %d", err);
return;
}
}
}
void cmd_group_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
UNUSED_VAR(window);
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Input required.");
return;
}
char nick[MAX_STR_SIZE];
snprintf(nick, sizeof(nick), "%s", argv[1]);
size_t len = strlen(nick);
if (!valid_nick(nick)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid name.");
return;
}
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
nick[len] = '\0';
set_nick_this_group(self, m, nick, len);
store_data(m, DATA_FILE);
}
void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified.");
return;
}
const char *nick = argv[1];
uint32_t peer_id;
if (group_get_peer_id_of_identifier(self, nick, &peer_id) != 0) {
return;
}
Tox_Err_Group_Set_Ignore err;
tox_group_set_ignore(m, self->num, peer_id, true, &err);
switch (err) {
case TOX_ERR_GROUP_SET_IGNORE_OK: {
break;
}
case TOX_ERR_GROUP_SET_IGNORE_SELF: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot ignore yourself.");
return;
}
case TOX_ERR_GROUP_SET_IGNORE_PEER_NOT_FOUND: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to toggle ignore on %s (error %d).", nick, err);
return;
}
}
line_info_add(self, true, NULL, NULL, SYS_MSG, 1, BLUE, "-!- Ignoring %s", nick);
group_toggle_peer_ignore(self->num, peer_id, true);
}
void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified.");
return;
}
const char *nick = argv[1];
uint32_t target_peer_id;
if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) {
return;
}
Tox_Err_Group_Mod_Kick_Peer err;
tox_group_mod_kick_peer(m, self->num, target_peer_id, &err);
switch (err) {
case TOX_ERR_GROUP_MOD_KICK_PEER_OK: {
char self_nick[TOX_MAX_NAME_LENGTH + 1];
get_group_self_nick_truncate(m, self_nick, self->num);
line_info_add(self, true, NULL, NULL, SYS_MSG, 1, RED, "-!- %s has been kicked by %s", nick, self_nick);
groupchat_onGroupPeerExit(self, m, self->num, target_peer_id, TOX_GROUP_EXIT_TYPE_KICK, nick, strlen(nick), NULL, 0);
return;
}
case TOX_ERR_GROUP_MOD_KICK_PEER_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to kick %s.", nick);
return;
}
case TOX_ERR_GROUP_MOD_KICK_PEER_SELF: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot kick yourself.");
return;
}
case TOX_ERR_GROUP_MOD_KICK_PEER_PEER_NOT_FOUND: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Specified nick or public key is invalid.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to kick %s from the group (error %d).", nick,
err);
return;
}
}
}
void cmd_list(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
GroupChat *chat = get_groupchat(self->num);
if (!chat) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch GroupChat object.");
return;
}
for (size_t i = 0; i < chat->max_idx; ++i) {
GroupPeer *peer = &chat->peer_list[i];
if (!peer->active) {
continue;
}
char pk_string[TOX_GROUP_PEER_PUBLIC_KEY_SIZE * 2 + 1] = {0};
for (size_t j = 0; j < TOX_GROUP_PEER_PUBLIC_KEY_SIZE; ++j) {
char d[3];
snprintf(d, sizeof(d), "%02X", peer->public_key[j] & 0xff);
strcat(pk_string, d);
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s : %s", pk_string, peer->name);
}
}
void cmd_mod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified.");
return;
}
const char *nick = argv[1];
uint32_t target_peer_id;
if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) {
return;
}
Tox_Err_Group_Self_Query s_err;
uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err);
if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch self peer_id.");
return;
}
Tox_Err_Group_Mod_Set_Role err;
tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_MODERATOR, &err);
switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_MODERATOR);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to promote moderators.");
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is already a moderator.", nick);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot make yourself a moderator.");
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to promote peer to moderator (error %d).", err);
return;
}
}
}
void cmd_unmod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified.");
return;
}
const char *nick = argv[1];
uint32_t target_peer_id;
if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) {
return;
}
Tox_Err_Group_Self_Query s_err;
uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err);
if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch self peer_id.");
return;
}
if (tox_group_peer_get_role(m, self->num, target_peer_id, NULL) != TOX_GROUP_ROLE_MODERATOR) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is not a moderator.", nick);
return;
}
Tox_Err_Group_Mod_Set_Role err;
tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_USER, &err);
switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_USER);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to unmod %s.", nick);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot remove your own moderator status.");
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to revoke moderator powers from %s (error %d).", nick,
err);
return;
}
}
}
void cmd_set_passwd(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
const char *passwd = NULL;
size_t len = 0;
if (argc > 0) {
passwd = argv[1];
len = strlen(passwd);
}
Tox_Err_Group_Founder_Set_Password err;
tox_group_founder_set_password(m, self->num, (uint8_t *) passwd, len, &err);
switch (err) {
case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK: {
if (len > 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password has been set to %s.", passwd);
} else {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password has been unset.");
}
return;
}
case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_TOO_LONG: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Password length must not exceed %d.",
TOX_GROUP_MAX_PASSWORD_SIZE);
return;
}
case TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the password.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to set password (error %d).", err);
return;
}
}
}
void cmd_set_peerlimit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
int maxpeers = 0;
if (argc < 1) {
Tox_Err_Group_State_Queries err;
uint32_t maxpeers = tox_group_get_peer_limit(m, self->num, &err);
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve peer limit (error %d).", err);
return;
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer limit is set to %d", maxpeers);
return;
}
maxpeers = atoi(argv[1]);
if (maxpeers <= 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer limit must be a value greater than 0.");
return;
}
Tox_Err_Group_Founder_Set_Peer_Limit err;
tox_group_founder_set_peer_limit(m, self->num, maxpeers, &err);
switch (err) {
case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer limit has been set to %d.", maxpeers);
return;
}
case TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the peer limit.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to set the peer limit (error %d).", err);
return;
}
}
}
void cmd_set_voice(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
Tox_Group_Voice_State voice_state;
if (argc < 1) {
Tox_Err_Group_State_Queries err;
voice_state = tox_group_get_voice_state(m, self->num, &err);
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve voice state (error %d).", err);
return;
}
switch (voice_state) {
case TOX_GROUP_VOICE_STATE_ALL: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state is set to ALL");
break;
}
case TOX_GROUP_VOICE_STATE_MODERATOR: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state is set to MODERATOR");
break;
}
case TOX_GROUP_VOICE_STATE_FOUNDER: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state is set to FOUNDER");
break;
}
default:
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error: Unknown voice state: %d", voice_state);
return;
}
return;
}
const char *vstate_str = argv[1];
if (strcasecmp(vstate_str, "mod") == 0) {
voice_state = TOX_GROUP_VOICE_STATE_MODERATOR;
} else if (strcasecmp(vstate_str, "founder") == 0) {
voice_state = TOX_GROUP_VOICE_STATE_FOUNDER;
} else if (strcasecmp(vstate_str, "all") == 0) {
voice_state = TOX_GROUP_VOICE_STATE_ALL;
} else {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0,
"voice state must be \"all\", \"mod\", or \"founder\".");
return;
}
Tox_Err_Group_Founder_Set_Voice_State err;
tox_group_founder_set_voice_state(m, self->num, voice_state, &err);
switch (err) {
case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Voice state has been set to %s.", vstate_str);
return;
}
case TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the voice state.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error setting voice state (error %d).", err);
return;
}
}
}
void cmd_set_privacy(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
const char *pstate_str = NULL;
Tox_Group_Privacy_State privacy_state;
if (argc < 1) {
Tox_Err_Group_State_Queries err;
privacy_state = tox_group_get_privacy_state(m, self->num, &err);
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve privacy state (error %d).", err);
return;
}
pstate_str = privacy_state == TOX_GROUP_PRIVACY_STATE_PRIVATE ? "private" : "public";
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Privacy state is set to %s.", pstate_str);
return;
}
pstate_str = argv[1];
if (strcasecmp(pstate_str, "private") != 0 && strcasecmp(pstate_str, "public") != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Privacy state must be \"private\" or \"public\".");
return;
}
privacy_state = strcasecmp(pstate_str,
"private") == 0 ? TOX_GROUP_PRIVACY_STATE_PRIVATE : TOX_GROUP_PRIVACY_STATE_PUBLIC;
Tox_Err_Group_Founder_Set_Privacy_State err;
tox_group_founder_set_privacy_state(m, self->num, privacy_state, &err);
switch (err) {
case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Privacy state has been set to %s.", pstate_str);
return;
}
case TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the privacy state.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error setting privacy state (error %d).", err);
return;
}
}
}
void cmd_set_topic_lock(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
Tox_Group_Topic_Lock topic_lock;
const char *tlock_str = NULL;
if (argc < 1) {
Tox_Err_Group_State_Queries err;
topic_lock = tox_group_get_topic_lock(m, self->num, &err);
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic lock (error %d).", err);
return;
}
tlock_str = topic_lock == TOX_GROUP_TOPIC_LOCK_ENABLED ? "Enabled" : "Disabled";
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic lock is %s.", tlock_str);
return;
}
tlock_str = argv[1];
if (strcasecmp(tlock_str, "on") != 0 && strcasecmp(tlock_str, "off") != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic lock must be \"on\" or \"off\".");
return;
}
topic_lock = strcasecmp(tlock_str, "on") == 0 ? TOX_GROUP_TOPIC_LOCK_ENABLED : TOX_GROUP_TOPIC_LOCK_DISABLED;
const char *display_str = (topic_lock == TOX_GROUP_TOPIC_LOCK_ENABLED) ? "enabled" : "disabled";
Tox_Err_Group_Founder_Set_Topic_Lock err;
tox_group_founder_set_topic_lock(m, self->num, topic_lock, &err);
switch (err) {
case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic lock has been %s.", display_str);
return;
}
case TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the topic lock.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Error setting topic lock (%d).", err);
return;
}
}
}
void cmd_silence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified.");
return;
}
const char *nick = argv[1];
uint32_t target_peer_id;
if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) {
return;
}
Tox_Err_Group_Self_Query s_err;
uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err);
if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch self peer_id.");
return;
}
Tox_Err_Group_Mod_Set_Role err;
tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_OBSERVER, &err);
switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_OBSERVER);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to silence %s.", nick);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is already silenced.", nick);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot silence yourself.");
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to silence %s (error %d).", nick, err);
return;
}
}
}
void cmd_unsilence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer name or public key must be specified.");
return;
}
const char *nick = argv[1];
uint32_t target_peer_id;
if (group_get_peer_id_of_identifier(self, nick, &target_peer_id) != 0) {
return;
}
if (tox_group_peer_get_role(m, self->num, target_peer_id, NULL) != TOX_GROUP_ROLE_OBSERVER) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is not silenced.", nick);
return;
}
Tox_Err_Group_Self_Query s_err;
uint32_t self_peer_id = tox_group_self_get_peer_id(m, self->num, &s_err);
if (s_err != TOX_ERR_GROUP_SELF_QUERY_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch self peer_id.");
return;
}
Tox_Err_Group_Mod_Set_Role err;
tox_group_mod_set_role(m, self->num, target_peer_id, TOX_GROUP_ROLE_USER, &err);
switch (err) {
case TOX_ERR_GROUP_MOD_SET_ROLE_OK: {
groupchat_onGroupModeration(self, m, self->num, self_peer_id, target_peer_id, TOX_GROUP_MOD_EVENT_USER);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to unsilence %s.", nick);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_ASSIGNMENT: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "%s is not silenced.", nick);
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_SELF: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot unsilence yourself.");
return;
}
case TOX_ERR_GROUP_MOD_SET_ROLE_PEER_NOT_FOUND: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to unsilence %s (error %d).", nick, err);
return;
}
}
}
void cmd_rejoin(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
Tox_Err_Group_Reconnect err;
if (!tox_group_reconnect(m, self->num, &err)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to rejoin group (error %d).", err);
return;
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Reconnecting to group...");
groupchat_rejoin(self, m);
}
void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
Tox_Err_Group_State_Queries err;
size_t tlen = tox_group_get_topic_size(m, self->num, &err);
if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic length (error %d).", err);
return;
}
if (tlen > 0) {
char cur_topic[TOX_GROUP_MAX_TOPIC_LENGTH + 1];
if (!tox_group_get_topic(m, self->num, (uint8_t *) cur_topic, &err)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to retrieve topic (error %d).", err);
return;
}
cur_topic[tlen] = 0;
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic is set to: %s", cur_topic);
} else {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic is not set.");
}
return;
}
const char *topic = argv[1];
Tox_Err_Group_Topic_Set err;
tox_group_set_topic(m, self->num, (uint8_t *) topic, strlen(topic), &err);
switch (err) {
case TOX_ERR_GROUP_TOPIC_SET_OK: {
/* handled below switch */
break;
}
case TOX_ERR_GROUP_TOPIC_SET_TOO_LONG: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Topic length must not exceed %d.", TOX_GROUP_MAX_TOPIC_LENGTH);
return;
}
case TOX_ERR_GROUP_TOPIC_SET_PERMISSIONS: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You do not have permission to set the topic.");
return;
}
case TOX_ERR_GROUP_TOPIC_SET_DISCONNECTED: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You are disconnected from the group.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to set the topic (error %d).", err);
return;
}
}
char self_nick[TOX_MAX_NAME_LENGTH + 1];
get_group_self_nick_truncate(m, self_nick, self->num);
line_info_add(self, true, NULL, NULL, SYS_MSG, 1, MAGENTA, "-!- You set the topic to: %s", topic);
char tmp_event[MAX_STR_SIZE];
snprintf(tmp_event, sizeof(tmp_event), "set topic to %s", topic);
write_to_log(tmp_event, self_nick, self->chatwin->log, true);
}
void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer must be specified.");
return;
}
const char *nick = argv[1];
uint32_t peer_id;
if (group_get_peer_id_of_identifier(self, nick, &peer_id) != 0) {
return;
}
Tox_Err_Group_Set_Ignore err;
tox_group_set_ignore(m, self->num, peer_id, false, &err);
switch (err) {
case TOX_ERR_GROUP_SET_IGNORE_OK: {
break;
}
case TOX_ERR_GROUP_SET_IGNORE_SELF: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "You cannot unignore yourself.");
return;
}
case TOX_ERR_GROUP_SET_IGNORE_PEER_NOT_FOUND: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "The specified nick or public key is invalid.");
return;
}
default: {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to toggle ignore on %s (error %d).", nick, err);
return;
}
}
line_info_add(self, true, NULL, NULL, SYS_MSG, 1, BLUE, "-!- You are no longer ignoring %s", nick);
group_toggle_peer_ignore(self->num, peer_id, false);
}
void cmd_whois(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
if (argc < 1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Peer must be specified.");
return;
}
GroupChat *chat = get_groupchat(self->num);
if (!chat) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to fetch GroupChat object.");
return;
}
const char *identifier = argv[1];
bool is_public_key = false;
for (size_t i = 0; i < chat->max_idx && !is_public_key; ++i) {
uint32_t peer_id;
if (group_get_public_key_peer_id(self->num, identifier, &peer_id) == 0) {
is_public_key = true;
} else {
GroupPeer *peer = &chat->peer_list[i];
if (!peer->active) {
continue;
}
if (strcmp(identifier, peer->name) != 0) {
continue;
}
peer_id = peer->peer_id;
}
int peer_index = get_peer_index(self->num, peer_id);
if (peer_index < 0) {
continue;
}
GroupPeer *peer = &chat->peer_list[peer_index];
const char *status_str = "Online";
if (peer->status == TOX_USER_STATUS_BUSY) {
status_str = "Busy";
} else if (peer->status == TOX_USER_STATUS_AWAY) {
status_str = "Away";
}
const char *role_str = "User";
if (peer->role == TOX_GROUP_ROLE_FOUNDER) {
role_str = "Founder";
} else if (peer->role == TOX_GROUP_ROLE_MODERATOR) {
role_str = "Moderator";
} else if (peer->role == TOX_GROUP_ROLE_OBSERVER) {
role_str = "Observer";
}
char last_seen_str[128];
get_elapsed_time_str_alt(last_seen_str, sizeof(last_seen_str),
get_unix_time() - peer->last_active);
char pk_string[TOX_GROUP_PEER_PUBLIC_KEY_SIZE * 2 + 1] = {0};
for (size_t i = 0; i < TOX_GROUP_PEER_PUBLIC_KEY_SIZE; ++i) {
char d[3];
snprintf(d, sizeof(d), "%02X", peer->public_key[i] & 0xff);
strcat(pk_string, d);
}
Tox_Err_Group_Peer_Query conn_err;
Tox_Connection connection_type = tox_group_peer_get_connection_status(m, self->num, peer_id, &conn_err);
const char *connection_type_str = "Unknown";
if (conn_err == TOX_ERR_GROUP_PEER_QUERY_OK || connection_type != TOX_CONNECTION_NONE) {
connection_type_str = connection_type == TOX_CONNECTION_UDP ? "UDP" : "TCP";
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Public key: %s", pk_string);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Name: %s", peer->name);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Role: %s", role_str);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Status: %s", status_str);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Connection: %s", connection_type_str);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Last active: %s", last_seen_str);
}
}

View File

@ -1,51 +0,0 @@
/* groupchat_commands.h
*
*
* Copyright (C) 2020 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic 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 3 of the License, or
* (at your option) any later version.
*
* Toxic 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 Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef GROUPCHAT_COMMANDS_H
#define GROUPCHAT_COMMANDS_H
#include "windows.h"
#include "toxic.h"
void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_disconnect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_group_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_kick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_list(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_mod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_prune(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_set_passwd(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_set_peerlimit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_set_privacy(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_set_voice(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_set_topic_lock(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_rejoin(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_silence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_unsilence(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_unmod(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_whois(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
#endif /* GROUPCHAT_COMMANDS_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,120 +0,0 @@
/* groupchats.h
*
*
* Copyright (C) 2020 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic 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 3 of the License, or
* (at your option) any later version.
*
* Toxic 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 Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef GROUPCHATS_H
#define GROUPCHATS_H
#include "toxic.h"
#include "windows.h"
#ifndef SIDEWAR_WIDTH
#define SIDEBAR_WIDTH 16
#endif
#define MAX_GROUPCHAT_NUM (MAX_WINDOWS_NUM - 2)
typedef enum Group_Join_Type {
Group_Join_Type_Create,
Group_Join_Type_Join,
Group_Join_Type_Load,
} Group_Join_Type;
typedef struct GroupPeer {
bool active;
char name[TOX_MAX_NAME_LENGTH];
size_t name_length;
char prev_name[TOX_MAX_NAME_LENGTH];
uint32_t peer_id;
uint8_t public_key[TOX_GROUP_PEER_PUBLIC_KEY_SIZE];
TOX_USER_STATUS status;
Tox_Group_Role role;
bool is_ignored;
uint64_t last_active;
} GroupPeer;
typedef struct {
GroupPeer *peer_list;
char **name_list; /* List of peer names, needed for tab completion */
uint32_t num_peers; /* Number of peers in the chat/name_list array */
uint32_t max_idx; /* Maximum peer list index - 1 */
uint8_t **ignored_list; /* List of keys of peers that we're ignoring */
uint16_t num_ignored;
char group_name[TOX_GROUP_MAX_GROUP_NAME_LENGTH + 1];
size_t group_name_length;
uint32_t groupnumber;
bool active;
uint64_t time_connected; /* The time we successfully connected to the group */
int chatwin;
int side_pos; /* current position of the sidebar - used for scrolling up and down */
} GroupChat;
void exit_groupchat(ToxWindow *self, Tox *m, uint32_t groupnumber, const char *partmessage, size_t length);
int init_groupchat_win(Tox *m, uint32_t groupnumber, const char *groupname, size_t length, Group_Join_Type join_type);
void set_nick_this_group(ToxWindow *self, Tox *m, const char *new_nick, size_t length);
void set_status_all_groups(Tox *m, uint8_t status);
int get_peer_index(uint32_t groupnumber, uint32_t peer_id);
void groupchat_onGroupPeerExit(ToxWindow *self, Tox *m, uint32_t groupnumber, uint32_t peer_id,
Tox_Group_Exit_Type exit_type,
const char *name, size_t name_len, const char *partmessage, size_t len);
void groupchat_onGroupModeration(ToxWindow *self, Tox *m, uint32_t groupnumber, uint32_t src_peer_id,
uint32_t tgt_peer_id, Tox_Group_Mod_Event type);
void groupchat_rejoin(ToxWindow *self, Tox *m);
/* Puts the peer_id associated with `identifier` in `peer_id`. The string may be
* either a nick or a public key.
*
* On failure, `peer_id` is set to (uint32_t)-1.
*
* This function is intended to be a helper for groupchat_commands.c and will print
* error messages to `self`.
* Return 0 on success.
* Return -1 if the identifier does not correspond with a peer in the group.
* Return -2 if the identifier is a nick and the nick is in use by multiple peers.
*/
int group_get_peer_id_of_identifier(ToxWindow *self, const char *identifier, uint32_t *peer_id);
/* Gets the peer_id associated with `public_key`.
*
* Returns 0 on success.
* Returns -1 on failure or if `public_key` is invalid.
*/
int group_get_public_key_peer_id(uint32_t groupnumber, const char *public_key, uint32_t *peer_id);
/* destroys and re-creates groupchat window */
void redraw_groupchat_win(ToxWindow *self);
/*
* Return a GroupChat pointer associated with groupnumber.
* Return NULL if groupnumber is invalid.
*/
GroupChat *get_groupchat(uint32_t groupnumber);
/**
* Toggles the ignore status of the peer associated with `peer_id`.
*/
void group_toggle_peer_ignore(uint32_t groupnumber, int peer_id, bool ignore);
#endif /* #define GROUPCHATS_H */

View File

@ -110,12 +110,6 @@ static void help_draw_menu(ToxWindow *self)
wattroff(win, A_BOLD | COLOR_PAIR(BLUE));
wprintw(win, "nference commands\n");
wprintw(win, " g");
wattron(win, A_BOLD | COLOR_PAIR(BLUE));
wprintw(win, "r");
wattroff(win, A_BOLD | COLOR_PAIR(BLUE));
wprintw(win, "oupchat commands\n");
#ifdef PYTHON
wattron(win, A_BOLD | COLOR_PAIR(BLUE));
wprintw(win, " p");
@ -177,18 +171,16 @@ static void help_draw_global(ToxWindow *self)
wprintw(win, " /add <addr> <msg> : Add contact with optional message\n");
wprintw(win, " /accept <id> : Accept friend request\n");
wprintw(win, " /avatar <path> : Set an avatar (leave path empty to unset)\n");
wprintw(win, " /conference <type> : Create a conference where type: text | audio\n");
wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n");
wprintw(win, " /decline <id> : Decline friend request\n");
wprintw(win, " /requests : List pending friend requests\n");
wprintw(win, " /connect <ip> <port> <key> : Manually connect to a DHT node\n");
wprintw(win, " /status <type> : Set status (Online, Busy, Away)\n");
wprintw(win, " /note <msg> : Set a personal note\n");
wprintw(win, " /nick <name> : Set your global name (doesn't affect groups)\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, " /log <on> or <off> : Enable/disable logging\n");
wprintw(win, " /conference <type> : Create a conference where type: text | audio\n");
wprintw(win, " /myid : Print your Tox ID\n");
wprintw(win, " /group <name> : Create a new group chat\n");
wprintw(win, " /join <chatid> : Join a groupchat using a Chat ID\n");
#ifdef GAMES
wprintw(win, " /game : Play a game\n");
#endif /* GAMES */
@ -246,10 +238,8 @@ static void help_draw_chat(ToxWindow *self)
wprintw(win, "Chat Commands:\n");
wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " /cinvite <n> : Invite contact to a conference \n");
wprintw(win, " /cjoin : Join a pending conference\n");
wprintw(win, " /invite <n> : Invite contact to a groupchat \n");
wprintw(win, " /gaccept <password> : Accept a pending groupchat invite\n");
wprintw(win, " /invite <n> : Invite contact to a conference \n");
wprintw(win, " /join : Join a pending conference\n");
wprintw(win, " /sendfile <path> : Send a file\n");
wprintw(win, " /savefile <id> : Receive a file\n");
wprintw(win, " /cancel <type> <id> : Cancel file transfer where type: in|out\n");
@ -288,45 +278,6 @@ static void help_draw_chat(ToxWindow *self)
wnoutrefresh(win);
}
static void help_draw_groupchats(ToxWindow *self)
{
WINDOW *win = self->help->win;
wmove(win, 1, 1);
wattron(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, "Groupchat commands:\n");
wattroff(win, A_BOLD | COLOR_PAIR(RED));
wprintw(win, " /chatid : Print this group's ID\n");
wprintw(win, " /close <m> : Leave the group with an optional part message\n");
wprintw(win, " /disconnect : Disconnect from the group (credentials retained)\n");
wprintw(win, " /ignore <name> : Ignore a peer\n");
wprintw(win, " /unignore <name> : Unignore an ignored peer\n");
wprintw(win, " /kick <name> : Remove a peer from the group\n");
wprintw(win, " /list : Print a list of peers currently in the group\n");
wprintw(win, " /locktopic : Set the topic lock: on | off\n");
wprintw(win, " /mod <name> : Promote a peer to moderator\n");
wprintw(win, " /nick <name> : Set your name for this group only\n");
wprintw(win, " /passwd <s> : Set a password needed to join the group\n");
wprintw(win, " /peerlimit <n> : Set the maximum number of peers that can join\n");
wprintw(win, " /privacy <state> : Set the privacy state: private | public\n");
wprintw(win, " /rejoin : Reconnect to the groupchat\n");
wprintw(win, " /silence <name> : Silence a peer for the entire group\n");
wprintw(win, " /unsilence <name> : Unsilence a silenced peer\n");
wprintw(win, " /status <type> : Set your status\n");
wprintw(win, " /topic <m> : Set the group topic\n");
wprintw(win, " /unmod <name> : Demote a moderator\n");
wprintw(win, " /voice <state> : Set the voice state: all | mod | founder\n");
wprintw(win, " /whisper <name> <m> : Send a private message to a peer\n");
wprintw(win, " /whois <name> : Print whois info for a peer\n");
help_draw_bottom_menu(win);
box(win, ACS_VLINE, ACS_HLINE);
wnoutrefresh(win);
}
static void help_draw_keys(ToxWindow *self)
{
WINDOW *win = self->help->win;
@ -434,21 +385,18 @@ void help_onKey(ToxWindow *self, wint_t key)
break;
case L'c':
height = 12;
#ifdef VIDEO
height += 15;
help_init_window(self, 26, 80);
#elif AUDIO
height += 5;
help_init_window(self, 21, 80);
#else
help_init_window(self, 11, 80);
#endif
#ifdef GAMES
height += 1;
#endif
help_init_window(self, height, 80);
self->help->type = HELP_CHAT;
break;
case L'g':
height = 24;
height = 22;
#ifdef VIDEO
height += 8;
#elif AUDIO
@ -495,11 +443,6 @@ void help_onKey(ToxWindow *self, wint_t key)
help_init_menu(self);
self->help->type = HELP_MENU;
break;
case L'r':
help_init_window(self, 27, 80);
self->help->type = HELP_GROUP;
break;
}
}
@ -536,9 +479,5 @@ void help_onDraw(ToxWindow *self)
help_draw_plugin(self);
break;
#endif /* PYTHON */
case HELP_GROUP:
help_draw_groupchats(self);
break;
}
}

View File

@ -29,7 +29,6 @@
typedef enum {
HELP_MENU,
HELP_GLOBAL,
HELP_GROUP,
HELP_CHAT,
HELP_CONFERENCE,
HELP_KEYS,

View File

@ -30,7 +30,6 @@
#include "line_info.h"
#include "misc_tools.h"
#include "notify.h"
#include "groupchats.h"
#include "settings.h"
#include "toxic.h"
#include "toxic_strings.h"
@ -338,9 +337,6 @@ bool input_handle(ToxWindow *self, wint_t key, int x, int mx_x)
if (self->type == WINDOW_TYPE_CONFERENCE) {
self->show_peerlist ^= 1;
redraw_conference_win(self);
} else if (self->type == WINDOW_TYPE_GROUPCHAT) {
self->show_peerlist ^= 1;
redraw_groupchat_win(self);
}
match = true;

View File

@ -20,17 +20,12 @@
*
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* needed for wcswidth() */
#endif
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "conference.h"
#include "groupchats.h"
#include "line_info.h"
#include "message_queue.h"
#include "misc_tools.h"
@ -142,23 +137,19 @@ static struct line_info *line_info_ret_queue(struct history *hst)
* Return 0 if string does not contain a newline byte.
* Return -1 if printing was aborted.
*/
static int print_n_chars(WINDOW *win, const wchar_t *s, size_t n, int max_y)
static int print_n_chars(WINDOW *win, const char *s, size_t n, int max_y)
{
// we use an array to represent a single wchar in order to get around an ncurses
// bug with waddnwstr() that overreads the memory address by one byte when
// supplied with a single wchar.
wchar_t ch[2] = {0};
bool newline = false;
char ch;
for (size_t i = 0; i < n && (ch[0] = s[i]); ++i) {
if (ch[0] == L'\n') {
for (size_t i = 0; i < n && (ch = s[i]); ++i) {
if (ch == '\n') {
newline = true;
int x;
int y;
getyx(win, y, x);
UNUSED_VAR(x);
getyx(win, y, x);
// make sure cursor will wrap correctly after newline to prevent display bugs
if (y + 1 >= max_y) {
@ -167,17 +158,7 @@ static int print_n_chars(WINDOW *win, const wchar_t *s, size_t n, int max_y)
}
if (win) {
#ifdef HAVE_WIDECHAR
waddnwstr(win, ch, 1);
#else
char b;
if (wcstombs(&b, ch, sizeof(char)) != 1) {
continue;
}
wprintw(win, "%c", b);
#endif // HAVE_WIDECHAR
wprintw(win, "%c", ch);
}
}
@ -187,10 +168,10 @@ static int print_n_chars(WINDOW *win, const wchar_t *s, size_t n, int max_y)
/* Returns the index of the last space character in `s` found before `limit`.
* Returns -1 if no space is found.
*/
static int rspace_index(const wchar_t *s, int limit)
static int rspace_index(const char *s, int limit)
{
for (int i = limit; i >= 0; --i) {
if (s[i] == L' ') {
if (s[i] == ' ') {
return i;
}
}
@ -201,12 +182,12 @@ static int rspace_index(const wchar_t *s, int limit)
/* Returns the first index in `s` containing a newline byte found before `limit`.
* Returns -1 if no newline is found.
*/
static int newline_index(const wchar_t *s, int limit)
static int newline_index(const char *s, int limit)
{
wchar_t ch;
char ch;
for (int i = 0; i < limit && (ch = s[i]); ++i) {
if (ch == L'\n') {
if (ch == '\n') {
return i;
}
}
@ -215,13 +196,13 @@ static int newline_index(const wchar_t *s, int limit)
}
/* Returns the number of newline bytes in `s` */
static unsigned int newline_count(const wchar_t *s)
static unsigned int newline_count(const char *s)
{
wchar_t ch;
char ch;
unsigned int count = 0;
for (size_t i = 0; (ch = s[i]); ++i) {
if (ch == L'\n') {
if (ch == '\n') {
++count;
}
}
@ -244,10 +225,10 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
int y;
UNUSED_VAR(y);
const wchar_t *msg = line->msg;
uint16_t length = line->msg_width;
const char *msg = line->msg;
uint16_t length = line->msg_len;
uint16_t lines = 0;
const int x_start = line->len - line->msg_width - 1; // manually keep track of x position because ncurses sucks
const int x_start = line->len - line->msg_len - 1; // manually keep track of x position because ncurses sucks
int x_limit = max_x - x_start;
if (x_limit <= 1) {
@ -264,7 +245,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
}
if (length < x_limit) {
const int p_ret = print_n_chars(win, msg, length, max_y);
int p_ret = print_n_chars(win, msg, length, max_y);
if (p_ret == 1) {
lines += newline_count(msg);
@ -276,7 +257,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
break;
}
const int newline_idx = newline_index(msg, x_limit - 1);
int newline_idx = newline_index(msg, x_limit - 1);
if (newline_idx >= 0) {
if (print_n_chars(win, msg, newline_idx + 1, max_y) == -1) {
@ -290,7 +271,7 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
continue;
}
const int space_idx = rspace_index(msg, x_limit - 1);
int space_idx = rspace_index(msg, x_limit - 1);
if (space_idx >= 1) {
if (print_n_chars(win, msg, space_idx, max_y) == -1) {
@ -339,45 +320,14 @@ static int print_wrap(WINDOW *win, struct line_info *line, int max_x, int max_y)
return 0;
}
/* Converts `msg` into a widechar string and puts the result in `buf`.
*
* Returns the widechar width of the string.
*/
static uint16_t line_info_add_msg(wchar_t *buf, size_t buf_size, const char *msg)
{
if (msg == NULL || msg[0] == '\0') {
return 0;
}
const wint_t wc_msg_len = mbs_to_wcs_buf(buf, msg, buf_size);
if (wc_msg_len > 0 && wc_msg_len < buf_size) {
buf[wc_msg_len] = L'\0';
int width = wcswidth(buf, wc_msg_len);
if (width == -1) { // the best we can do on failure is to fall back to strlen
width = strlen(msg);
}
return (uint16_t)width;
} else {
fprintf(stderr, "Failed to convert string '%s' to widechar\n", msg);
const wchar_t *err = L"Failed to parse message";
uint16_t width = (uint16_t)wcslen(err);
wmemcpy(buf, err, width);
buf[width] = L'\0';
return width;
}
}
static void line_info_init_line(ToxWindow *self, struct line_info *line)
{
int y2;
int x2;
getmaxyx(self->window, y2, x2);
UNUSED_VAR(y2);
getmaxyx(self->window, y2, x2);
const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT;
const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2;
@ -422,29 +372,18 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
switch (type) {
case IN_ACTION:
/* fallthrough */
case OUT_ACTION_READ:
/* fallthrough */
case OUT_ACTION:
len += strlen(user_settings->line_normal) + 2; // two spaces
break;
case IN_MSG:
case OUT_MSG_READ:
/* fallthrough */
case OUT_MSG:
len += strlen(user_settings->line_normal) + 3; // two spaces and a ':' char
break;
case IN_PRVT_MSG:
/* fallthrough */
case OUT_PRVT_MSG:
len += strlen(user_settings->line_special) + 3;
break;
case CONNECTION:
len += strlen(user_settings->line_join) + 2; // two spaces
break;
@ -469,8 +408,13 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
break;
}
const uint16_t msg_width = line_info_add_msg(new_line->msg, sizeof(new_line->msg), frmt_msg);
len += msg_width;
uint16_t msg_len = 0;
if (frmt_msg[0]) {
snprintf(new_line->msg, sizeof(new_line->msg), "%s", frmt_msg);
msg_len = strlen(new_line->msg);
len += msg_len;
}
if (show_timestamp) {
get_time_str(new_line->timestr, sizeof(new_line->timestr));
@ -489,7 +433,7 @@ int line_info_add(ToxWindow *self, bool show_timestamp, const char *name1, const
new_line->id = (hst->line_end->id + 1 + hst->queue_size) % INT_MAX;
new_line->len = len;
new_line->msg_width = msg_width;
new_line->msg_len = msg_len;
new_line->type = type;
new_line->bold = bold;
new_line->colour = colour;
@ -558,7 +502,7 @@ void line_info_print(ToxWindow *self)
return;
}
if (self->type == WINDOW_TYPE_CONFERENCE || self->type == WINDOW_TYPE_GROUPCHAT) {
if (self->type == WINDOW_TYPE_CONFERENCE) {
wmove(win, 0, 0);
} else {
wmove(win, TOP_BAR_HEIGHT, 0);
@ -573,14 +517,15 @@ void line_info_print(ToxWindow *self)
const int max_y = y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT;
const int max_x = self->show_peerlist ? x2 - 1 - SIDEBAR_WIDTH : x2;
uint16_t numlines = line->format_lines;
int print_ret = 0;
while (line && numlines++ <= max_y) {
while (line && numlines++ <= max_y && print_ret == 0) {
int y;
int x;
getyx(win, y, x);
UNUSED_VAR(y);
getyx(win, y, x);
if (x > 0) { // Prevents us from printing off the screen
break;
}
@ -594,7 +539,7 @@ void line_info_print(ToxWindow *self)
case OUT_MSG_READ:
/* fallthrough */
case IN_MSG: {
case IN_MSG:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
wattroff(win, COLOR_PAIR(BLUE));
@ -611,60 +556,18 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s %s: ", user_settings->line_normal, line->name1);
wattroff(win, COLOR_PAIR(nameclr));
if (line->msg[0] == L'\0') {
if (line->msg[0] == 0) {
waddch(win, '\n');
break;
}
if (line->msg[0] == L'>') {
wattron(win, COLOR_PAIR(GREEN));
} else if (line->msg[0] == L'<') {
wattron(win, COLOR_PAIR(RED));
}
print_wrap(win, line, max_x, max_y);
if (line->msg[0] == L'>') {
wattroff(win, COLOR_PAIR(GREEN));
} else if (line->msg[0] == L'<') {
wattroff(win, COLOR_PAIR(RED));
}
waddch(win, '\n');
break;
}
case IN_PRVT_MSG:
/* fallthrough */
case OUT_PRVT_MSG: {
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
wattroff(win, COLOR_PAIR(BLUE));
int nameclr = GREEN;
if (line->colour) {
nameclr = line->colour;
} else if (type == IN_MSG) {
nameclr = CYAN;
}
wattron(win, COLOR_PAIR(nameclr));
wprintw(win, "%s %s: ", (type != OUT_PRVT_MSG && type != IN_PRVT_MSG) ?
user_settings->line_normal :
user_settings->line_special,
line->name1);
wattroff(win, COLOR_PAIR(nameclr));
if (line->msg[0] == '>') {
wattron(win, COLOR_PAIR(GREEN));
} else if (line->msg[0] == '<') {
wattron(win, COLOR_PAIR(RED));
}
print_wrap(win, line, max_x, max_y);
print_ret = print_wrap(win, line, max_x, max_y);
if (line->msg[0] == '>') {
wattroff(win, COLOR_PAIR(GREEN));
@ -674,7 +577,6 @@ void line_info_print(ToxWindow *self)
waddch(win, '\n');
break;
}
case OUT_ACTION_READ:
@ -682,21 +584,20 @@ void line_info_print(ToxWindow *self)
case OUT_ACTION:
/* fallthrough */
case IN_ACTION: {
case IN_ACTION:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
wattroff(win, COLOR_PAIR(BLUE));
wattron(win, COLOR_PAIR(YELLOW));
wprintw(win, "%s %s ", user_settings->line_normal, line->name1);
print_wrap(win, line, max_x, max_y);
print_ret = print_wrap(win, line, max_x, max_y);
wattroff(win, COLOR_PAIR(YELLOW));
waddch(win, '\n');
break;
}
case SYS_MSG: {
case SYS_MSG:
if (line->timestr[0]) {
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
@ -711,7 +612,7 @@ void line_info_print(ToxWindow *self)
wattron(win, COLOR_PAIR(line->colour));
}
print_wrap(win, line, max_x, max_y);
print_ret = print_wrap(win, line, max_x, max_y);
waddch(win, '\n');
if (line->bold) {
@ -723,22 +624,20 @@ void line_info_print(ToxWindow *self)
}
break;
}
case PROMPT: {
case PROMPT:
wattron(win, COLOR_PAIR(GREEN));
wprintw(win, "$ ");
wattroff(win, COLOR_PAIR(GREEN));
if (line->msg[0] != L'\0') {
print_wrap(win, line, max_x, max_y);
if (line->msg[0]) {
print_ret = print_wrap(win, line, max_x, max_y);
}
waddch(win, '\n');
break;
}
case CONNECTION: {
case CONNECTION:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
wattroff(win, COLOR_PAIR(BLUE));
@ -750,15 +649,14 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s ", line->name1);
wattroff(win, A_BOLD);
print_wrap(win, line, max_x, max_y);
print_ret = print_wrap(win, line, max_x, max_y);
waddch(win, '\n');
wattroff(win, COLOR_PAIR(line->colour));
break;
}
case DISCONNECTION: {
case DISCONNECTION:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
wattroff(win, COLOR_PAIR(BLUE));
@ -770,15 +668,14 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s ", line->name1);
wattroff(win, A_BOLD);
print_wrap(win, line, max_x, max_y);
print_ret = print_wrap(win, line, max_x, max_y);
waddch(win, '\n');
wattroff(win, COLOR_PAIR(line->colour));
break;
}
case NAME_CHANGE: {
case NAME_CHANGE:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s ", line->timestr);
wattroff(win, COLOR_PAIR(BLUE));
@ -789,7 +686,7 @@ void line_info_print(ToxWindow *self)
wprintw(win, "%s", line->name1);
wattroff(win, A_BOLD);
print_wrap(win, line, max_x, max_y);
print_ret = print_wrap(win, line, max_x, max_y);
wattron(win, A_BOLD);
wprintw(win, "%s\n", line->name2);
@ -797,7 +694,6 @@ void line_info_print(ToxWindow *self)
wattroff(win, COLOR_PAIR(MAGENTA));
break;
}
}
line = line->next;
@ -852,9 +748,10 @@ void line_info_set(ToxWindow *self, uint32_t id, char *msg)
while (line) {
if (line->id == id) {
const uint16_t new_width = line_info_add_msg(line->msg, sizeof(line->msg), msg);
line->len = line->len - line->msg_width + new_width;
line->msg_width = new_width;
size_t new_len = strlen(msg);
line->len = line->len - line->msg_len + new_len;
line->msg_len = new_len;
snprintf(line->msg, sizeof(line->msg), "%s", msg);
return;
}

View File

@ -39,8 +39,6 @@ typedef enum LINE_TYPE {
IN_ACTION,
OUT_ACTION,
OUT_ACTION_READ, /* same as OUT_MSG_READ but for actions */
IN_PRVT_MSG, /* PRVT should only be used for groups */
OUT_PRVT_MSG,
PROMPT,
CONNECTION,
DISCONNECTION,
@ -48,11 +46,11 @@ typedef enum LINE_TYPE {
} LINE_TYPE;
struct line_info {
char timestr[TIME_STR_SIZE];
char name1[TOXIC_MAX_NAME_LENGTH + 1];
char name2[TOXIC_MAX_NAME_LENGTH + 1];
wchar_t msg[MAX_LINE_INFO_MSG_SIZE];
time_t timestamp;
char timestr[TIME_STR_SIZE];
char name1[TOXIC_MAX_NAME_LENGTH + 1];
char name2[TOXIC_MAX_NAME_LENGTH + 1];
char msg[MAX_LINE_INFO_MSG_SIZE];
time_t timestamp;
uint8_t type;
uint8_t bold;
uint8_t colour;
@ -60,7 +58,7 @@ struct line_info {
bool read_flag; /* true if a message has been flagged as read */
uint32_t id;
uint16_t len; /* combined length of entire line */
uint16_t msg_width; /* width of the message */
uint16_t msg_len; /* length of the message */
uint16_t format_lines; /* number of lines the combined string takes up (dynamically set) */
struct line_info *prev;

View File

@ -62,21 +62,21 @@ static int get_log_path(char *dest, int destsize, const char *name, const char *
/* first 6 bytes of selfkey */
char self_id[32] = {0};
path_len += KEY_IDENT_BYTES;
path_len += KEY_IDENT_DIGITS * 2;
sprintf(&self_id[0], "%02X", selfkey[0] & 0xff);
sprintf(&self_id[2], "%02X", selfkey[1] & 0xff);
sprintf(&self_id[4], "%02X", selfkey[2] & 0xff);
self_id[KEY_IDENT_BYTES] = '\0';
self_id[KEY_IDENT_DIGITS * 2] = '\0';
char other_id[32] = {0};
if (otherkey) {
/* first 6 bytes of otherkey */
path_len += KEY_IDENT_BYTES;
path_len += KEY_IDENT_DIGITS * 2;
sprintf(&other_id[0], "%02X", otherkey[0] & 0xff);
sprintf(&other_id[2], "%02X", otherkey[1] & 0xff);
sprintf(&other_id[4], "%02X", otherkey[2] & 0xff);
other_id[KEY_IDENT_BYTES] = '\0';
other_id[KEY_IDENT_DIGITS * 2] = '\0';
}
if (path_len >= destsize) {

View File

@ -48,7 +48,7 @@ void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type,
return;
}
struct cqueue_msg *new_m = calloc(1, sizeof(struct cqueue_msg));
struct cqueue_msg *new_m = malloc(sizeof(struct cqueue_msg));
if (new_m == NULL) {
exit_toxic_err("failed in cqueue_message", FATALERR_MEMORY);
@ -62,7 +62,6 @@ void cqueue_add(struct chat_queue *q, const char *msg, size_t len, uint8_t type,
new_m->time_added = get_unix_time();
new_m->receipt = -1;
new_m->next = NULL;
new_m->noread_flag = false;
if (q->root == NULL) {
new_m->prev = NULL;
@ -204,7 +203,7 @@ void cqueue_try_send(ToxWindow *self, Tox *m)
return;
}
Tox_Err_Friend_Send_Message err;
TOX_ERR_FRIEND_SEND_MESSAGE err;
Tox_Message_Type type = msg->type == OUT_MSG ? TOX_MESSAGE_TYPE_NORMAL : TOX_MESSAGE_TYPE_ACTION;
uint32_t receipt = tox_friend_send_message(m, self->num, type, (uint8_t *) msg->message, msg->len, &err);

View File

@ -136,26 +136,6 @@ void get_elapsed_time_str(char *buf, int bufsize, time_t secs)
}
}
/* Converts seconds to string in format H hours, m minutes, s seconds */
void get_elapsed_time_str_alt(char *buf, int bufsize, uint64_t secs)
{
if (!secs) {
return;
}
long int seconds = secs % 60;
long int minutes = (secs % 3600) / 60;
long int hours = secs / 3600;
if (!minutes && !hours) {
snprintf(buf, bufsize, "%ld seconds", seconds);
} else if (!hours) {
snprintf(buf, bufsize, "%ld minutes, %ld seconds", minutes, seconds);
} else {
snprintf(buf, bufsize, "%ld hours, %ld minutes, %ld seconds", hours, minutes, seconds);
}
}
/*
* Converts a hexidecimal string representation of a Tox public key to binary format and puts
* the result in output.
@ -168,7 +148,7 @@ void get_elapsed_time_str_alt(char *buf, int bufsize, uint64_t secs)
*/
int tox_pk_string_to_bytes(const char *hex_string, size_t hex_len, char *output, size_t output_size)
{
if (output_size != TOX_PUBLIC_KEY_SIZE || hex_len != output_size * 2) {
if (output_size != TOX_PUBLIC_KEY_SIZE || hex_len > output_size * 2) {
return -1;
}
@ -308,7 +288,7 @@ int qsort_strcasecmp_hlpr(const void *str1, const void *str2)
/* case-insensitive string compare function for use with qsort */
int qsort_ptr_char_array_helper(const void *str1, const void *str2)
{
return strcasecmp(*(const char *const *)str1, *(const char *const *)str2);
return strcasecmp(*(char **)str1, *(char **)str2);
}
static const char invalid_chars[] = {'/', '\n', '\t', '\v', '\r', '\0'};
@ -490,59 +470,6 @@ on_error:
strcpy(buf, UNKNOWN_NAME);
len = strlen(UNKNOWN_NAME);
buf[len] = '\0';
return len;
}
/* same as get_nick_truncate but for groupchats */
size_t get_group_nick_truncate(Tox *m, char *buf, uint32_t peer_id, uint32_t groupnum)
{
Tox_Err_Group_Peer_Query err;
size_t len = tox_group_peer_get_name_size(m, groupnum, peer_id, &err);
if (err != TOX_ERR_GROUP_PEER_QUERY_OK || len == 0) {
strcpy(buf, UNKNOWN_NAME);
len = strlen(UNKNOWN_NAME);
} else {
tox_group_peer_get_name(m, groupnum, peer_id, (uint8_t *) buf, &err);
if (err != TOX_ERR_GROUP_PEER_QUERY_OK) {
strcpy(buf, UNKNOWN_NAME);
len = strlen(UNKNOWN_NAME);
}
}
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
buf[len] = '\0';
filter_str(buf, len);
return len;
}
/* same as get_group_nick_truncate() but for self. */
size_t get_group_self_nick_truncate(Tox *m, char *buf, uint32_t groupnum)
{
Tox_Err_Group_Self_Query err;
size_t len = tox_group_self_get_name_size(m, groupnum, &err);
if (err != TOX_ERR_GROUP_SELF_QUERY_OK) {
strcpy(buf, UNKNOWN_NAME);
len = strlen(UNKNOWN_NAME);
} else {
tox_group_self_get_name(m, groupnum, (uint8_t *) buf, &err);
if (err != TOX_ERR_GROUP_SELF_QUERY_OK) {
strcpy(buf, UNKNOWN_NAME);
len = strlen(UNKNOWN_NAME);
}
}
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
buf[len] = 0;
filter_str(buf, len);
return len;
}
@ -550,9 +477,10 @@ size_t get_group_self_nick_truncate(Tox *m, char *buf, uint32_t groupnum)
returns length of msg, which will be no larger than size-1 */
size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length)
{
size_t i;
size_t j = 0;
for (size_t i = 0; (i < length) && (j < size - 1); ++i) {
for (i = 0; (i < length) && (j < size - 1); ++i) {
if (data[i] != '\r') {
msg[j++] = data[i];
}
@ -678,8 +606,7 @@ void set_window_title(ToxWindow *self, const char *title, int len)
char cpy[TOXIC_MAX_NAME_LENGTH + 1];
/* keep conferencenumber in title */
if (self->type == WINDOW_TYPE_CONFERENCE || self->type == WINDOW_TYPE_GROUPCHAT) {
if (self->type == WINDOW_TYPE_CONFERENCE) { /* keep conferencenumber in title for invites */
snprintf(cpy, sizeof(cpy), "%u %s", self->num, title);
} else {
snprintf(cpy, sizeof(cpy), "%s", title);

View File

@ -97,9 +97,6 @@ time_t get_unix_time(void);
/* Puts the current time in buf in the format of specified by the config */
void get_time_str(char *buf, size_t bufsize);
/* Converts seconds to string in format H hours, m minutes, s seconds */
void get_elapsed_time_str_alt(char *buf, int bufsize, uint64_t secs);
/* Converts seconds to string in format HH:mm:ss; truncates hours and minutes when necessary */
void get_elapsed_time_str(char *buf, int bufsize, time_t secs);
@ -171,12 +168,6 @@ size_t get_nick_truncate(Tox *m, char *buf, uint32_t friendnum);
/* same as get_nick_truncate but for conferences */
int get_conference_nick_truncate(Tox *m, char *buf, uint32_t peernum, uint32_t conferencenum);
/* same as get_nick_truncate but for groupchats */
size_t get_group_nick_truncate(Tox *m, char *buf, uint32_t peer_id, uint32_t groupnum);
/* same as get_group_nick_truncate() but for self. */
size_t get_group_self_nick_truncate(Tox *m, char *buf, uint32_t groupnum);
/* copies data to msg buffer.
returns length of msg, which will be no larger than size-1 */
size_t copy_tox_str(char *msg, size_t size, const char *data, size_t length);

View File

@ -33,6 +33,9 @@
#include "toxic.h"
#include "windows.h"
extern struct arg_opts arg_opts;
extern struct Winthread Winthread;
#define NAMESERVER_API_PATH "api"
#define SERVER_KEY_SIZE 32
#define MAX_SERVERS 50
@ -108,15 +111,14 @@ static int load_nameserver_list(const char *path)
char line[MAX_SERVER_LINE];
while (fgets(line, sizeof(line), fp) && Nameservers.lines < MAX_SERVERS) {
size_t linelen = strlen(line);
int linelen = strlen(line);
if (linelen < SERVER_KEY_SIZE * 2 + 5) {
continue;
}
if (line[linelen - 1] == '\n') {
--linelen;
line[linelen] = '\0';
line[--linelen] = '\0';
}
const char *name = strtok(line, " ");
@ -362,20 +364,16 @@ on_exit:
return 0;
}
/* Attempts to do a tox name lookup.
*
* Returns true on success.
*/
bool name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message)
void name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message)
{
if (t_data.disabled) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "nameservers list is empty or does not exist.");
return false;
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "name lookups are disabled.");
return;
}
if (t_data.busy) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous name lookup to finish.");
return false;
return;
}
snprintf(t_data.id_bin, sizeof(t_data.id_bin), "%s", id_bin);
@ -388,24 +386,22 @@ bool name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr,
if (pthread_attr_init(&lookup_thread.attr) != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to init");
clear_thread_data();
return false;
return;
}
if (pthread_attr_setdetachstate(&lookup_thread.attr, PTHREAD_CREATE_DETACHED) != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to set");
pthread_attr_destroy(&lookup_thread.attr);
clear_thread_data();
return false;
return;
}
if (pthread_create(&lookup_thread.tid, &lookup_thread.attr, lookup_thread_func, NULL) != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread failed to init");
pthread_attr_destroy(&lookup_thread.attr);
clear_thread_data();
return false;
return;
}
return true;
}
/* Initializes http based name lookups. Note: This function must be called only once before additional

View File

@ -23,19 +23,14 @@
#ifndef NAME_LOOKUP
#define NAME_LOOKUP
/* Initializes http based name lookups.
*
* Note: This function must be called only once before additional threads are spawned.
/* Initializes http based name lookups. Note: This function must be called only once before additional
* threads are spawned.
*
* Returns 0 on success.
* Returns -1 on failure.
*/
int name_lookup_init(int curl_init_status);
/* Attempts to do a tox name lookup.
*
* Returns true on success.
*/
bool name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message);
int name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message);
#endif /* NAME_LOOKUP */

View File

@ -489,27 +489,16 @@ void terminate_notify(void)
}
#ifdef SOUND_NOTIFY
/*
* Sets notification sound designated by `sound` to file path `value`.
*
* Return true if the sound is successfully set.
*/
bool set_sound(Notification sound, const char *value)
int set_sound(Notification sound, const char *value)
{
if (sound == silent) {
return false;
return 0;
}
free(Control.sounds[sound]);
size_t len = strlen(value) + 1;
Control.sounds[sound] = calloc(len, 1);
if (Control.sounds[sound] == NULL) {
return false;
}
memcpy(Control.sounds[sound], value, len);
struct stat buf;

View File

@ -77,7 +77,7 @@ int box_silent_notify(ToxWindow *self, uint64_t flags, int *id_indicator, const
int box_silent_notify2(ToxWindow *self, uint64_t flags, int id, const char *format, ...);
#ifdef SOUND_NOTIFY
bool set_sound(Notification sound, const char *value);
int set_sound(Notification sound, const char *value);
#endif /* SOUND_NOTIFY */
#endif /* NOTIFY_H */

View File

@ -59,13 +59,11 @@ static const char *glob_cmd_list[] = {
"/connect",
"/decline",
"/exit",
"/group",
"/conference",
#ifdef GAMES
"/game",
#endif
"/help",
"/join",
"/log",
"/myid",
#ifdef QRCODE
@ -177,7 +175,9 @@ static int add_friend_request(const char *public_key, const char *data)
return -1;
}
for (int i = 0; i <= FrndRequests.max_idx; ++i) {
int i;
for (i = 0; i <= FrndRequests.max_idx; ++i) {
if (!FrndRequests.request[i].active) {
FrndRequests.request[i].active = true;
memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE);
@ -526,26 +526,6 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnu
}
}
/**
* Return true is the first 3 bytes of `key` are identical to any other contact in the contact list.
*/
static bool key_is_similar(const char *key)
{
for (size_t i = 0; i < Friends.max_idx; ++i) {
const ToxicFriend *friend = &Friends.list[i];
if (!friend->active) {
continue;
}
if (memcmp(friend->pub_key, key, KEY_IDENT_BYTES / 2) == 0) {
return true;
}
}
return false;
}
static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length)
{
UNUSED_VAR(m);
@ -556,13 +536,6 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con
line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data);
write_to_log("Friend request with the message '%s'", "", ctx->log, true);
if (key_is_similar(key)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"WARNING: This contact's public key is suspiciously similar to that of another contact ");
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"in your list. This may be an impersonation attempt, or it may have occurred by chance.");
}
int n = add_friend_request(key, data);
if (n == -1) {

View File

@ -40,9 +40,6 @@ typedef struct FriendRequests {
struct friend_request request[MAX_FRIEND_REQUESTS];
} FriendRequests;
extern ToxWindow *prompt;
extern FriendRequests FrndRequests;
ToxWindow *new_prompt(void);
void prep_prompt_win(void);

View File

@ -20,10 +20,9 @@
*
*/
#include "api.h"
#ifdef PYTHON
#include <Python.h>
#include "api.h"
#include "execute.h"

View File

@ -63,7 +63,6 @@ static struct ui_strings {
const char *show_typing_other;
const char *show_welcome_msg;
const char *show_connection_msg;
const char *show_group_connection_msg;
const char *nodeslist_update_freq;
const char *autosave_freq;
@ -71,8 +70,6 @@ static struct ui_strings {
const char *line_quit;
const char *line_alert;
const char *line_normal;
const char *line_special;
const char *group_part_message;
const char *mplex_away;
const char *mplex_away_note;
@ -100,19 +97,14 @@ static struct ui_strings {
"show_typing_other",
"show_welcome_msg",
"show_connection_msg",
"show_group_connection_msg",
"nodeslist_update_freq",
"autosave_freq",
"line_join",
"line_quit",
"line_alert",
"line_normal",
"line_special",
"group_part_message",
"mplex_away",
"mplex_away_note",
"color_bar_bg",
"color_bar_fg",
"color_bar_accent",
@ -138,15 +130,13 @@ static void ui_defaults(struct user_settings *settings)
settings->show_typing_other = SHOW_TYPING_ON;
settings->show_welcome_msg = SHOW_WELCOME_MSG_ON;
settings->show_connection_msg = SHOW_CONNECTION_MSG_ON;
settings->show_group_connection_msg = SHOW_GROUP_CONNECTION_MSG_ON;
settings->nodeslist_update_freq = 1;
settings->nodeslist_update_freq = 7;
settings->autosave_freq = 600;
snprintf(settings->line_join, LINE_HINT_MAX + 1, "%s", LINE_JOIN);
snprintf(settings->line_quit, LINE_HINT_MAX + 1, "%s", LINE_QUIT);
snprintf(settings->line_alert, LINE_HINT_MAX + 1, "%s", LINE_ALERT);
snprintf(settings->line_normal, LINE_HINT_MAX + 1, "%s", LINE_NORMAL);
snprintf(settings->line_special, LINE_HINT_MAX + 1, "%s", LINE_SPECIAL);
settings->mplex_away = MPLEX_ON;
snprintf(settings->mplex_away_note, sizeof(settings->mplex_away_note), "%s", MPLEX_AWAY_NOTE);
@ -408,7 +398,6 @@ int settings_load(struct user_settings *s, const char *patharg)
config_setting_lookup_bool(setting, ui_strings.show_typing_other, &s->show_typing_other);
config_setting_lookup_bool(setting, ui_strings.show_welcome_msg, &s->show_welcome_msg);
config_setting_lookup_bool(setting, ui_strings.show_connection_msg, &s->show_connection_msg);
config_setting_lookup_bool(setting, ui_strings.show_group_connection_msg, &s->show_group_connection_msg);
config_setting_lookup_int(setting, ui_strings.history_size, &s->history_size);
config_setting_lookup_int(setting, ui_strings.notification_timeout, &s->notification_timeout);
@ -431,19 +420,11 @@ int settings_load(struct user_settings *s, const char *patharg)
snprintf(s->line_normal, sizeof(s->line_normal), "%s", str);
}
if (config_setting_lookup_string(setting, ui_strings.line_special, &str)) {
snprintf(s->line_special, sizeof(s->line_special), "%s", str);
}
config_setting_lookup_bool(setting, ui_strings.mplex_away, &s->mplex_away);
if (config_setting_lookup_string(setting, ui_strings.mplex_away_note, &str)) {
snprintf(s->mplex_away_note, sizeof(s->mplex_away_note), "%s", str);
}
if (config_setting_lookup_string(setting, ui_strings.group_part_message, &str)) {
snprintf(s->group_part_message, sizeof(s->group_part_message), "%s", str);
}
}
/* paths */

View File

@ -54,7 +54,6 @@ struct user_settings {
int show_typing_other; /* boolean */
int show_welcome_msg; /* boolean */
int show_connection_msg; /* boolean */
int show_group_connection_msg; /* boolean */
int nodeslist_update_freq; /* int (<= 0 to disable updates) */
int autosave_freq; /* int (<= 0 to disable autosave) */
@ -62,7 +61,6 @@ struct user_settings {
char line_quit[LINE_HINT_MAX + 1];
char line_alert[LINE_HINT_MAX + 1];
char line_normal[LINE_HINT_MAX + 1];
char line_special[LINE_HINT_MAX + 1];
char download_path[PATH_MAX];
char chatlogs_path[PATH_MAX];
@ -87,7 +85,6 @@ struct user_settings {
int mplex_away; /* boolean (1 for reaction to terminal attach/detach) */
char mplex_away_note [TOX_MAX_STATUS_MESSAGE_LENGTH];
char group_part_message[TOX_GROUP_MAX_PART_LENGTH];
#ifdef AUDIO
int audio_in_dev;
@ -99,8 +96,6 @@ struct user_settings {
#endif
};
extern struct user_settings *user_settings;
enum settings_values {
AUTOLOG_OFF = 0,
AUTOLOG_ON = 1,
@ -123,9 +118,6 @@ enum settings_values {
SHOW_CONNECTION_MSG_OFF = 0,
SHOW_CONNECTION_MSG_ON = 1,
SHOW_GROUP_CONNECTION_MSG_OFF = 0,
SHOW_GROUP_CONNECTION_MSG_ON = 1,
DFLT_HST_SIZE = 700,
MPLEX_OFF = 0,
@ -136,7 +128,6 @@ enum settings_values {
#define LINE_QUIT "<--"
#define LINE_ALERT "-!-"
#define LINE_NORMAL "-"
#define LINE_SPECIAL ">"
#define TIMESTAMP_DEFAULT "%H:%M"
#define LOG_TIMESTAMP_DEFAULT "%Y/%m/%d [%H:%M:%S]"
#define MPLEX_AWAY_NOTE "Away from keyboard, be back soon!"

View File

@ -37,7 +37,6 @@
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <termios.h>
#include <time.h>
@ -54,7 +53,6 @@
#include "execute.h"
#include "file_transfers.h"
#include "friendlist.h"
#include "groupchats.h"
#include "line_info.h"
#include "log.h"
#include "message_queue.h"
@ -76,7 +74,7 @@
#ifdef VIDEO
#include "video_call.h"
#endif /* VIDEO */
static ToxAV *av;
ToxAV *av;
#endif /* AUDIO */
#ifdef PYTHON
@ -100,13 +98,10 @@ ToxWindow *prompt = NULL;
#define MAX_PASSWORD_LEN 64
struct Winthread Winthread;
static struct cqueue_thread cqueue_thread;
struct cqueue_thread cqueue_thread;
struct av_thread av_thread;
struct arg_opts arg_opts;
#ifdef AUDIO
static struct av_thread av_thread;
#endif
// This struct is not thread safe. It should only ever be written to from the main thread
// before any other thread that uses it is initialized.
struct user_settings *user_settings = NULL;
@ -231,55 +226,20 @@ void exit_toxic_err(const char *errmsg, int errcode)
exit(EXIT_FAILURE);
}
static const char *tox_log_level_show(Tox_Log_Level level)
{
switch (level) {
case TOX_LOG_LEVEL_TRACE:
return "TRACE";
case TOX_LOG_LEVEL_DEBUG:
return "DEBUG";
case TOX_LOG_LEVEL_INFO:
return "INFO";
case TOX_LOG_LEVEL_WARNING:
return "WARNING";
case TOX_LOG_LEVEL_ERROR:
return "ERROR";
}
return "<invalid>";
}
void cb_toxcore_logger(Tox *m, TOX_LOG_LEVEL level, const char *file, uint32_t line, const char *func,
const char *message, void *user_data)
{
UNUSED_VAR(user_data);
UNUSED_VAR(file);
UNUSED_VAR(m);
FILE *fp = (FILE *)user_data;
if (!fp) {
fp = stderr;
if (user_data) {
FILE *fp = (FILE *)user_data;
fprintf(fp, "[%d] %u:%s() - %s\n", level, line, func, message);
fflush(fp);
} else {
fprintf(stderr, "[%d] %u:%s() - %s\n", level, line, func, message);
}
struct timeval tv;
gettimeofday(&tv, NULL);
struct tm tmp;
gmtime_r(&tv.tv_sec, &tmp);
char timestamp[200];
strftime(timestamp, sizeof(timestamp), "%F %T", &tmp);
fprintf(fp, "%c %s.%06ld %s:%u(%s) - %s\n", tox_log_level_show(level)[0], timestamp, tv.tv_usec, file, line, func,
message);
fflush(fp);
}
/* Sets ncurses refresh rate. Lower values make it refresh more often. */
@ -509,17 +469,6 @@ static void load_friendlist(Tox *m)
sort_friendlist_index();
}
static void load_groups(Tox *m)
{
size_t numgroups = tox_group_get_number_groups(m);
for (size_t i = 0; i < numgroups; ++i) {
if (init_groupchat_win(m, i, NULL, 0, Group_Join_Type_Load) != 0) {
tox_group_leave(m, i, NULL, 0, NULL);
}
}
}
static void load_conferences(Tox *m)
{
size_t num_chats = tox_conference_get_chatlist_size(m);
@ -863,22 +812,6 @@ static void init_tox_callbacks(Tox *m)
tox_callback_file_recv_control(m, on_file_recv_control);
tox_callback_file_recv_chunk(m, on_file_recv_chunk);
tox_callback_friend_lossless_packet(m, on_lossless_custom_packet);
tox_callback_group_invite(m, on_group_invite);
tox_callback_group_message(m, on_group_message);
tox_callback_group_private_message(m, on_group_private_message);
tox_callback_group_peer_status(m, on_group_status_change);
tox_callback_group_peer_join(m, on_group_peer_join);
tox_callback_group_peer_exit(m, on_group_peer_exit);
tox_callback_group_peer_name(m, on_group_nick_change);
tox_callback_group_topic(m, on_group_topic_change);
tox_callback_group_peer_limit(m, on_group_peer_limit);
tox_callback_group_privacy_state(m, on_group_privacy_state);
tox_callback_group_topic_lock(m, on_group_topic_lock);
tox_callback_group_password(m, on_group_password);
tox_callback_group_self_join(m, on_group_self_join);
tox_callback_group_join_fail(m, on_group_rejected);
tox_callback_group_moderation(m, on_group_moderation);
tox_callback_group_voice_state(m, on_group_voice_state);
}
static void init_tox_options(struct Tox_Options *tox_opts)
@ -1648,7 +1581,6 @@ int main(int argc, char **argv)
prompt = init_windows(m);
prompt_init_statusbar(prompt, m, !datafile_exists);
load_groups(m);
load_conferences(m);
set_active_window_index(0);

View File

@ -23,10 +23,6 @@
#ifndef TOXIC_H
#define TOXIC_H
#ifndef NCURSES_WIDECHAR
#define NCURSES_WIDECHAR 1
#endif
#ifndef TOXICVER
#define TOXICVER "NOVERS" /* Use the -D flag to set this */
#endif
@ -50,7 +46,7 @@
#define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */
#define MAX_CMDNAME_SIZE 64
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */
#define KEY_IDENT_BYTES 6 /* number of hex digits to display for the public key identifier */
#define KEY_IDENT_DIGITS 3 /* number of hex digits to display for the pub-key based identifier */
#define TIME_STR_SIZE 32
#define COLOR_STR_SIZE 10 /* should fit every color option */
@ -114,8 +110,8 @@ void flag_interface_refresh(void);
/* Sets ncurses refresh rate. Lower values make it refresh more often. */
void set_window_refresh_rate(size_t refresh_rate);
void exit_toxic_success(Tox *m) __attribute__((__noreturn__));
void exit_toxic_err(const char *errmsg, int errcode) __attribute__((__noreturn__));
void exit_toxic_success(Tox *m);
void exit_toxic_err(const char *errmsg, int errcode);
int store_data(Tox *m, const char *path);
@ -148,34 +144,6 @@ void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t k
void on_friend_typing(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata);
void on_friend_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata);
void on_lossless_custom_packet(Tox *m, uint32_t friendnumber, const uint8_t *data, size_t length, void *userdata);
void on_group_invite(Tox *m, uint32_t friendnumber, const uint8_t *invite_data, size_t length,
const uint8_t *group_name,
size_t group_name_length, void *userdata);
void on_group_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, uint32_t message_id, void *userdata);
void on_group_private_message(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length,
void *userdata);
void on_group_peer_join(Tox *m, uint32_t groupnumber, uint32_t peernumber, void *userdata);
void on_group_peer_exit(Tox *m, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type,
const uint8_t *nick,
size_t nick_len, const uint8_t *partmsg, size_t length, void *userdata);
void on_group_topic_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *topic, size_t length,
void *userdata);
void on_group_peer_limit(Tox *m, uint32_t groupnumber, uint32_t peer_limit, void *userdata);
void on_group_privacy_state(Tox *m, uint32_t groupnumber, Tox_Group_Privacy_State privacy_state, void *userdata);
void on_group_topic_lock(Tox *m, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, void *userdata);
void on_group_password(Tox *m, uint32_t groupnumber, const uint8_t *password, size_t length, void *userdata);
void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, const uint8_t *newname, size_t length,
void *userdata);
void on_group_status_change(Tox *m, uint32_t groupnumber, uint32_t peernumber, TOX_USER_STATUS status, void *userdata);
void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata);
void on_group_rejected(Tox *m, uint32_t groupnumber, Tox_Group_Join_Fail type, void *userdata);
void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peernum, uint32_t target_peernum,
Tox_Group_Mod_Event type, void *userdata);
void on_group_voice_state(Tox *m, uint32_t groupnumber, Tox_Group_Voice_State voice_state, void *userdata);
extern char *DATA_FILE;
extern char *BLOCK_FILE;
#endif /* TOXIC_H */

View File

@ -92,21 +92,21 @@ typedef struct VideoDevice {
} VideoDevice;
static const char *dvideo_device_names[2]; /* Default device */
static char *video_devices_names[2][MAX_DEVICES]; /* Container of available devices */
static int size[2]; /* Size of above containers */
static VideoDevice *video_devices_running[2][MAX_DEVICES] = {{NULL}}; /* Running devices */
static uint32_t primary_video_device[2]; /* Primary device */
const char *dvideo_device_names[2]; /* Default device */
const char *video_devices_names[2][MAX_DEVICES]; /* Container of available devices */
static int size[2]; /* Size of above containers */
VideoDevice *video_devices_running[2][MAX_DEVICES] = {{NULL}}; /* Running devices */
uint32_t primary_video_device[2]; /* Primary device */
static ToxAV *av = NULL;
/* q_mutex */
#define lock pthread_mutex_lock(&video_mutex)
#define unlock pthread_mutex_unlock(&video_mutex)
static pthread_mutex_t video_mutex;
pthread_mutex_t video_mutex;
static bool video_thread_running = true;
static bool video_thread_paused = true; /* Thread control */
bool video_thread_running = true,
video_thread_paused = true; /* Thread control */
void *video_thread_poll(void *);
@ -187,7 +187,7 @@ VideoDeviceError init_video_devices(void)
#if defined(__OSX__) || defined(__APPLE__)
if (osx_video_init(&video_devices_names[vdt_input][0], &size[vdt_input]) != 0) {
if (osx_video_init((char **)video_devices_names[vdt_input], &size[vdt_input]) != 0) {
return vde_InternalError;
}
@ -209,24 +209,12 @@ VideoDeviceError init_video_devices(void)
/* Query V4L for capture capabilities */
if (-1 != ioctl(fd, VIDIOC_QUERYCAP, &cap)) {
video_input_name = (char *)malloc(strlen((const char *)cap.card) + strlen(device_address) + 4);
if (video_input_name == NULL) {
close(fd);
return vde_InternalError;
}
strcpy(video_input_name, (char *)cap.card);
strcat(video_input_name, " (");
strcat(video_input_name, (char *)device_address);
strcat(video_input_name, ")");
} else {
video_input_name = (char *)malloc(strlen(device_address) + 3);
if (video_input_name == NULL) {
close(fd);
return vde_InternalError;
}
strcpy(video_input_name, "(");
strcat(video_input_name, device_address);
strcat(video_input_name, ")");
@ -241,9 +229,6 @@ VideoDeviceError init_video_devices(void)
#endif
size[vdt_output] = 1;
// TODO(iphydf): String literals are const char *. This may need to be
// copied, or if we're not owning any output device names, it should be
// const and video_devices_names needs to be split.
char *video_output_name = "Toxic Video Receiver";
video_devices_names[vdt_output][0] = video_output_name;
@ -277,7 +262,7 @@ VideoDeviceError terminate_video_devices(void)
int i;
for (i = 0; i < size[vdt_input]; ++i) {
free(video_devices_names[vdt_input][i]);
free((void *)video_devices_names[vdt_input][i]);
}
if (pthread_mutex_destroy(&video_mutex) != 0) {

View File

@ -30,7 +30,6 @@
#include "conference.h"
#include "file_transfers.h"
#include "friendlist.h"
#include "groupchats.h"
#include "line_info.h"
#include "misc_tools.h"
#include "prompt.h"
@ -42,10 +41,16 @@
#include "game_base.h"
#endif
extern char *DATA_FILE;
extern struct Winthread Winthread;
ToxWindow *windows[MAX_WINDOWS_NUM];
static uint8_t active_window_index;
static int num_active_windows;
extern ToxWindow *prompt;
extern struct user_settings *user_settings;
/* CALLBACKS START */
void on_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
{
@ -191,7 +196,7 @@ void on_conference_invite(Tox *m, uint32_t friendnumber, Tox_Conference_Type typ
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onConferenceInvite != NULL) {
windows[i]->onConferenceInvite(windows[i], m, friendnumber, type, (const char *) conference_pub_key, length);
windows[i]->onConferenceInvite(windows[i], m, friendnumber, type, (char *) conference_pub_key, length);
}
}
}
@ -245,7 +250,7 @@ void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, u
{
UNUSED_VAR(userdata);
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
if (!ft) {
return;
@ -268,7 +273,7 @@ void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint
{
UNUSED_VAR(userdata);
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
if (!ft) {
return;
@ -276,7 +281,7 @@ void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onFileRecvChunk != NULL) {
windows[i]->onFileRecvChunk(windows[i], m, friendnumber, filenumber, position, (const char *) data, length);
windows[i]->onFileRecvChunk(windows[i], m, friendnumber, filenumber, position, (char *) data, length);
}
}
}
@ -286,7 +291,7 @@ void on_file_recv_control(Tox *m, uint32_t friendnumber, uint32_t filenumber, To
{
UNUSED_VAR(userdata);
FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber);
if (!ft) {
return;
@ -317,7 +322,7 @@ void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t k
for (uint8_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onFileRecv != NULL) {
windows[i]->onFileRecv(windows[i], m, friendnumber, filenumber, file_size, (const char *) filename,
windows[i]->onFileRecv(windows[i], m, friendnumber, filenumber, file_size, (char *) filename,
filename_length);
}
}
@ -380,192 +385,6 @@ void on_lossless_custom_packet(Tox *m, uint32_t friendnumber, const uint8_t *dat
}
}
void on_group_invite(Tox *m, uint32_t friendnumber, const uint8_t *invite_data, size_t length,
const uint8_t *group_name,
size_t group_name_length, void *userdata)
{
char gname[MAX_STR_SIZE + 1];
group_name_length = copy_tox_str(gname, sizeof(gname), (const char *) group_name, group_name_length);
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupInvite != NULL) {
windows[i]->onGroupInvite(windows[i], m, friendnumber, (char *) invite_data, length, gname, group_name_length);
}
}
}
void on_group_message(Tox *m, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
const uint8_t *message, size_t length, uint32_t message_id, void *userdata)
{
UNUSED_VAR(message_id);
char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) message, length);
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupMessage != NULL) {
windows[i]->onGroupMessage(windows[i], m, groupnumber, peer_id, type, msg, length);
}
}
}
void on_group_private_message(Tox *m, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
const uint8_t *message,
size_t length, void *userdata)
{
char msg[MAX_STR_SIZE + 1];
length = copy_tox_str(msg, sizeof(msg), (const char *) message, length);
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupPrivateMessage != NULL) {
windows[i]->onGroupPrivateMessage(windows[i], m, groupnumber, peer_id, msg, length);
}
}
}
void on_group_status_change(Tox *m, uint32_t groupnumber, uint32_t peer_id, TOX_USER_STATUS status, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupStatusChange != NULL) {
windows[i]->onGroupStatusChange(windows[i], m, groupnumber, peer_id, status);
}
}
flag_interface_refresh();
}
void on_group_peer_join(Tox *m, uint32_t groupnumber, uint32_t peer_id, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupPeerJoin != NULL) {
windows[i]->onGroupPeerJoin(windows[i], m, groupnumber, peer_id);
}
}
flag_interface_refresh();
}
void on_group_peer_exit(Tox *m, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type,
const uint8_t *nick,
size_t nick_len, const uint8_t *part_message, size_t length, void *userdata)
{
char toxic_nick[TOXIC_MAX_NAME_LENGTH + 1];
nick_len = copy_tox_str(toxic_nick, sizeof(toxic_nick), (const char *) nick, nick_len);
char buf[MAX_STR_SIZE + 1] = {0};
size_t buf_len = 0;
if (part_message) {
buf_len = copy_tox_str(buf, sizeof(buf), (const char *) part_message, length);
}
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupPeerExit != NULL) {
windows[i]->onGroupPeerExit(windows[i], m, groupnumber, peer_id, exit_type, toxic_nick, nick_len, buf, buf_len);
}
}
}
void on_group_topic_change(Tox *m, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic, size_t length,
void *userdata)
{
char data[MAX_STR_SIZE + 1];
length = copy_tox_str(data, sizeof(data), (const char *) topic, length);
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupTopicChange != NULL) {
windows[i]->onGroupTopicChange(windows[i], m, groupnumber, peer_id, data, length);
}
}
}
void on_group_peer_limit(Tox *m, uint32_t groupnumber, uint32_t peer_limit, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupPeerLimit != NULL) {
windows[i]->onGroupPeerLimit(windows[i], m, groupnumber, peer_limit);
}
}
}
void on_group_privacy_state(Tox *m, uint32_t groupnumber, Tox_Group_Privacy_State privacy_state, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupPrivacyState != NULL) {
windows[i]->onGroupPrivacyState(windows[i], m, groupnumber, privacy_state);
}
}
}
void on_group_topic_lock(Tox *m, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupTopicLock != NULL) {
windows[i]->onGroupTopicLock(windows[i], m, groupnumber, topic_lock);
}
}
}
void on_group_password(Tox *m, uint32_t groupnumber, const uint8_t *password, size_t length, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupPassword != NULL) {
windows[i]->onGroupPassword(windows[i], m, groupnumber, (char *) password, length);
}
}
}
void on_group_nick_change(Tox *m, uint32_t groupnumber, uint32_t peer_id, const uint8_t *newname, size_t length,
void *userdata)
{
char name[TOXIC_MAX_NAME_LENGTH + 1];
length = copy_tox_str(name, sizeof(name), (const char *) newname, length);
filter_str(name, length);
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupNickChange != NULL) {
windows[i]->onGroupNickChange(windows[i], m, groupnumber, peer_id, name, length);
}
}
}
void on_group_self_join(Tox *m, uint32_t groupnumber, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupSelfJoin != NULL) {
windows[i]->onGroupSelfJoin(windows[i], m, groupnumber);
}
}
}
void on_group_rejected(Tox *m, uint32_t groupnumber, Tox_Group_Join_Fail type, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupRejected != NULL) {
windows[i]->onGroupRejected(windows[i], m, groupnumber, type);
}
}
}
void on_group_moderation(Tox *m, uint32_t groupnumber, uint32_t source_peer_id, uint32_t target_peer_id,
Tox_Group_Mod_Event type, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupModeration != NULL) {
windows[i]->onGroupModeration(windows[i], m, groupnumber, source_peer_id, target_peer_id, type);
}
}
}
void on_group_voice_state(Tox *m, uint32_t groupnumber, Tox_Group_Voice_State voice_state, void *userdata)
{
for (size_t i = 0; i < MAX_WINDOWS_NUM; ++i) {
if (windows[i] != NULL && windows[i]->onGroupVoiceState != NULL) {
windows[i]->onGroupVoiceState(windows[i], m, groupnumber, voice_state);
}
}
}
/* CALLBACKS END */
int add_window(Tox *m, ToxWindow *w)
@ -736,7 +555,7 @@ void on_window_resize(void)
wclear(w->help->win);
}
if (w->type == WINDOW_TYPE_CONFERENCE || w->type == WINDOW_TYPE_GROUPCHAT) {
if (w->type == WINDOW_TYPE_CONFERENCE) {
delwin(w->chatwin->sidebar);
w->chatwin->sidebar = NULL;
} else {
@ -764,7 +583,7 @@ void on_window_resize(void)
} else {
w->chatwin->history = subwin(w->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0);
if (!(w->type == WINDOW_TYPE_CONFERENCE || w->type == WINDOW_TYPE_GROUPCHAT)) {
if (w->type != WINDOW_TYPE_CONFERENCE) {
w->stb->topline = subwin(w->window, TOP_BAR_HEIGHT, x2, 0, 0);
}
}
@ -872,10 +691,10 @@ void draw_window_bar(ToxWindow *self)
int cur_x;
int cur_y;
getyx(win, cur_y, cur_x);
UNUSED_VAR(cur_y);
getyx(win, cur_y, cur_x);
wattron(win, COLOR_PAIR(BAR_TEXT));
mvwhline(win, 0, cur_x, ' ', COLS - cur_x);
wattroff(win, COLOR_PAIR(BAR_TEXT));
@ -1163,12 +982,6 @@ void kill_all_windows(Tox *m)
#endif // GAMES
case WINDOW_TYPE_GROUPCHAT: {
exit_groupchat(w, m, w->num, user_settings->group_part_message,
strlen(user_settings->group_part_message));
break;
}
default: {
break;
}

View File

@ -87,7 +87,6 @@ typedef enum {
WINDOW_TYPE_PROMPT,
WINDOW_TYPE_CHAT,
WINDOW_TYPE_CONFERENCE,
WINDOW_TYPE_GROUPCHAT,
WINDOW_TYPE_FRIEND_LIST,
#ifdef GAMES
@ -115,8 +114,6 @@ struct Winthread {
volatile sig_atomic_t last_refresh_flag;
};
extern struct Winthread Winthread;
struct cqueue_thread {
pthread_t tid;
};
@ -150,8 +147,6 @@ struct arg_opts {
uint16_t tcp_port;
};
extern struct arg_opts arg_opts;
typedef struct ToxWindow ToxWindow;
typedef struct StatusBar StatusBar;
typedef struct PromptBuf PromptBuf;
@ -193,24 +188,6 @@ struct ToxWindow {
void(*onGameData)(ToxWindow *, Tox *, uint32_t, const uint8_t *, size_t);
#endif // GAMES
void(*onGroupInvite)(ToxWindow *, Tox *, uint32_t, const char *, size_t, const char *, size_t);
void(*onGroupMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_MESSAGE_TYPE, const char *, size_t);
void(*onGroupPrivateMessage)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
void(*onGroupPeerJoin)(ToxWindow *, Tox *, uint32_t, uint32_t);
void(*onGroupPeerExit)(ToxWindow *, Tox *, uint32_t, uint32_t, Tox_Group_Exit_Type, const char *, size_t, const char *,
size_t);
void(*onGroupNickChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
void(*onGroupStatusChange)(ToxWindow *, Tox *, uint32_t, uint32_t, TOX_USER_STATUS);
void(*onGroupTopicChange)(ToxWindow *, Tox *, uint32_t, uint32_t, const char *, size_t);
void(*onGroupPeerLimit)(ToxWindow *, Tox *, uint32_t, uint32_t);
void(*onGroupPrivacyState)(ToxWindow *, Tox *, uint32_t, Tox_Group_Privacy_State);
void(*onGroupTopicLock)(ToxWindow *, Tox *, uint32_t, Tox_Group_Topic_Lock);
void(*onGroupPassword)(ToxWindow *, Tox *, uint32_t, const char *, size_t);
void(*onGroupSelfJoin)(ToxWindow *, Tox *, uint32_t);
void(*onGroupRejected)(ToxWindow *, Tox *, uint32_t, Tox_Group_Join_Fail);
void(*onGroupModeration)(ToxWindow *, Tox *, uint32_t, uint32_t, uint32_t, Tox_Group_Mod_Event);
void(*onGroupVoiceState)(ToxWindow *, Tox *, uint32_t, Tox_Group_Voice_State);
#ifdef AUDIO
void(*onInvite)(ToxWindow *, ToxAV *, uint32_t, int);
@ -256,8 +233,6 @@ struct ToxWindow {
WINDOW *window_bar;
};
extern ToxWindow *windows[MAX_WINDOWS_NUM];
/* statusbar info holder */
struct StatusBar {
WINDOW *topline;