mirror of
https://github.com/Tha14/toxic.git
synced 2025-06-27 21:06:46 +02:00
Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
97a8ecd115 | |||
64d782569a | |||
6248baf98b | |||
33cfca7ecc | |||
a01cc35368 | |||
b10eebd77e | |||
05661ca9b6 | |||
784883f773 | |||
a9e5723ca4 | |||
95dfea8d29 | |||
e574af7d68 | |||
2918ca45a2 | |||
6ad744f770 | |||
5b394e6f35 | |||
940af2c711 | |||
544c402f78 | |||
cee9e624b8 | |||
2e65ee3609 | |||
3a176e1cab | |||
00cccad22c | |||
a432d733d7 | |||
893e88294b | |||
b071a9e992 | |||
48cf4ebf02 | |||
773a75b948 | |||
133c0e8d63 | |||
bf54cb36ef | |||
032853b5c9 | |||
650c13ca7a | |||
9d5fe03285 | |||
c3f68b60d3 | |||
1c16467eb9 | |||
3c74385f5c | |||
c07c0028bb | |||
dc3b2e04ab | |||
7fd3aa9164 | |||
4c60312e2d | |||
16e29aa4e0 | |||
bd7b073155 | |||
f25cf870e6 | |||
13291d0365 |
@ -5,7 +5,7 @@ compiler:
|
||||
|
||||
before_script:
|
||||
# Installing yasm (needed for compiling vpx) and openal
|
||||
- sudo apt-get -yq install yasm libopenal-dev libconfig-dev libalut-dev
|
||||
- sudo apt-get -yq install yasm libopenal-dev libconfig-dev libalut-dev libnotify-dev asciidoc
|
||||
# Installing libsodium, needed for toxcore
|
||||
- git clone https://github.com/jedisct1/libsodium.git libsodium
|
||||
- cd libsodium
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Toxic [](https://travis-ci.org/Tox/toxic)
|
||||
Toxic is a [Tox](https://tox.im)-based instant messenging client which formerly resided in the [Tox core repository](https://github.com/irungentoo/toxcore), and is now available as a standalone application.
|
||||
|
||||

|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -6,8 +6,8 @@ CFG_DIR = $(BASE_DIR)/cfg
|
||||
LIBS = libtoxcore ncursesw libconfig
|
||||
|
||||
CFLAGS = -std=gnu99 -pthread -Wall -g
|
||||
CFLAGS += '-DTOXICVER="$(VERSION)"' -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED
|
||||
CFLAGS += -DPACKAGE_DATADIR="\"$(abspath $(DATADIR))\""
|
||||
CFLAGS += '-DTOXICVER="$(VERSION)"' -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED -D_FILE_OFFSET_BITS=64
|
||||
CFLAGS += '-DPACKAGE_DATADIR="$(abspath $(DATADIR))"'
|
||||
CFLAGS += $(USER_CFLAGS)
|
||||
LDFLAGS = $(USER_LDFLAGS)
|
||||
|
||||
@ -58,7 +58,7 @@ toxic: $(OBJ)
|
||||
@$(CC) -MM $(CFLAGS) $(SRC_DIR)/$*.c > $*.d
|
||||
|
||||
clean:
|
||||
rm -rf *.d *.o toxic
|
||||
rm -f *.d *.o toxic
|
||||
|
||||
-include $(OBJ:.o=.d)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Variables for audio call support
|
||||
AUDIO_LIBS = libtoxav openal
|
||||
AUDIO_CFLAGS = -D_AUDIO
|
||||
AUDIO_CFLAGS = -DAUDIO
|
||||
ifneq (, $(findstring device.o, $(OBJ)))
|
||||
AUDIO_OBJ = audio_call.o
|
||||
else
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Variables for desktop notifications support
|
||||
DESK_NOTIFY_LIBS = libnotify
|
||||
DESK_NOTIFY_CFLAGS = -D_BOX_NOTIFY
|
||||
DESK_NOTIFY_CFLAGS = -DBOX_NOTIFY
|
||||
|
||||
# Check if we can build desktop notifications support
|
||||
CHECK_DESK_NOTIFY_LIBS = $(shell pkg-config --exists $(DESK_NOTIFY_LIBS) || echo -n "error")
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Variables for sound notifications support
|
||||
SND_NOTIFY_LIBS = openal freealut
|
||||
SND_NOTIFY_CFLAGS = -D_SOUND_NOTIFY
|
||||
SND_NOTIFY_CFLAGS = -DSOUND_NOTIFY
|
||||
ifneq (, $(findstring device.o, $(OBJ)))
|
||||
SND_NOTIFY_OBJ =
|
||||
else
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Variables for X11 support
|
||||
X11_LIBS = x11
|
||||
X11_CFLAGS = -D_X11
|
||||
X11_CFLAGS = -DX11
|
||||
|
||||
# Check if we can build X11 support
|
||||
CHECK_X11_LIBS = $(shell pkg-config --exists $(X11_LIBS) || echo -n "error")
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Version
|
||||
TOXIC_VERSION = 0.5.0
|
||||
TOXIC_VERSION = 0.5.2
|
||||
REV = $(shell git rev-list HEAD --count)
|
||||
VERSION = $(TOXIC_VERSION)_r$(REV)
|
||||
|
||||
|
@ -2,12 +2,12 @@
|
||||
.\" Title: toxic.conf
|
||||
.\" Author: [see the "AUTHORS" section]
|
||||
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
|
||||
.\" Date: 2014-08-26
|
||||
.\" Date: 2014-09-19
|
||||
.\" Manual: Toxic Manual
|
||||
.\" Source: toxic __VERSION__
|
||||
.\" Language: English
|
||||
.\"
|
||||
.TH "TOXIC\&.CONF" "5" "2014\-08\-26" "toxic __VERSION__" "Toxic Manual"
|
||||
.TH "TOXIC\&.CONF" "5" "2014\-09\-19" "toxic __VERSION__" "Toxic Manual"
|
||||
.\" -----------------------------------------------------------------
|
||||
.\" * Define some portability stuff
|
||||
.\" -----------------------------------------------------------------
|
||||
@ -138,6 +138,11 @@ Configuration related to paths\&.
|
||||
Default path for downloads\&. String value\&. Absolute path for downloaded files\&.
|
||||
.RE
|
||||
.PP
|
||||
\fBavatar_path\fR
|
||||
.RS 4
|
||||
Path for your avatar (file must be a \&.png and cannot exceed 16\&.3 KiB)
|
||||
.RE
|
||||
.PP
|
||||
\fBchatlogs_path\fR
|
||||
.RS 4
|
||||
Default path for chatlogs\&. String value\&. Absolute path for chatlog files\&.
|
||||
|
@ -87,6 +87,9 @@ OPTIONS
|
||||
Default path for downloads. String value. Absolute path for downloaded
|
||||
files.
|
||||
|
||||
*avatar_path*;;
|
||||
Path for your avatar (file must be a .png and cannot exceed 16.3 KiB)
|
||||
|
||||
*chatlogs_path*;;
|
||||
Default path for chatlogs. String value. Absolute path for chatlog files.
|
||||
|
||||
|
@ -45,6 +45,9 @@ tox = {
|
||||
// Path for downloaded files
|
||||
// download_path="/home/USERNAME/Downloads/";
|
||||
|
||||
// Path for your avatar (file must be a .png and cannot exceed 16.3 KiB)
|
||||
// avatar_path="/home/USERNAME/Pictures/youravatar.png";
|
||||
|
||||
// Path for chatlogs
|
||||
// chatlogs_path="/home/USERNAME/toxic_chatlogs/";
|
||||
};
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "line_info.h"
|
||||
#include "notify.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <curses.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
@ -48,36 +49,41 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define _cbend pthread_exit(NULL)
|
||||
#define cbend pthread_exit(NULL)
|
||||
|
||||
#define MAX_CALLS 10
|
||||
|
||||
#define frame_size (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000)
|
||||
|
||||
typedef struct _Call {
|
||||
typedef struct Call {
|
||||
pthread_t ttid; /* Transmission thread id */
|
||||
_Bool ttas, has_output; /* Transmission thread active status (0 - stopped, 1- running) */
|
||||
bool ttas, has_output; /* Transmission thread active status (0 - stopped, 1- running) */
|
||||
uint32_t in_idx, out_idx;
|
||||
pthread_mutex_t mutex;
|
||||
} Call;
|
||||
|
||||
|
||||
void set_call(Call* call, _Bool start)
|
||||
static int set_call(Call* call, bool start)
|
||||
{
|
||||
call->in_idx = -1;
|
||||
call->out_idx = -1;
|
||||
|
||||
if ( start ) {
|
||||
call->ttas = _True;
|
||||
pthread_mutex_init(&call->mutex, NULL);
|
||||
call->ttas = true;
|
||||
|
||||
if (pthread_mutex_init(&call->mutex, NULL) != 0)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
call->ttid = 0;
|
||||
pthread_mutex_destroy(&call->mutex);
|
||||
if (pthread_mutex_destroy(&call->mutex) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct _ASettings {
|
||||
struct ASettings {
|
||||
AudioError errors;
|
||||
|
||||
ToxAv *av;
|
||||
@ -198,7 +204,8 @@ int start_transmission(ToxWindow *self)
|
||||
!toxav_capability_supported(ASettins.av, self->call_idx, AudioEncoding) )
|
||||
return -1;
|
||||
|
||||
set_call(&ASettins.calls[self->call_idx], _True);
|
||||
if (set_call(&ASettins.calls[self->call_idx], true) == -1)
|
||||
return -1;
|
||||
|
||||
ToxAvCSettings csettings;
|
||||
toxav_get_peer_csettings(ASettins.av, self->call_idx, 0, &csettings);
|
||||
@ -208,7 +215,7 @@ int start_transmission(ToxWindow *self)
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open input device!");
|
||||
|
||||
if ( register_device_callback(self->call_idx, ASettins.calls[self->call_idx].in_idx,
|
||||
read_device_callback, &self->call_idx, _True) != de_None)
|
||||
read_device_callback, &self->call_idx, true) != de_None)
|
||||
/* Set VAD as true for all; TODO: Make it more dynamic */
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to register input handler!");
|
||||
|
||||
@ -225,7 +232,7 @@ int stop_transmission(int call_index)
|
||||
{
|
||||
if ( ASettins.calls[call_index].ttas ) {
|
||||
toxav_kill_transmission(ASettins.av, call_index);
|
||||
ASettins.calls[call_index].ttas = _False;
|
||||
ASettins.calls[call_index].ttas = false;
|
||||
|
||||
if ( ASettins.calls[call_index].in_idx != -1 )
|
||||
close_device(input, ASettins.calls[call_index].in_idx);
|
||||
@ -233,7 +240,9 @@ int stop_transmission(int call_index)
|
||||
if ( ASettins.calls[call_index].out_idx != -1 )
|
||||
close_device(output, ASettins.calls[call_index].out_idx);
|
||||
|
||||
set_call(&ASettins.calls[call_index], _False);
|
||||
if (set_call(&ASettins.calls[call_index], false) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -452,7 +461,7 @@ void cmd_hangup(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
|
||||
if (toxav_get_call_state(ASettins.av, self->call_idx) == av_CallInviting) {
|
||||
error = toxav_cancel(ASettins.av, self->call_idx, self->num,
|
||||
"Only those who appreciate small things know the beauty that is life");
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call canceled!");
|
||||
@ -610,7 +619,7 @@ void cmd_ccur_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a
|
||||
open_device(input, selection, &this_call->in_idx, csettings.audio_sample_rate,
|
||||
csettings.audio_frame_duration, csettings.audio_channels);
|
||||
/* Set VAD as true for all; TODO: Make it more dynamic */
|
||||
register_device_callback(self->call_idx, this_call->in_idx, read_device_callback, &self->call_idx, _True);
|
||||
register_device_callback(self->call_idx, this_call->in_idx, read_device_callback, &self->call_idx, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _audio_h
|
||||
#define _audio_h
|
||||
#ifndef AUDIO_H
|
||||
#define AUDIO_H
|
||||
|
||||
#include <tox/toxav.h>
|
||||
|
||||
@ -42,4 +42,4 @@ void terminate_audio();
|
||||
|
||||
void stop_current_call(ToxWindow *self);
|
||||
|
||||
#endif /* _audio_h */
|
||||
#endif /* AUDIO_H */
|
||||
|
@ -104,7 +104,9 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
||||
if (wcs_to_mbs_buf(ubuf, ctx->line, sizeof(ubuf)) == -1)
|
||||
return -1;
|
||||
|
||||
bool dir_search = strncmp(ubuf, "/sendfile", strlen("/sendfile")) == 0;
|
||||
/* TODO: generalize this */
|
||||
bool dir_search = !strncmp(ubuf, "/sendfile", strlen("/sendfile"))
|
||||
|| !strncmp(ubuf, "/avatar", strlen("/avatar"));
|
||||
|
||||
/* isolate substring from space behind pos to pos */
|
||||
char tmp[MAX_STR_SIZE];
|
||||
@ -202,8 +204,8 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
||||
return diff;
|
||||
}
|
||||
|
||||
/* transforms a sendfile tab complete contaning the shorthand "~/" into the full home directory.*/
|
||||
static void complt_home_dir(ToxWindow *self, char *path, int pathsize)
|
||||
/* transforms a tab complete starting with the shorthand "~" into the full home directory.*/
|
||||
static void complt_home_dir(ToxWindow *self, char *path, int pathsize, const char *cmd, int cmdlen)
|
||||
{
|
||||
ChatContext *ctx = self->chatwin;
|
||||
|
||||
@ -211,8 +213,8 @@ static void complt_home_dir(ToxWindow *self, char *path, int pathsize)
|
||||
get_home_dir(homedir, sizeof(homedir));
|
||||
|
||||
char newline[MAX_STR_SIZE];
|
||||
snprintf(newline, sizeof(newline), "/sendfile \"%s%s", homedir, path + 1);
|
||||
snprintf(path, pathsize, "%s", &newline[11]);
|
||||
snprintf(newline, sizeof(newline), "%s \"%s%s", cmd, homedir, path + 1);
|
||||
snprintf(path, pathsize, "%s", &newline[cmdlen]);
|
||||
|
||||
wchar_t wline[MAX_STR_SIZE];
|
||||
|
||||
@ -229,23 +231,27 @@ static void complt_home_dir(ToxWindow *self, char *path, int pathsize)
|
||||
ctx->len = ctx->pos;
|
||||
}
|
||||
|
||||
/* attempts to match /sendfile "<incomplete-dir>" line to matching directories.
|
||||
/* attempts to match /command "<incomplete-dir>" line to matching directories.
|
||||
|
||||
if only one match, auto-complete line.
|
||||
return diff between old len and new len of ctx->line, -1 if no matches or > 1 match */
|
||||
#define MAX_DIRS 512
|
||||
|
||||
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line)
|
||||
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
|
||||
{
|
||||
char b_path[MAX_STR_SIZE];
|
||||
char b_name[MAX_STR_SIZE];
|
||||
const wchar_t *tmpline = &line[11]; /* start after "/sendfile \"" */
|
||||
char b_cmd[MAX_STR_SIZE];
|
||||
const wchar_t *tmpline = &line[wcslen(cmd) + 2]; /* start after "/command \"" */
|
||||
|
||||
if (wcs_to_mbs_buf(b_path, tmpline, sizeof(b_path)) == -1)
|
||||
return -1;
|
||||
|
||||
if (wcs_to_mbs_buf(b_cmd, cmd, sizeof(b_cmd)) == -1)
|
||||
return -1;
|
||||
|
||||
if (b_path[0] == '~')
|
||||
complt_home_dir(self, b_path, sizeof(b_path));
|
||||
complt_home_dir(self, b_path, sizeof(b_path), b_cmd, strlen(b_cmd) + 2);
|
||||
|
||||
int si = char_rfind(b_path, '/', strlen(b_path));
|
||||
|
||||
@ -261,7 +267,6 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line)
|
||||
strcpy(b_name, &b_path[si + 1]);
|
||||
b_path[si + 1] = '\0';
|
||||
int b_name_len = strlen(b_name);
|
||||
|
||||
DIR *dp = opendir(b_path);
|
||||
|
||||
if (dp == NULL)
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _autocomplete_h
|
||||
#define _autocomplete_h
|
||||
#ifndef AUTOCOMPLETE_H
|
||||
#define AUTOCOMPLETE_H
|
||||
|
||||
/* looks for all instances in list that begin with the last entered word in line according to pos,
|
||||
then fills line with the complete word. e.g. "Hello jo" would complete the line
|
||||
@ -33,10 +33,10 @@
|
||||
Returns the difference between the old len and new len of line on success, -1 if error */
|
||||
int complete_line(ToxWindow *self, const void *list, int n_items, int size);
|
||||
|
||||
/* attempts to match /sendfile "<incomplete-dir>" line to matching directories.
|
||||
/* attempts to match /command "<incomplete-dir>" line to matching directories.
|
||||
|
||||
if only one match, auto-complete line.
|
||||
return diff between old len and new len of ctx->line, -1 if no matches or > 1 match */
|
||||
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line);
|
||||
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd);
|
||||
|
||||
#endif /* #define _autocomplete_h */
|
||||
#endif /* #define AUTOCOMPLETE_H */
|
||||
|
141
src/chat.c
141
src/chat.c
@ -45,34 +45,35 @@
|
||||
#include "notify.h"
|
||||
#include "message_queue.h"
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
#include "audio_call.h"
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
|
||||
extern char *DATA_FILE;
|
||||
|
||||
extern FileSender file_senders[MAX_FILES];
|
||||
extern _Friends Friends;
|
||||
extern FriendsList Friends;
|
||||
|
||||
extern struct _Winthread Winthread;
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct Winthread Winthread;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
static void init_infobox(ToxWindow *self);
|
||||
static void kill_infobox(ToxWindow *self);
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#ifdef _AUDIO
|
||||
#define AC_NUM_CHAT_COMMANDS 26
|
||||
#ifdef AUDIO
|
||||
#define AC_NUM_CHAT_COMMANDS 27
|
||||
#else
|
||||
#define AC_NUM_CHAT_COMMANDS 19
|
||||
#endif /* _AUDIO */
|
||||
#define AC_NUM_CHAT_COMMANDS 20
|
||||
#endif /* AUDIO */
|
||||
|
||||
/* Array of chat command names used for tab completion. */
|
||||
static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/accept" },
|
||||
{ "/add" },
|
||||
{ "/avatar" },
|
||||
{ "/cancel" },
|
||||
{ "/clear" },
|
||||
{ "/close" },
|
||||
@ -91,7 +92,7 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/sendfile" },
|
||||
{ "/status" },
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
|
||||
{ "/call" },
|
||||
{ "/answer" },
|
||||
@ -101,12 +102,12 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/mute" },
|
||||
{ "/sense" },
|
||||
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
};
|
||||
|
||||
static void set_self_typingstatus(ToxWindow *self, Tox *m, uint8_t is_typing)
|
||||
{
|
||||
if (user_settings_->show_typing_self == SHOW_TYPING_OFF)
|
||||
if (user_settings->show_typing_self == SHOW_TYPING_OFF)
|
||||
return;
|
||||
|
||||
ChatContext *ctx = self->chatwin;
|
||||
@ -137,7 +138,7 @@ void kill_chat_window(ToxWindow *self, Tox *m)
|
||||
line_info_cleanup(ctx->hst);
|
||||
cqueue_cleanup(ctx->cqueue);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
stop_current_call(self);
|
||||
#endif
|
||||
|
||||
@ -197,7 +198,7 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_
|
||||
|
||||
if (status == 1) { /* Friend goes online */
|
||||
statusbar->is_online = true;
|
||||
Friends.list[num].is_typing = user_settings_->show_typing_other == SHOW_TYPING_ON
|
||||
Friends.list[num].is_typing = user_settings->show_typing_other == SHOW_TYPING_ON
|
||||
? tox_get_is_typing(m, num) : 0;
|
||||
chat_resume_file_transfers(m, num);
|
||||
|
||||
@ -317,9 +318,9 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
|
||||
}
|
||||
|
||||
/* use specified path in config if possible */
|
||||
if (user_settings_->download_path[0]) {
|
||||
snprintf(filename_path, sizeof(filename_path), "%s%s", user_settings_->download_path, filename_nopath);
|
||||
len += strlen(user_settings_->download_path);
|
||||
if (user_settings->download_path[0]) {
|
||||
snprintf(filename_path, sizeof(filename_path), "%s%s", user_settings->download_path, filename_nopath);
|
||||
len += strlen(user_settings->download_path);
|
||||
}
|
||||
|
||||
if (len >= sizeof(Friends.list[num].file_receiver[filenum].filename)) {
|
||||
@ -528,7 +529,12 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
|
||||
uint64_t datapos;
|
||||
memcpy(&datapos, tmp, sizeof(uint64_t));
|
||||
|
||||
fseek(fp, datapos, SEEK_SET);
|
||||
if (fseek(fp, datapos, SEEK_SET) == -1) {
|
||||
snprintf(msg, sizeof(msg), "File transfer for '%s' failed.", filename);
|
||||
close_file_sender(self, m, send_idx, NULL, TOX_FILECONTROL_FINISHED, filenum, num);
|
||||
break;
|
||||
}
|
||||
|
||||
tox_file_send_control(m, num, 0, filenum, TOX_FILECONTROL_ACCEPT, 0, 0);
|
||||
file_senders[send_idx].noconnection = false;
|
||||
break;
|
||||
@ -557,32 +563,40 @@ static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenu
|
||||
Friends.list[num].file_receiver[filenum].bytes_recv += length;
|
||||
}
|
||||
|
||||
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, const char *group_pub_key)
|
||||
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, const char *group_pub_key, uint16_t length)
|
||||
{
|
||||
if (self->num != friendnumber)
|
||||
return;
|
||||
|
||||
if (Friends.list[friendnumber].group_invite.key != NULL)
|
||||
free(Friends.list[friendnumber].group_invite.key);
|
||||
|
||||
char *k = malloc(length);
|
||||
|
||||
if (k == NULL)
|
||||
exit_toxic_err("Failed in chat_onGroupInvite", FATALERR_MEMORY);
|
||||
|
||||
memcpy(k, group_pub_key, length);
|
||||
Friends.list[friendnumber].group_invite.key = k;
|
||||
Friends.list[friendnumber].group_invite.pending = true;
|
||||
Friends.list[friendnumber].group_invite.length = length;
|
||||
|
||||
char name[TOX_MAX_NAME_LENGTH];
|
||||
get_nick_truncate(m, name, friendnumber);
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a group chat.", name);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat.");
|
||||
|
||||
memcpy(Friends.list[friendnumber].groupchat_key, group_pub_key,
|
||||
sizeof(Friends.list[friendnumber].groupchat_key));
|
||||
Friends.list[friendnumber].groupchat_pending = true;
|
||||
|
||||
|
||||
sound_notify(self, generic_message, NT_WNDALERT_2, NULL);
|
||||
|
||||
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, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s has invited you to a group chat.", name);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat.");
|
||||
}
|
||||
|
||||
/* Av Stuff */
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
|
||||
void chat_onInvite (ToxWindow *self, ToxAv *av, int call_index)
|
||||
{
|
||||
@ -611,10 +625,10 @@ void chat_onRinging (ToxWindow *self, ToxAv *av, int call_index)
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Ringing...type \"/hangup\" to cancel it.");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
if (self->ringing_sound == -1)
|
||||
sound_notify(self, call_outgoing, NT_LOOP, &self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -626,9 +640,9 @@ void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index)
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call started! Type: \"/hangup\" to end it.");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -640,9 +654,9 @@ void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index)
|
||||
self->call_idx = -1;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call ended!");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onError (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -653,9 +667,9 @@ void chat_onError (ToxWindow *self, ToxAv *av, int call_index)
|
||||
self->call_idx = -1;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error!");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onStart (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -667,9 +681,9 @@ void chat_onStart (ToxWindow *self, ToxAv *av, int call_index)
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call started! Type: \"/hangup\" to end it.");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -681,9 +695,9 @@ void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index)
|
||||
self->call_idx = -1;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call canceled!");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onReject (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -694,9 +708,9 @@ void chat_onReject (ToxWindow *self, ToxAv *av, int call_index)
|
||||
self->call_idx = -1;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Rejected!");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -708,9 +722,9 @@ void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index)
|
||||
self->call_idx = -1;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Call ended!");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onRequestTimeout (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -721,9 +735,9 @@ void chat_onRequestTimeout (ToxWindow *self, ToxAv *av, int call_index)
|
||||
self->call_idx = -1;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No answer!");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index)
|
||||
@ -735,9 +749,9 @@ void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index)
|
||||
self->call_idx = -1;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer disconnected; call ended!");
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
stop_sound(self->ringing_sound);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
static void init_infobox(ToxWindow *self)
|
||||
@ -752,7 +766,7 @@ static void init_infobox(ToxWindow *self)
|
||||
|
||||
ctx->infobox.win = newwin(INFOBOX_HEIGHT, INFOBOX_WIDTH + 1, 1, x2 - INFOBOX_WIDTH);
|
||||
ctx->infobox.starttime = get_unix_time();
|
||||
ctx->infobox.vad_lvl = user_settings_->VAD_treshold;
|
||||
ctx->infobox.vad_lvl = user_settings->VAD_treshold;
|
||||
ctx->infobox.active = true;
|
||||
strcpy(ctx->infobox.timestr, "00");
|
||||
}
|
||||
@ -822,7 +836,7 @@ static void draw_infobox(ToxWindow *self)
|
||||
wrefresh(infobox->win);
|
||||
}
|
||||
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action)
|
||||
{
|
||||
@ -874,8 +888,11 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
if (key == '\t' && ctx->len > 1 && ctx->line[0] == '/') { /* TAB key: auto-complete */
|
||||
int diff = -1;
|
||||
|
||||
/* TODO: make this not suck */
|
||||
if (wcsncmp(ctx->line, L"/sendfile \"", wcslen(L"/sendfile \"")) == 0) {
|
||||
diff = dir_match(self, m, ctx->line);
|
||||
diff = dir_match(self, m, ctx->line, L"/sendfile");
|
||||
} else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) {
|
||||
diff = dir_match(self, m, ctx->line, L"/avatar");
|
||||
} else {
|
||||
diff = complete_line(self, chat_cmd_list, AC_NUM_CHAT_COMMANDS, MAX_CMDNAME_SIZE);
|
||||
}
|
||||
@ -1017,7 +1034,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
||||
}
|
||||
|
||||
if (statusbar->statusmsg[0])
|
||||
wprintw(statusbar->topline, "- %s ", statusbar->statusmsg);
|
||||
wprintw(statusbar->topline, ": %s ", statusbar->statusmsg);
|
||||
|
||||
wclrtoeol(statusbar->topline);
|
||||
wmove(statusbar->topline, 0, x2 - (KEY_IDENT_DIGITS * 2) - 3);
|
||||
@ -1040,7 +1057,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
||||
|
||||
wrefresh(self->window);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
if (ctx->infobox.active) {
|
||||
draw_infobox(self);
|
||||
wrefresh(self->window);
|
||||
@ -1091,8 +1108,14 @@ static void chat_onInit(ToxWindow *self, Tox *m)
|
||||
|
||||
line_info_init(ctx->hst);
|
||||
|
||||
if (Friends.list[self->num].logging_on)
|
||||
log_enable(nick, Friends.list[self->num].pub_key, ctx->log);
|
||||
char myid[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(m, (uint8_t *) myid);
|
||||
|
||||
log_enable(nick, myid, Friends.list[self->num].pub_key, ctx->log, LOG_CHAT);
|
||||
load_chat_history(self, ctx->log);
|
||||
|
||||
if (!Friends.list[self->num].logging_on)
|
||||
log_disable(ctx->log);
|
||||
|
||||
execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE);
|
||||
|
||||
@ -1124,7 +1147,7 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
|
||||
ret.onFileData = &chat_onFileData;
|
||||
ret.onReadReceipt = &chat_onReadReceipt;
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
ret.onInvite = &chat_onInvite;
|
||||
ret.onRinging = &chat_onRinging;
|
||||
ret.onStarting = &chat_onStarting;
|
||||
@ -1140,7 +1163,7 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
|
||||
ret.call_idx = -1;
|
||||
ret.device_selection[0] = ret.device_selection[1] = -1;
|
||||
ret.ringing_sound = -1;
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
ret.active_box = -1;
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CHAT_H_6489PZ13
|
||||
#define CHAT_H_6489PZ13
|
||||
#ifndef CHAT_H
|
||||
#define CHAT_H
|
||||
|
||||
#include "windows.h"
|
||||
#include "toxic.h"
|
||||
@ -32,4 +32,4 @@ void chat_close_file_receiver(Tox *m, int filenum, int friendnum, int CTRL);
|
||||
void kill_chat_window(ToxWindow *self, Tox *m);
|
||||
ToxWindow new_chat(Tox *m, int32_t friendnum);
|
||||
|
||||
#endif /* end of include guard: CHAT_H_6489PZ13 */
|
||||
#endif /* end of include guard: CHAT_H */
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "file_senders.h"
|
||||
|
||||
extern ToxWindow *prompt;
|
||||
extern _Friends Friends;
|
||||
extern FriendsList Friends;
|
||||
|
||||
extern FileSender file_senders[MAX_FILES];
|
||||
extern uint8_t max_file_senders_index;
|
||||
@ -123,14 +123,15 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar
|
||||
return;
|
||||
}
|
||||
|
||||
const char *groupkey = Friends.list[self->num].groupchat_key;
|
||||
const char *groupkey = Friends.list[self->num].group_invite.key;
|
||||
uint16_t length = Friends.list[self->num].group_invite.length;
|
||||
|
||||
if (!Friends.list[self->num].groupchat_pending) {
|
||||
if (!Friends.list[self->num].group_invite.pending) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending group chat invite.");
|
||||
return;
|
||||
}
|
||||
|
||||
int groupnum = tox_join_groupchat(m, self->num, (uint8_t *) groupkey);
|
||||
int groupnum = tox_join_groupchat(m, self->num, (uint8_t *) groupkey, length);
|
||||
|
||||
if (groupnum == -1) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat instance failed to initialize.");
|
||||
@ -224,9 +225,13 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(file_to_send, 0, SEEK_END);
|
||||
uint64_t filesize = ftell(file_to_send);
|
||||
fseek(file_to_send, 0, SEEK_SET);
|
||||
off_t filesize = file_size(path);
|
||||
|
||||
if (filesize == -1) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "File corrupt.");
|
||||
fclose(file_to_send);
|
||||
return;
|
||||
}
|
||||
|
||||
char filename[MAX_STR_SIZE] = {0};
|
||||
get_file_name(filename, sizeof(filename), path);
|
||||
@ -235,6 +240,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
||||
|
||||
if (filenum == -1) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error sending file.");
|
||||
fclose(file_to_send);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _chat_commands_h
|
||||
#define _chat_commands_h
|
||||
#ifndef CHAT_COMMANDS_H
|
||||
#define CHAT_COMMANDS_H
|
||||
|
||||
#include "windows.h"
|
||||
#include "toxic.h"
|
||||
@ -32,7 +32,7 @@ void cmd_join_group(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR
|
||||
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]);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
void cmd_call(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_answer(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_reject(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
@ -41,6 +41,6 @@ void cmd_cancel(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZ
|
||||
void cmd_ccur_device(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_mute(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_sense(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#endif /* #define _chat_commands_h */
|
||||
#endif /* #define CHAT_COMMANDS_H */
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _configdir_h
|
||||
#define _configdir_h
|
||||
#ifndef CONFIGDIR_H
|
||||
#define CONFIGDIR_H
|
||||
|
||||
#ifndef NSS_BUFLEN_PASSWD
|
||||
#define NSS_BUFLEN_PASSWD 4096
|
||||
@ -38,4 +38,4 @@ char *get_user_config_dir(void);
|
||||
void get_home_dir(char *home, int size);
|
||||
int create_user_config_dirs(char *path);
|
||||
|
||||
#endif /* #define _configdir_h */
|
||||
#endif /* #define CONFIGDIR_H */
|
||||
|
98
src/device.c
98
src/device.c
@ -22,7 +22,7 @@
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
#include "audio_call.h"
|
||||
#endif
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
@ -50,9 +51,9 @@
|
||||
#define OPENAL_BUFS 5
|
||||
#define inline__ inline __attribute__((always_inline))
|
||||
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
typedef struct _Device {
|
||||
typedef struct Device {
|
||||
ALCdevice *dhndl; /* Handle of device selected/opened */
|
||||
ALCcontext *ctx; /* Device context */
|
||||
DataHandleCallback cb; /* Use this to handle data from input device usually */
|
||||
@ -60,15 +61,15 @@ typedef struct _Device {
|
||||
int32_t call_idx; /* ToxAv call index */
|
||||
|
||||
uint32_t source, buffers[OPENAL_BUFS]; /* Playback source/buffers */
|
||||
size_t ref_count;
|
||||
uint32_t ref_count;
|
||||
int32_t selection;
|
||||
_Bool enable_VAD;
|
||||
_Bool muted;
|
||||
bool enable_VAD;
|
||||
bool muted;
|
||||
pthread_mutex_t mutex[1];
|
||||
uint32_t sample_rate;
|
||||
uint32_t frame_duration;
|
||||
int32_t sound_mode;
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
float VAD_treshold; /* 40 is usually recommended value */
|
||||
#endif
|
||||
} Device;
|
||||
@ -76,12 +77,12 @@ typedef struct _Device {
|
||||
const char *ddevice_names[2]; /* Default device */
|
||||
const char *devices_names[2][MAX_DEVICES]; /* Container of available devices */
|
||||
static int size[2]; /* Size of above containers */
|
||||
Device *running[2][MAX_DEVICES]; /* Running devices */
|
||||
Device *running[2][MAX_DEVICES] = {{NULL}}; /* Running devices */
|
||||
uint32_t primary_device[2]; /* Primary device */
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
static ToxAv* av = NULL;
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
/* q_mutex */
|
||||
#define lock pthread_mutex_lock(&mutex)
|
||||
@ -89,21 +90,19 @@ static ToxAv* av = NULL;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
|
||||
_Bool thread_running = _True,
|
||||
thread_paused = _True; /* Thread control */
|
||||
bool thread_running = true,
|
||||
thread_paused = true; /* Thread control */
|
||||
|
||||
void* thread_poll(void*);
|
||||
/* Meet devices */
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
DeviceError init_devices(ToxAv* av_)
|
||||
#else
|
||||
DeviceError init_devices()
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
{
|
||||
const char *stringed_device_list;
|
||||
|
||||
|
||||
|
||||
size[input] = 0;
|
||||
if ( (stringed_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER)) ) {
|
||||
ddevice_names[input] = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
||||
@ -114,8 +113,6 @@ DeviceError init_devices()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
size[output] = 0;
|
||||
if ( (stringed_device_list = alcGetString(NULL, ALC_DEVICE_SPECIFIER)) ) {
|
||||
ddevice_names[output] = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
@ -127,16 +124,16 @@ DeviceError init_devices()
|
||||
}
|
||||
|
||||
// Start poll thread
|
||||
|
||||
pthread_mutex_init(&mutex, NULL);
|
||||
if (pthread_mutex_init(&mutex, NULL) != 0)
|
||||
return de_InternalError;
|
||||
|
||||
pthread_t thread_id;
|
||||
if ( pthread_create(&thread_id, NULL, thread_poll, NULL) != 0 || pthread_detach(thread_id) != 0)
|
||||
return de_InternalError;
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
av = av_;
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
return (DeviceError) de_None;
|
||||
}
|
||||
@ -147,7 +144,8 @@ DeviceError terminate_devices()
|
||||
thread_running = false;
|
||||
usleep(20000);
|
||||
|
||||
pthread_mutex_destroy(&mutex);
|
||||
if (pthread_mutex_destroy(&mutex) != 0)
|
||||
return (DeviceError) de_InternalError;
|
||||
|
||||
return (DeviceError) de_None;
|
||||
}
|
||||
@ -170,7 +168,7 @@ DeviceError device_mute(DeviceType type, uint32_t device_idx)
|
||||
return de_None;
|
||||
}
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
DeviceError device_set_VAD_treshold(uint32_t device_idx, float value)
|
||||
{
|
||||
if (device_idx >= MAX_DEVICES) return de_InvalidSelection;
|
||||
@ -222,6 +220,18 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
||||
if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; }
|
||||
else *device_idx = i;
|
||||
|
||||
for (i = 0; i < MAX_DEVICES; i ++) { /* Check if any device has the same selection */
|
||||
if ( running[type][i] && running[type][i]->selection == selection ) {
|
||||
// printf("a%d-%d:%p ", selection, i, running[type][i]->dhndl);
|
||||
|
||||
running[type][*device_idx] = running[type][i];
|
||||
running[type][i]->ref_count ++;
|
||||
|
||||
unlock;
|
||||
return de_None;
|
||||
}
|
||||
}
|
||||
|
||||
Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));
|
||||
device->selection = selection;
|
||||
|
||||
@ -229,26 +239,17 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
||||
device->frame_duration = frame_duration;
|
||||
device->sound_mode = channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
||||
|
||||
for (i = 0; i < *device_idx; i ++) { /* Check if any previous has the same selection */
|
||||
if ( running[type][i]->selection == selection ) {
|
||||
device->dhndl = running[type][i]->dhndl;
|
||||
if (type == output) {
|
||||
device->ctx = running[type][i]->ctx;
|
||||
memcpy(device->buffers, running[type][i]->buffers, sizeof(running[type][i]->buffers));
|
||||
device->source = running[type][i]->source;
|
||||
}
|
||||
device->ref_count++;
|
||||
pthread_mutex_init(device->mutex, NULL);
|
||||
if (pthread_mutex_init(device->mutex, NULL) != 0) {
|
||||
free(device);
|
||||
unlock;
|
||||
return de_None;
|
||||
}
|
||||
return de_InternalError;
|
||||
}
|
||||
|
||||
if (type == input) {
|
||||
device->dhndl = alcCaptureOpenDevice(devices_names[type][selection],
|
||||
sample_rate, device->sound_mode, frame_size * 2);
|
||||
#ifdef _AUDIO
|
||||
device->VAD_treshold = user_settings_->VAD_treshold;
|
||||
#ifdef AUDIO
|
||||
device->VAD_treshold = user_settings->VAD_treshold;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@ -287,10 +288,9 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
||||
|
||||
if (type == input) {
|
||||
alcCaptureStart(device->dhndl);
|
||||
thread_paused = _False;
|
||||
thread_paused = false;
|
||||
}
|
||||
|
||||
pthread_mutex_init(device->mutex, NULL);
|
||||
unlock;
|
||||
return de_None;
|
||||
}
|
||||
@ -301,17 +301,18 @@ DeviceError close_device(DeviceType type, uint32_t device_idx)
|
||||
|
||||
lock;
|
||||
Device* device = running[type][device_idx];
|
||||
DeviceError rc = de_None;
|
||||
|
||||
if (!device) {
|
||||
unlock;
|
||||
return de_DeviceNotActive;
|
||||
}
|
||||
|
||||
if ( !(device->ref_count--) ) {
|
||||
running[type][device_idx] = NULL;
|
||||
unlock;
|
||||
|
||||
DeviceError rc = de_None;
|
||||
if ( !device->ref_count ) {
|
||||
|
||||
// printf("Closed device ");
|
||||
|
||||
if (type == input) {
|
||||
if ( !alcCaptureCloseDevice(device->dhndl) ) rc = de_AlError;
|
||||
@ -328,15 +329,14 @@ DeviceError close_device(DeviceType type, uint32_t device_idx)
|
||||
}
|
||||
|
||||
free(device);
|
||||
return rc;
|
||||
}
|
||||
else device->ref_count--;
|
||||
|
||||
unlock;
|
||||
|
||||
return de_None;
|
||||
return rc;
|
||||
}
|
||||
|
||||
DeviceError register_device_callback( int32_t call_idx, uint32_t device_idx, DataHandleCallback callback, void* data, _Bool enable_VAD)
|
||||
DeviceError register_device_callback( int32_t call_idx, uint32_t device_idx, DataHandleCallback callback, void* data, bool enable_VAD)
|
||||
{
|
||||
if (size[input] <= device_idx || !running[input][device_idx] || running[input][device_idx]->dhndl == NULL)
|
||||
return de_InvalidSelection;
|
||||
@ -427,9 +427,9 @@ void* thread_poll (void* arg) // TODO: maybe use thread for every input source
|
||||
alcCaptureSamples(device->dhndl, frame, f_size);
|
||||
|
||||
if ( device->muted
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
|| (device->enable_VAD && !toxav_has_activity(av, device->call_idx, frame, f_size, device->VAD_treshold))
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
)
|
||||
{ unlock; continue; } /* Skip if no voice activity */
|
||||
|
||||
|
17
src/device.h
17
src/device.h
@ -26,16 +26,13 @@
|
||||
* Read from running input device(s) via select()/callback combo.
|
||||
*/
|
||||
|
||||
#ifndef _device_h
|
||||
#define _device_h
|
||||
#ifndef DEVICE_H
|
||||
#define DEVICE_H
|
||||
|
||||
#define MAX_DEVICES 32
|
||||
#include <inttypes.h>
|
||||
#include "windows.h"
|
||||
|
||||
#define _True 1
|
||||
#define _False 0
|
||||
|
||||
typedef enum DeviceType {
|
||||
input,
|
||||
output,
|
||||
@ -57,22 +54,22 @@ typedef enum DeviceError {
|
||||
typedef void (*DataHandleCallback) (const int16_t*, uint32_t size, void* data);
|
||||
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
DeviceError init_devices(ToxAv* av);
|
||||
#else
|
||||
DeviceError init_devices();
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
DeviceError terminate_devices();
|
||||
|
||||
/* Callback handles ready data from INPUT device */
|
||||
DeviceError register_device_callback(int32_t call_idx, uint32_t device_idx, DataHandleCallback callback, void* data, _Bool enable_VAD);
|
||||
DeviceError register_device_callback(int32_t call_idx, uint32_t device_idx, DataHandleCallback callback, void* data, bool enable_VAD);
|
||||
void* get_device_callback_data(uint32_t device_idx);
|
||||
|
||||
/* toggle device mute */
|
||||
DeviceError device_mute(DeviceType type, uint32_t device_idx);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
DeviceError device_set_VAD_treshold(uint32_t device_idx, float value);
|
||||
#endif
|
||||
|
||||
@ -89,4 +86,4 @@ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t lenght, uint8
|
||||
void print_devices(ToxWindow* self, DeviceType type);
|
||||
|
||||
DeviceError selection_valid(DeviceType type, int32_t selection);
|
||||
#endif /* _device_h */
|
||||
#endif /* DEVICE_H */
|
||||
|
@ -46,7 +46,7 @@
|
||||
#define MAX_DNS_REQST_SIZE 255
|
||||
#define TOX_DNS3_TXT_PREFIX "v=tox3;id="
|
||||
|
||||
extern struct _Winthread Winthread;
|
||||
extern struct Winthread Winthread;
|
||||
extern struct _dns3_servers dns3_servers;
|
||||
extern struct arg_opts arg_opts;
|
||||
|
||||
|
@ -23,10 +23,10 @@
|
||||
/* Does DNS lookup for addr and puts resulting tox id in id_bin.
|
||||
Return 0 on success, -1 on failure. */
|
||||
|
||||
#ifndef _dns_h
|
||||
#define _dns_h
|
||||
#ifndef DNS_H
|
||||
#define DNS_H
|
||||
|
||||
/* creates new thread for dns3 lookup. Only allows one lookup at a time. */
|
||||
void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg);
|
||||
|
||||
#endif /* #define _dns_h */
|
||||
#endif /* #define DNS_H */
|
||||
|
@ -41,6 +41,7 @@ struct cmd_func {
|
||||
static struct cmd_func global_commands[] = {
|
||||
{ "/accept", cmd_accept },
|
||||
{ "/add", cmd_add },
|
||||
{ "/avatar", cmd_avatar },
|
||||
{ "/clear", cmd_clear },
|
||||
{ "/connect", cmd_connect },
|
||||
{ "/decline", cmd_decline },
|
||||
@ -55,10 +56,10 @@ static struct cmd_func global_commands[] = {
|
||||
{ "/quit", cmd_quit },
|
||||
{ "/requests", cmd_requests },
|
||||
{ "/status", cmd_status },
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
{ "/lsdev", cmd_list_devices },
|
||||
{ "/sdev", cmd_change_device },
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
@ -68,7 +69,7 @@ static struct cmd_func chat_commands[] = {
|
||||
{ "/join", cmd_join_group },
|
||||
{ "/savefile", cmd_savefile },
|
||||
{ "/sendfile", cmd_sendfile },
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
{ "/call", cmd_call },
|
||||
{ "/answer", cmd_answer },
|
||||
{ "/reject", cmd_reject },
|
||||
@ -76,7 +77,7 @@ static struct cmd_func chat_commands[] = {
|
||||
{ "/sdev", cmd_ccur_device },
|
||||
{ "/mute", cmd_mute },
|
||||
{ "/sense", cmd_sense },
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _execute_h
|
||||
#define _execute_h
|
||||
#ifndef EXECUTE_H
|
||||
#define EXECUTE_H
|
||||
|
||||
#include "toxic.h"
|
||||
#include "windows.h"
|
||||
@ -36,4 +36,4 @@ enum {
|
||||
|
||||
void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode);
|
||||
|
||||
#endif /* #define _execute_h */
|
||||
#endif /* #define EXECUTE_H */
|
||||
|
@ -36,7 +36,7 @@
|
||||
FileSender file_senders[MAX_FILES];
|
||||
uint8_t max_file_senders_index;
|
||||
uint8_t num_active_file_senders;
|
||||
extern _Friends Friends;
|
||||
extern FriendsList Friends;
|
||||
|
||||
/* creates initial progress line that will be updated during file transfer.
|
||||
Assumes progline is of size MAX_STR_SIZE */
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _filesenders_h
|
||||
#define _filesenders_h
|
||||
#ifndef FILESENDERS_H
|
||||
#define FILESENDERS_H
|
||||
|
||||
#include "toxic.h"
|
||||
#include "windows.h"
|
||||
@ -72,4 +72,4 @@ void reset_file_sender_queue(void);
|
||||
void close_all_file_senders(Tox *m);
|
||||
void do_file_senders(Tox *m);
|
||||
|
||||
#endif /* #define _filesenders_h */
|
||||
#endif /* #define FILESENDERS_H */
|
||||
|
@ -37,8 +37,9 @@
|
||||
#include "settings.h"
|
||||
#include "notify.h"
|
||||
#include "help.h"
|
||||
#include "log.h"
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
#include "audio_call.h"
|
||||
#endif
|
||||
|
||||
@ -46,15 +47,15 @@
|
||||
extern char *DATA_FILE;
|
||||
extern char *BLOCK_FILE;
|
||||
extern ToxWindow *prompt;
|
||||
extern struct _Winthread Winthread;
|
||||
extern struct user_settings *user_settings_;
|
||||
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 */
|
||||
|
||||
_Friends Friends;
|
||||
FriendsList Friends;
|
||||
|
||||
static struct _Blocked {
|
||||
static struct Blocked {
|
||||
int num_selected;
|
||||
int max_idx;
|
||||
int num_blocked;
|
||||
@ -63,7 +64,7 @@ static struct _Blocked {
|
||||
BlockedFriend *list;
|
||||
} Blocked;
|
||||
|
||||
static struct _pendingDel {
|
||||
static struct pendingDel {
|
||||
int num;
|
||||
bool active;
|
||||
WINDOW *popup;
|
||||
@ -111,6 +112,13 @@ static void realloc_blocklist(int n)
|
||||
|
||||
void kill_friendlist(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < Friends.max_idx; ++i) {
|
||||
if (Friends.list[i].active && Friends.list[i].group_invite.key != NULL)
|
||||
free(Friends.list[i].group_invite.key);
|
||||
}
|
||||
|
||||
realloc_blocklist(0);
|
||||
realloc_friends(0);
|
||||
}
|
||||
@ -163,6 +171,8 @@ static int save_blocklist(char *path)
|
||||
ret = 0;
|
||||
|
||||
fclose(fp);
|
||||
return ret;
|
||||
|
||||
on_error:
|
||||
free(data);
|
||||
return ret;
|
||||
@ -180,9 +190,12 @@ int load_blocklist(char *path)
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int len = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
off_t len = file_size(path);
|
||||
|
||||
if (len == -1) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *data = malloc(len);
|
||||
|
||||
@ -285,7 +298,7 @@ static void update_friend_last_online(int32_t num, uint64_t timestamp)
|
||||
Friends.list[num].last_online.tm = *localtime((const time_t*)×tamp);
|
||||
|
||||
/* if the format changes make sure TIME_STR_SIZE is the correct size */
|
||||
const char *t = user_settings_->time == TIME_12 ? "%I:%M %p" : "%H:%M";
|
||||
const char *t = user_settings->time == TIME_12 ? "%I:%M %p" : "%H:%M";
|
||||
strftime(Friends.list[num].last_online.hour_min_str, TIME_STR_SIZE, t,
|
||||
&Friends.list[num].last_online.tm);
|
||||
}
|
||||
@ -330,12 +343,27 @@ static void friendlist_onNickChange(ToxWindow *self, Tox *m, int32_t num, const
|
||||
if (len > TOX_MAX_NAME_LENGTH || num >= Friends.max_idx)
|
||||
return;
|
||||
|
||||
/* save old name for log renaming */
|
||||
char oldname[TOXIC_MAX_NAME_LENGTH];
|
||||
snprintf(oldname, sizeof(oldname), "%s", Friends.list[num].name);
|
||||
|
||||
/* update name */
|
||||
char tempname[TOX_MAX_NAME_LENGTH];
|
||||
strcpy(tempname, nick);
|
||||
len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
|
||||
tempname[len] = '\0';
|
||||
snprintf(Friends.list[num].name, sizeof(Friends.list[num].name), "%s", tempname);
|
||||
Friends.list[num].namelength = len;
|
||||
|
||||
/* get data for chatlog renaming */
|
||||
char newnamecpy[TOXIC_MAX_NAME_LENGTH];
|
||||
char myid[TOX_FRIEND_ADDRESS_SIZE];
|
||||
strcpy(newnamecpy, tempname);
|
||||
tox_get_address(m, (uint8_t *) myid);
|
||||
|
||||
if (strcmp(oldname, newnamecpy) != 0)
|
||||
rename_logfile(oldname, newnamecpy, myid, Friends.list[num].pub_key, Friends.list[num].chatwin);
|
||||
|
||||
sort_friendlist_index();
|
||||
}
|
||||
|
||||
@ -377,7 +405,7 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort)
|
||||
Friends.list[i].chatwin = -1;
|
||||
Friends.list[i].online = false;
|
||||
Friends.list[i].status = TOX_USERSTATUS_NONE;
|
||||
Friends.list[i].logging_on = (bool) user_settings_->autolog == AUTOLOG_ON;
|
||||
Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON;
|
||||
tox_get_client_id(m, num, (uint8_t *) Friends.list[i].pub_key);
|
||||
update_friend_last_online(i, tox_get_last_online(m, i));
|
||||
|
||||
@ -419,7 +447,7 @@ static void friendlist_add_blocked(Tox *m, int32_t fnum, int32_t bnum)
|
||||
Friends.list[i].active = true;
|
||||
Friends.list[i].chatwin = -1;
|
||||
Friends.list[i].status = TOX_USERSTATUS_NONE;
|
||||
Friends.list[i].logging_on = (bool) user_settings_->autolog == AUTOLOG_ON;
|
||||
Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON;
|
||||
Friends.list[i].namelength = Blocked.list[bnum].namelength;
|
||||
update_friend_last_online(i, Blocked.list[bnum].last_on);
|
||||
memcpy(Friends.list[i].name, Blocked.list[bnum].name, Friends.list[i].namelength + 1);
|
||||
@ -458,7 +486,7 @@ static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, u
|
||||
}
|
||||
}
|
||||
|
||||
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const char *group_pub_key)
|
||||
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const char *group_pub_key, uint16_t length)
|
||||
{
|
||||
if (num >= Friends.max_idx)
|
||||
return;
|
||||
@ -501,6 +529,9 @@ static void delete_friend(Tox *m, int32_t f_num)
|
||||
}
|
||||
}
|
||||
|
||||
if (Friends.list[f_num].group_invite.key != NULL)
|
||||
free(Friends.list[f_num].group_invite.key);
|
||||
|
||||
tox_del_friend(m, f_num);
|
||||
memset(&Friends.list[f_num], 0, sizeof(ToxicFriend));
|
||||
|
||||
@ -994,7 +1025,7 @@ void disable_chatwin(int32_t f_num)
|
||||
Friends.list[f_num].chatwin = -1;
|
||||
}
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index)
|
||||
{
|
||||
int id = toxav_get_peer_id(av, call_index, 0);
|
||||
@ -1021,7 +1052,7 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
ToxWindow new_friendlist(void)
|
||||
{
|
||||
@ -1043,7 +1074,7 @@ ToxWindow new_friendlist(void)
|
||||
ret.onFileSendRequest = &friendlist_onFileSendRequest;
|
||||
ret.onGroupInvite = &friendlist_onGroupInvite;
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
ret.onInvite = &friendlist_onAv;
|
||||
ret.onRinging = &friendlist_onAv;
|
||||
ret.onStarting = &friendlist_onAv;
|
||||
@ -1058,7 +1089,7 @@ ToxWindow new_friendlist(void)
|
||||
|
||||
ret.call_idx = -1;
|
||||
ret.device_selection[0] = ret.device_selection[1] = -1;
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
ret.active_box = -1;
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FRIENDLIST_H_53I41IM
|
||||
#define FRIENDLIST_H_53I41IM
|
||||
#ifndef FRIENDLIST_H
|
||||
#define FRIENDLIST_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
@ -48,13 +48,17 @@ struct LastOnline {
|
||||
char hour_min_str[TIME_STR_SIZE]; /* holds 12/24-hour time string e.g. "10:43 PM" */
|
||||
};
|
||||
|
||||
struct GroupChatInvite {
|
||||
char *key;
|
||||
uint16_t length;
|
||||
bool pending;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char name[TOXIC_MAX_NAME_LENGTH];
|
||||
int namelength;
|
||||
char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH];
|
||||
uint16_t statusmsg_len;
|
||||
char groupchat_key[TOX_CLIENT_ID_SIZE];
|
||||
bool groupchat_pending;
|
||||
char pub_key[TOX_CLIENT_ID_SIZE];
|
||||
int32_t num;
|
||||
int chatwin;
|
||||
@ -65,6 +69,7 @@ typedef struct {
|
||||
uint8_t status;
|
||||
struct LastOnline last_online;
|
||||
struct FileReceiver file_receiver[MAX_FILES];
|
||||
struct GroupChatInvite group_invite;
|
||||
uint8_t active_file_receivers;
|
||||
} ToxicFriend;
|
||||
|
||||
@ -83,7 +88,7 @@ typedef struct {
|
||||
int num_friends;
|
||||
int *index;
|
||||
ToxicFriend *list;
|
||||
} _Friends;
|
||||
} FriendsList;
|
||||
|
||||
ToxWindow new_friendlist(void);
|
||||
void disable_chatwin(int32_t f_num);
|
||||
@ -95,4 +100,4 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort);
|
||||
/* sorts friendlist_index first by connection status then alphabetically */
|
||||
void sort_friendlist_index(void);
|
||||
|
||||
#endif /* end of include guard: FRIENDLIST_H_53I41IM */
|
||||
#endif /* end of include guard: FRIENDLIST_H */
|
||||
|
@ -37,8 +37,8 @@
|
||||
|
||||
extern char *DATA_FILE;
|
||||
extern ToxWindow *prompt;
|
||||
extern _Friends Friends;
|
||||
extern _FriendRequests FriendRequests;
|
||||
extern FriendsList Friends;
|
||||
extern FriendRequests FrndRequests;
|
||||
|
||||
/* command functions */
|
||||
void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
@ -55,13 +55,13 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FriendRequests.request[req].active) {
|
||||
if (!FrndRequests.request[req].active) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID.");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *msg;
|
||||
int32_t friendnum = tox_add_friend_norequest(m, FriendRequests.request[req].key);
|
||||
int32_t friendnum = tox_add_friend_norequest(m, FrndRequests.request[req].key);
|
||||
|
||||
if (friendnum == -1)
|
||||
msg = "Failed to add friend.";
|
||||
@ -70,17 +70,17 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
|
||||
on_friendadded(m, friendnum, true);
|
||||
}
|
||||
|
||||
memset(&FriendRequests.request[req], 0, sizeof(struct _friend_request));
|
||||
memset(&FrndRequests.request[req], 0, sizeof(struct friend_request));
|
||||
|
||||
int i;
|
||||
|
||||
for (i = FriendRequests.max_idx; i > 0; --i) {
|
||||
if (FriendRequests.request[i - 1].active)
|
||||
for (i = FrndRequests.max_idx; i > 0; --i) {
|
||||
if (FrndRequests.request[i - 1].active)
|
||||
break;
|
||||
}
|
||||
|
||||
FriendRequests.max_idx = i;
|
||||
--FriendRequests.num_requests;
|
||||
FrndRequests.max_idx = i;
|
||||
--FrndRequests.num_requests;
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", msg);
|
||||
}
|
||||
|
||||
@ -184,6 +184,81 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
|
||||
}
|
||||
}
|
||||
|
||||
void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
{
|
||||
if (argc < 2) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: No file path supplied.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* turns the avatar off */
|
||||
if (strlen(argv[1]) < 3) {
|
||||
tox_unset_avatar(m);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No avatar set.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (argv[1][0] != '\"') {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Path must be enclosed in quotes.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* remove opening and closing quotes */
|
||||
char path[MAX_STR_SIZE];
|
||||
snprintf(path, sizeof(path), "%s", &argv[1][1]);
|
||||
int len = strlen(path) - 1;
|
||||
path[len] = '\0';
|
||||
|
||||
off_t sz = file_size(path);
|
||||
|
||||
if (sz <= 8) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Invalid file.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sz > TOX_AVATAR_MAX_DATA_LENGTH) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: File is too large.");
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *fp = fopen(path, "rb");
|
||||
|
||||
if (fp == NULL) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Could not open file.");
|
||||
return;
|
||||
}
|
||||
|
||||
char PNG_signature[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
||||
|
||||
if (check_file_signature(PNG_signature, sizeof(PNG_signature), fp) != 0) {
|
||||
fclose(fp);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: File type not supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
char *avatar = malloc(sz);
|
||||
|
||||
if (avatar == NULL)
|
||||
exit_toxic_err("Failed in set_avatar", FATALERR_MEMORY);
|
||||
|
||||
if (fread(avatar, sz, 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
free(avatar);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Read fail.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (tox_set_avatar(m, TOX_AVATAR_FORMAT_PNG, (const uint8_t *) avatar, (uint32_t) sz) == -1)
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Core error.");
|
||||
|
||||
char filename[MAX_STR_SIZE];
|
||||
get_file_name(filename, sizeof(filename), path);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar set to '%s'", filename);
|
||||
|
||||
fclose(fp);
|
||||
free(avatar);
|
||||
}
|
||||
|
||||
void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
{
|
||||
line_info_clear(self->chatwin->hst);
|
||||
@ -227,22 +302,22 @@ void cmd_decline(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!FriendRequests.request[req].active) {
|
||||
if (!FrndRequests.request[req].active) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend request with that ID.");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&FriendRequests.request[req], 0, sizeof(struct _friend_request));
|
||||
memset(&FrndRequests.request[req], 0, sizeof(struct friend_request));
|
||||
|
||||
int i;
|
||||
|
||||
for (i = FriendRequests.max_idx; i > 0; --i) {
|
||||
if (FriendRequests.request[i - 1].active)
|
||||
for (i = FrndRequests.max_idx; i > 0; --i) {
|
||||
if (FrndRequests.request[i - 1].active)
|
||||
break;
|
||||
}
|
||||
|
||||
FriendRequests.max_idx = i;
|
||||
--FriendRequests.num_requests;
|
||||
FrndRequests.max_idx = i;
|
||||
--FrndRequests.num_requests;
|
||||
}
|
||||
|
||||
void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
@ -286,16 +361,16 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
|
||||
const char *swch = argv[1];
|
||||
|
||||
if (!strcmp(swch, "1") || !strcmp(swch, "on")) {
|
||||
char myid[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(m, (uint8_t *) myid);
|
||||
|
||||
if (self->is_chat) {
|
||||
Friends.list[self->num].logging_on = true;
|
||||
log_enable(self->name, Friends.list[self->num].pub_key, log);
|
||||
log_enable(self->name, myid, Friends.list[self->num].pub_key, log, LOG_CHAT);
|
||||
} else if (self->is_prompt) {
|
||||
char myid[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(m, (uint8_t *) myid);
|
||||
log_enable(self->name, myid, log);
|
||||
log_enable(self->name, myid, NULL, log, LOG_PROMPT);
|
||||
} else if (self->is_groupchat) {
|
||||
log_enable(self->name, NULL, log);
|
||||
log_enable(self->name, myid, NULL, log, LOG_GROUP);
|
||||
}
|
||||
|
||||
msg = "Logging enabled";
|
||||
@ -399,7 +474,7 @@ void cmd_quit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
|
||||
|
||||
void cmd_requests(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||
{
|
||||
if (FriendRequests.num_requests == 0) {
|
||||
if (FrndRequests.num_requests == 0) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No pending friend requests.");
|
||||
return;
|
||||
}
|
||||
@ -407,22 +482,22 @@ void cmd_requests(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
||||
int i, j;
|
||||
int count = 0;
|
||||
|
||||
for (i = 0; i < FriendRequests.max_idx; ++i) {
|
||||
if (!FriendRequests.request[i].active)
|
||||
for (i = 0; i < FrndRequests.max_idx; ++i) {
|
||||
if (!FrndRequests.request[i].active)
|
||||
continue;
|
||||
|
||||
char id[TOX_CLIENT_ID_SIZE * 2 + 1] = {0};
|
||||
|
||||
for (j = 0; j < TOX_CLIENT_ID_SIZE; ++j) {
|
||||
char d[3];
|
||||
snprintf(d, sizeof(d), "%02X", FriendRequests.request[i].key[j] & 0xff);
|
||||
snprintf(d, sizeof(d), "%02X", FrndRequests.request[i].key[j] & 0xff);
|
||||
strcat(id, d);
|
||||
}
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%d : %s", i, id);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", FriendRequests.request[i].msg);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", FrndRequests.request[i].msg);
|
||||
|
||||
if (++count < FriendRequests.num_requests)
|
||||
if (++count < FrndRequests.num_requests)
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "");
|
||||
}
|
||||
}
|
||||
|
@ -20,14 +20,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _global_commands_h
|
||||
#define _global_commands_h
|
||||
#ifndef GLOBAL_COMMANDS_H
|
||||
#define GLOBAL_COMMANDS_H
|
||||
|
||||
#include "windows.h"
|
||||
#include "toxic.h"
|
||||
|
||||
void cmd_accept(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
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_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]);
|
||||
@ -43,9 +44,9 @@ void cmd_status(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZ
|
||||
|
||||
void cmd_add_helper(ToxWindow *self, Tox *m, char *id_bin, char *msg);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
void cmd_list_devices(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
void cmd_change_device(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#endif /* #define _global_commands_h */
|
||||
#endif /* #define GLOBAL_COMMANDS_H */
|
||||
|
@ -50,7 +50,7 @@ extern char *DATA_FILE;
|
||||
static GroupChat groupchats[MAX_GROUPCHAT_NUM];
|
||||
static int max_groupchat_index = 0;
|
||||
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
/* temporary until group chats have unique commands */
|
||||
extern const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE];
|
||||
@ -67,11 +67,16 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum)
|
||||
groupchats[i].chatwin = add_window(m, new_group_chat(m, groupnum));
|
||||
groupchats[i].active = true;
|
||||
groupchats[i].num_peers = 0;
|
||||
|
||||
groupchats[i].peer_names = malloc(sizeof(uint8_t) * TOX_MAX_NAME_LENGTH);
|
||||
groupchats[i].oldpeer_names = malloc(sizeof(uint8_t) * TOX_MAX_NAME_LENGTH);
|
||||
groupchats[i].peer_name_lengths = malloc(sizeof(uint16_t));
|
||||
groupchats[i].oldpeer_name_lengths = malloc(sizeof(uint16_t));
|
||||
|
||||
if (groupchats[i].peer_names == NULL || groupchats[i].oldpeer_names == NULL
|
||||
|| groupchats[i].peer_name_lengths == NULL || groupchats[i].oldpeer_name_lengths == NULL)
|
||||
exit_toxic_err("failed in init_groupchat_win", FATALERR_MEMORY);
|
||||
|
||||
memcpy(&groupchats[i].oldpeer_names[0], UNKNOWN_NAME, sizeof(UNKNOWN_NAME));
|
||||
groupchats[i].oldpeer_name_lengths[0] = (uint16_t) strlen(UNKNOWN_NAME);
|
||||
|
||||
@ -302,7 +307,7 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
|
||||
|
||||
case TOX_CHAT_CHANGE_PEER_DEL:
|
||||
event = "has left the room";
|
||||
line_info_add(self, timefrmt, (char *) oldpeername, NULL, CONNECTION, 0, 0, event);
|
||||
line_info_add(self, timefrmt, (char *) oldpeername, NULL, CONNECTION, 0, RED, event);
|
||||
|
||||
if (groupchats[self->num].side_pos > 0)
|
||||
--groupchats[self->num].side_pos;
|
||||
@ -367,11 +372,15 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
if (ctx->len > 0) {
|
||||
int diff;
|
||||
|
||||
if ((ctx->line[0] != '/') || (ctx->line[1] == 'm' && ctx->line[2] == 'e'))
|
||||
diff = complete_line(self, groupchats[self->num].peer_names,
|
||||
groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH);
|
||||
else
|
||||
/* TODO: make this not suck */
|
||||
if (ctx->line[0] != L'/' || wcscmp(ctx->line, L"/me") == 0) {
|
||||
diff = complete_line(self, groupchats[self->num].peer_names, groupchats[self->num].num_peers,
|
||||
TOX_MAX_NAME_LENGTH);
|
||||
} else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) {
|
||||
diff = dir_match(self, m, ctx->line, L"/avatar");
|
||||
} else {
|
||||
diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);
|
||||
}
|
||||
|
||||
if (diff != -1) {
|
||||
if (x + diff > x2 - 1) {
|
||||
@ -384,12 +393,12 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
} else {
|
||||
sound_notify(self, error, 0, NULL);
|
||||
}
|
||||
} else if (key == user_settings_->key_peer_list_down) { /* Scroll peerlist up and down one position */
|
||||
} else if (key == user_settings->key_peer_list_down) { /* Scroll peerlist up and down one position */
|
||||
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
|
||||
|
||||
if (groupchats[self->num].side_pos < groupchats[self->num].num_peers - L)
|
||||
++groupchats[self->num].side_pos;
|
||||
} else if (key == user_settings_->key_peer_list_up) {
|
||||
} else if (key == user_settings->key_peer_list_up) {
|
||||
if (groupchats[self->num].side_pos > 0)
|
||||
--groupchats[self->num].side_pos;
|
||||
} else if (key == '\n') {
|
||||
@ -503,8 +512,11 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
|
||||
|
||||
line_info_init(ctx->hst);
|
||||
|
||||
if (user_settings_->autolog == AUTOLOG_ON)
|
||||
log_enable(self->name, NULL, ctx->log);
|
||||
if (user_settings->autolog == AUTOLOG_ON) {
|
||||
char myid[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(m, (uint8_t *) myid);
|
||||
log_enable(self->name, myid, NULL, ctx->log, LOG_GROUP);
|
||||
}
|
||||
|
||||
execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE);
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _groupchat_h
|
||||
#define _groupchat_h
|
||||
#ifndef GROUPCHAT_H
|
||||
#define GROUPCHAT_H
|
||||
|
||||
#include "toxic.h"
|
||||
#include "windows.h"
|
||||
@ -45,4 +45,4 @@ void kill_groupchat_window(ToxWindow *self);
|
||||
int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum);
|
||||
ToxWindow new_group_chat(Tox *m, int groupnum);
|
||||
|
||||
#endif /* #define _groupchat_h */
|
||||
#endif /* #define GROUPCHAT_H */
|
||||
|
17
src/help.c
17
src/help.c
@ -138,6 +138,7 @@ 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 a personal avatar\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");
|
||||
@ -151,14 +152,14 @@ static void help_draw_global(ToxWindow *self)
|
||||
wprintw(win, " /close : Close the current chat window\n");
|
||||
wprintw(win, " /quit or /exit : Exit Toxic\n");
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
wattron(win, A_BOLD);
|
||||
wprintw(win, "\n Audio:\n");
|
||||
wattroff(win, A_BOLD);
|
||||
|
||||
wprintw(win, " /lsdev <type> : List devices where type: in|out\n");
|
||||
wprintw(win, " /sdev <type> <id> : Set active device\n");
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
help_draw_bottom_menu(win);
|
||||
|
||||
@ -182,7 +183,7 @@ static void help_draw_chat(ToxWindow *self)
|
||||
wprintw(win, " /savefile <id> : Receive a file\n");
|
||||
wprintw(win, " /cancel <type> <id> : Cancel file transfer where type: in|out\n");
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
wattron(win, A_BOLD);
|
||||
wprintw(win, "\n Audio:\n");
|
||||
wattroff(win, A_BOLD);
|
||||
@ -194,7 +195,7 @@ static void help_draw_chat(ToxWindow *self)
|
||||
wprintw(win, " /sdev <type> <id> : Change active device\n");
|
||||
wprintw(win, " /mute <type> : Mute active device if in call\n");
|
||||
wprintw(win, " /sense <n> : VAD sensitivity treshold\n");
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
help_draw_bottom_menu(win);
|
||||
|
||||
@ -256,7 +257,7 @@ void help_onKey(ToxWindow *self, wint_t key)
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
help_init_window(self, 19, 80);
|
||||
#else
|
||||
help_init_window(self, 9, 80);
|
||||
@ -265,10 +266,10 @@ void help_onKey(ToxWindow *self, wint_t key)
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
#ifdef _AUDIO
|
||||
help_init_window(self, 23, 80);
|
||||
#ifdef AUDIO
|
||||
help_init_window(self, 24, 80);
|
||||
#else
|
||||
help_init_window(self, 19, 80);
|
||||
help_init_window(self, 20, 80);
|
||||
#endif
|
||||
self->help->type = HELP_GLOBAL;
|
||||
break;
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _help_h
|
||||
#define _help_h
|
||||
#ifndef HELP_H
|
||||
#define HELP_H
|
||||
|
||||
#include "toxic.h"
|
||||
#include "windows.h"
|
||||
@ -39,4 +39,4 @@ void help_onDraw(ToxWindow *self);
|
||||
void help_init_menu(ToxWindow *self);
|
||||
void help_onKey(ToxWindow *self, wint_t key);
|
||||
|
||||
#endif /* #define _help_h */
|
||||
#endif /* #define HELP_H */
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _input_h
|
||||
#define _input_h
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
/* add a char to input field and buffer for given chatcontext */
|
||||
void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y);
|
||||
@ -30,4 +30,4 @@ void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_
|
||||
return true if key matches a function, false otherwise */
|
||||
bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y);
|
||||
|
||||
#endif /* #define _input_h */
|
||||
#endif /* #define INPUT_H */
|
@ -34,7 +34,7 @@
|
||||
#include "message_queue.h"
|
||||
#include "misc_tools.h"
|
||||
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
void line_info_init(struct history *hst)
|
||||
{
|
||||
@ -48,8 +48,8 @@ void line_info_init(struct history *hst)
|
||||
hst->queue_sz = 0;
|
||||
}
|
||||
|
||||
/* resets line_start (page end) */
|
||||
static void line_info_reset_start(ToxWindow *self, struct history *hst)
|
||||
/* resets line_start (moves to end of chat history) */
|
||||
void line_info_reset_start(ToxWindow *self, struct history *hst)
|
||||
{
|
||||
struct line_info *line = hst->line_end;
|
||||
|
||||
@ -111,13 +111,13 @@ static void line_info_root_fwd(struct history *hst)
|
||||
hst->line_root = tmp;
|
||||
}
|
||||
|
||||
/* returns ptr to queue item 0 and removes it from queue */
|
||||
/* returns ptr to queue item 0 and removes it from queue. Returns NULL if queue is empty. */
|
||||
static struct line_info *line_info_ret_queue(struct history *hst)
|
||||
{
|
||||
if (hst->queue_sz <= 0)
|
||||
return NULL;
|
||||
|
||||
struct line_info *ret = hst->queue[0];
|
||||
struct line_info *line = hst->queue[0];
|
||||
|
||||
int i;
|
||||
|
||||
@ -126,7 +126,7 @@ static struct line_info *line_info_ret_queue(struct history *hst)
|
||||
|
||||
--hst->queue_sz;
|
||||
|
||||
return ret;
|
||||
return line;
|
||||
}
|
||||
|
||||
/* creates new line_info line and puts it in the queue. */
|
||||
@ -135,7 +135,7 @@ void line_info_add(ToxWindow *self, char *timestr, char *name1, char *name2, uin
|
||||
{
|
||||
struct history *hst = self->chatwin->hst;
|
||||
|
||||
if (hst->queue_sz >= MAX_QUEUE)
|
||||
if (hst->queue_sz >= MAX_LINE_INFO_QUEUE)
|
||||
return;
|
||||
|
||||
struct line_info *new_line = calloc(1, sizeof(struct line_info));
|
||||
@ -143,7 +143,7 @@ void line_info_add(ToxWindow *self, char *timestr, char *name1, char *name2, uin
|
||||
if (new_line == NULL)
|
||||
exit_toxic_err("failed in line_info_add", FATALERR_MEMORY);
|
||||
|
||||
char frmt_msg[MAX_STR_SIZE] = {0};
|
||||
char frmt_msg[MAX_LINE_INFO_MSG_SIZE] = {0};
|
||||
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
@ -156,21 +156,25 @@ void line_info_add(ToxWindow *self, char *timestr, char *name1, char *name2, uin
|
||||
switch (type) {
|
||||
case IN_ACTION:
|
||||
case OUT_ACTION:
|
||||
len += 3;
|
||||
len += 5;
|
||||
break;
|
||||
|
||||
case IN_MSG:
|
||||
case OUT_MSG:
|
||||
len += 2;
|
||||
len += 6;
|
||||
break;
|
||||
|
||||
case CONNECTION:
|
||||
len += 3;
|
||||
len += 5;
|
||||
break;
|
||||
|
||||
case SYS_MSG:
|
||||
break;
|
||||
|
||||
case NAME_CHANGE:
|
||||
len += 4;
|
||||
break;
|
||||
|
||||
case PROMPT:
|
||||
++len;
|
||||
break;
|
||||
@ -226,7 +230,7 @@ static void line_info_check_queue(ToxWindow *self)
|
||||
if (line == NULL)
|
||||
return;
|
||||
|
||||
if (hst->start_id > user_settings_->history_size)
|
||||
if (hst->start_id > user_settings->history_size)
|
||||
line_info_root_fwd(hst);
|
||||
|
||||
line->id = hst->line_end->id + 1;
|
||||
@ -254,6 +258,10 @@ static void line_info_check_queue(ToxWindow *self)
|
||||
++hst->start_id;
|
||||
}
|
||||
}
|
||||
|
||||
/* force move to bottom of history when we print an outgoing message */
|
||||
if (line->type == OUT_MSG)
|
||||
line_info_reset_start(self, hst);
|
||||
}
|
||||
|
||||
#define NOREAD_FLAG_TIMEOUT 5 /* seconds before a sent message with no read receipt is flagged as unread */
|
||||
@ -305,7 +313,7 @@ void line_info_print(ToxWindow *self)
|
||||
nameclr = CYAN;
|
||||
|
||||
wattron(win, COLOR_PAIR(nameclr));
|
||||
wprintw(win, "%s: ", line->name1);
|
||||
wprintw(win, "--- %s: ", line->name1);
|
||||
wattroff(win, COLOR_PAIR(nameclr));
|
||||
|
||||
if (line->msg[0] == '>')
|
||||
@ -338,7 +346,7 @@ void line_info_print(ToxWindow *self)
|
||||
wattroff(win, COLOR_PAIR(BLUE));
|
||||
|
||||
wattron(win, COLOR_PAIR(YELLOW));
|
||||
wprintw(win, "* %s %s", line->name1, line->msg);
|
||||
wprintw(win, "-*- %s %s", line->name1, line->msg);
|
||||
wattroff(win, COLOR_PAIR(YELLOW));
|
||||
|
||||
if (type == OUT_ACTION && timed_out(line->timestamp, get_unix_time(), NOREAD_FLAG_TIMEOUT)) {
|
||||
@ -395,9 +403,12 @@ void line_info_print(ToxWindow *self)
|
||||
wattroff(win, COLOR_PAIR(BLUE));
|
||||
|
||||
wattron(win, COLOR_PAIR(line->colour));
|
||||
wprintw(win, "%s ", line->colour == RED ? "<--" : "-->");
|
||||
|
||||
wattron(win, A_BOLD);
|
||||
wprintw(win, "* %s ", line->name1);
|
||||
wprintw(win, "%s ", line->name1);
|
||||
wattroff(win, A_BOLD);
|
||||
|
||||
wprintw(win, "%s\n", line->msg);
|
||||
wattroff(win, COLOR_PAIR(line->colour));
|
||||
|
||||
@ -409,8 +420,9 @@ void line_info_print(ToxWindow *self)
|
||||
wattroff(win, COLOR_PAIR(BLUE));
|
||||
|
||||
wattron(win, COLOR_PAIR(MAGENTA));
|
||||
wprintw(win, "-!- ");
|
||||
wattron(win, A_BOLD);
|
||||
wprintw(win, "* %s", line->name1);
|
||||
wprintw(win, "%s", line->name1);
|
||||
wattroff(win, A_BOLD);
|
||||
|
||||
wprintw(win, "%s", line->msg);
|
||||
@ -494,19 +506,19 @@ bool line_info_onKey(ToxWindow *self, wint_t key)
|
||||
struct history *hst = self->chatwin->hst;
|
||||
bool match = true;
|
||||
|
||||
if (key == user_settings_->key_half_page_up) {
|
||||
if (key == user_settings->key_half_page_up) {
|
||||
line_info_page_up(self, hst);
|
||||
}
|
||||
else if (key == user_settings_->key_half_page_down) {
|
||||
else if (key == user_settings->key_half_page_down) {
|
||||
line_info_page_down(self, hst);
|
||||
}
|
||||
else if (key == user_settings_->key_scroll_line_up) {
|
||||
else if (key == user_settings->key_scroll_line_up) {
|
||||
line_info_scroll_up(hst);
|
||||
}
|
||||
else if (key == user_settings_->key_scroll_line_down) {
|
||||
else if (key == user_settings->key_scroll_line_down) {
|
||||
line_info_scroll_down(hst);
|
||||
}
|
||||
else if (key == user_settings_->key_page_bottom) {
|
||||
else if (key == user_settings->key_page_bottom) {
|
||||
line_info_reset_start(self, hst);
|
||||
}
|
||||
else {
|
||||
|
@ -20,15 +20,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _line_info_h
|
||||
#define _line_info_h
|
||||
#ifndef LINE_INFO_H
|
||||
#define LINE_INFO_H
|
||||
|
||||
#include "windows.h"
|
||||
#include "toxic.h"
|
||||
|
||||
#define MAX_HISTORY 100000
|
||||
#define MIN_HISTORY 40
|
||||
#define MAX_QUEUE 128
|
||||
#define MAX_LINE_INFO_QUEUE 1024
|
||||
#define MAX_LINE_INFO_MSG_SIZE MAX_STR_SIZE + TOXIC_MAX_NAME_LENGTH + 32 /* needs extra room for log loading */
|
||||
|
||||
enum {
|
||||
SYS_MSG,
|
||||
@ -47,7 +48,7 @@ struct line_info {
|
||||
char timestr[TIME_STR_SIZE];
|
||||
char name1[TOXIC_MAX_NAME_LENGTH];
|
||||
char name2[TOXIC_MAX_NAME_LENGTH];
|
||||
char msg[TOX_MAX_MESSAGE_LENGTH];
|
||||
char msg[MAX_LINE_INFO_MSG_SIZE];
|
||||
uint64_t timestamp;
|
||||
uint8_t type;
|
||||
uint8_t bold;
|
||||
@ -68,7 +69,7 @@ struct history {
|
||||
struct line_info *line_end;
|
||||
uint32_t start_id; /* keeps track of where line_start should be when at bottom of history */
|
||||
|
||||
struct line_info *queue[MAX_QUEUE];
|
||||
struct line_info *queue[MAX_LINE_INFO_QUEUE];
|
||||
int queue_sz;
|
||||
};
|
||||
|
||||
@ -88,7 +89,10 @@ void line_info_clear(struct history *hst);
|
||||
/* puts msg in specified line_info msg buffer */
|
||||
void line_info_set(ToxWindow *self, uint32_t id, char *msg);
|
||||
|
||||
/* resets line_start (moves to end of chat history) */
|
||||
void line_info_reset_start(ToxWindow *self, struct history *hst);
|
||||
|
||||
void line_info_init(struct history *hst);
|
||||
bool line_info_onKey(ToxWindow *self, wint_t key); /* returns true if key is a match */
|
||||
|
||||
#endif /* #define _line_info_h */
|
||||
#endif /* #define LINE_INFO_H */
|
||||
|
214
src/log.c
214
src/log.c
@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "configdir.h"
|
||||
#include "toxic.h"
|
||||
@ -30,60 +31,88 @@
|
||||
#include "misc_tools.h"
|
||||
#include "log.h"
|
||||
#include "settings.h"
|
||||
#include "line_info.h"
|
||||
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
/* Creates/fetches log file by appending to the config dir the name and a pseudo-unique identity */
|
||||
void init_logging_session(char *name, const char *key, struct chatlog *log)
|
||||
/* There are three types of logs: chat logs, groupchat logs, and prompt logs (see LOG_TYPE in log.h)
|
||||
A prompt log is in the format: LOGDIR/selfkey-home.log
|
||||
A chat log is in the format: LOGDIR/selfkey-friendname-otherkey.log
|
||||
A groupchat log is in the format: LOGDIR/selfkey-groupname-date[time].log
|
||||
|
||||
Only the first (KEY_IDENT_DIGITS * 2) numbers of the key are used.
|
||||
|
||||
Returns 0 on success, -1 if the path is too long */
|
||||
static int get_log_path(char *dest, int destsize, char *name, const char *selfkey, const char *otherkey, int logtype)
|
||||
{
|
||||
if (!log->log_on)
|
||||
return;
|
||||
|
||||
if (!valid_nick(name))
|
||||
name = UNKNOWN_NAME;
|
||||
|
||||
const char *set_path = user_settings_->chatlogs_path;
|
||||
const char *namedash = logtype == LOG_PROMPT ? "" : "-";
|
||||
const char *set_path = user_settings->chatlogs_path;
|
||||
|
||||
char *user_config_dir = get_user_config_dir();
|
||||
int path_len = strlen(set_path) + strlen(name) ? *set_path
|
||||
: strlen(user_config_dir) + strlen(LOGDIR) + strlen(name);
|
||||
int path_len = strlen(name) + strlen(".log") + strlen("-") + strlen(namedash);
|
||||
path_len += strlen(set_path) ? *set_path : strlen(user_config_dir) + strlen(LOGDIR);
|
||||
|
||||
/* use first 4 digits of key as log ident. If no key use a timestamp */
|
||||
char ident[32];
|
||||
/* first 6 digits of selfkey */
|
||||
char self_id[32];
|
||||
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_DIGITS * 2] = '\0';
|
||||
|
||||
if (key != NULL) {
|
||||
path_len += (KEY_IDENT_DIGITS * 2 + 5);
|
||||
sprintf(&ident[0], "%02X", key[0] & 0xff);
|
||||
sprintf(&ident[2], "%02X", key[1] & 0xff);
|
||||
ident[KEY_IDENT_DIGITS * 2 + 1] = '\0';
|
||||
} else {
|
||||
strftime(ident, sizeof(ident), "%Y-%m-%d[%H:%M:%S]", get_time());
|
||||
path_len += strlen(ident) + 1;
|
||||
char other_id[32] = {0};
|
||||
|
||||
switch (logtype) {
|
||||
case LOG_CHAT:
|
||||
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_DIGITS * 2] = '\0';
|
||||
break;
|
||||
|
||||
case LOG_GROUP:
|
||||
strftime(other_id, sizeof(other_id), "%Y-%m-%d[%H:%M:%S]", get_time());
|
||||
path_len += strlen(other_id);
|
||||
break;
|
||||
}
|
||||
|
||||
if (path_len >= MAX_STR_SIZE) {
|
||||
log->log_on = false;
|
||||
if (path_len >= destsize) {
|
||||
free(user_config_dir);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!string_is_empty(set_path))
|
||||
snprintf(dest, destsize, "%s%s-%s%s%s.log", set_path, self_id, name, namedash, other_id);
|
||||
else
|
||||
snprintf(dest, destsize, "%s%s%s-%s%s%s.log", user_config_dir, LOGDIR, self_id, name, namedash, other_id);
|
||||
|
||||
free(user_config_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Opens log file or creates a new one */
|
||||
static int init_logging_session(char *name, const char *selfkey, const char *otherkey, struct chatlog *log, int logtype)
|
||||
{
|
||||
if (selfkey == NULL || (logtype == LOG_CHAT && otherkey == NULL))
|
||||
return -1;
|
||||
|
||||
char log_path[MAX_STR_SIZE];
|
||||
|
||||
if (*set_path)
|
||||
snprintf(log_path, sizeof(log_path), "%s%s-%s.log", set_path, name, ident);
|
||||
else
|
||||
snprintf(log_path, sizeof(log_path), "%s%s%s-%s.log", user_config_dir, LOGDIR, name, ident);
|
||||
if (get_log_path(log_path, sizeof(log_path), name, selfkey, otherkey, logtype) == -1)
|
||||
return -1;
|
||||
|
||||
free(user_config_dir);
|
||||
log->file = fopen(log_path, "a+");
|
||||
snprintf(log->path, sizeof(log->path), "%s", log_path);
|
||||
|
||||
log->file = fopen(log_path, "a");
|
||||
if (log->file == NULL)
|
||||
return -1;
|
||||
|
||||
if (log->file == NULL) {
|
||||
log->log_on = false;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(log->file, "\n*** NEW SESSION ***\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LOG_FLUSH_LIMIT 1 /* limits calls to fflush to a max of one per LOG_FLUSH_LIMIT seconds */
|
||||
@ -105,7 +134,7 @@ void write_to_log(const char *msg, const char *name, struct chatlog *log, bool e
|
||||
else
|
||||
snprintf(name_frmt, sizeof(name_frmt), "%s:", name);
|
||||
|
||||
const char *t = user_settings_->time == TIME_12 ? "%Y/%m/%d [%I:%M:%S %p]" : "%Y/%m/%d [%H:%M:%S]";
|
||||
const char *t = user_settings->time == TIME_12 ? "%Y/%m/%d [%I:%M:%S %p]" : "%Y/%m/%d [%H:%M:%S]";
|
||||
char s[MAX_STR_SIZE];
|
||||
strftime(s, MAX_STR_SIZE, t, get_time());
|
||||
fprintf(log->file, "%s %s %s\n", s, name_frmt, msg);
|
||||
@ -118,20 +147,119 @@ void write_to_log(const char *msg, const char *name, struct chatlog *log, bool e
|
||||
}
|
||||
}
|
||||
|
||||
void log_enable(char *name, const char *key, struct chatlog *log)
|
||||
void log_disable(struct chatlog *log)
|
||||
{
|
||||
if (log->file != NULL)
|
||||
fclose(log->file);
|
||||
|
||||
memset(log, 0, sizeof(struct chatlog));
|
||||
}
|
||||
|
||||
void log_enable(char *name, const char *selfkey, const char *otherkey, struct chatlog *log, int logtype)
|
||||
{
|
||||
log->log_on = true;
|
||||
|
||||
if (log->file == NULL)
|
||||
init_logging_session(name, key, log);
|
||||
if (log->file != NULL)
|
||||
return;
|
||||
|
||||
if (init_logging_session(name, selfkey, otherkey, log, logtype) == -1)
|
||||
log_disable(log);
|
||||
}
|
||||
|
||||
void log_disable(struct chatlog *log)
|
||||
/* Loads previous history from chat log */
|
||||
void load_chat_history(ToxWindow *self, struct chatlog *log)
|
||||
{
|
||||
log->log_on = false;
|
||||
if (log->file == NULL)
|
||||
return;
|
||||
|
||||
if (log->file != NULL) {
|
||||
fclose(log->file);
|
||||
log->file = NULL;
|
||||
off_t sz = file_size(log->path);
|
||||
|
||||
if (sz <= 0)
|
||||
return;
|
||||
|
||||
char *hstbuf = malloc(sz);
|
||||
|
||||
if (hstbuf == NULL)
|
||||
exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY);
|
||||
|
||||
if (fseek(log->file, 0L, SEEK_SET) == -1) {
|
||||
free(hstbuf);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to read log file");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fread(hstbuf, sz, 1, log->file) != 1) {
|
||||
free(hstbuf);
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to read log file");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Number of history lines to load: must not be larger than MAX_LINE_INFO_QUEUE - 2 */
|
||||
int L = MIN(MAX_LINE_INFO_QUEUE - 2, user_settings->history_size);
|
||||
int start, count = 0;
|
||||
|
||||
/* start at end and backtrace L lines or to the beginning of buffer */
|
||||
for (start = sz - 1; start >= 0 && count < L; --start) {
|
||||
if (hstbuf[start] == '\n')
|
||||
++count;
|
||||
}
|
||||
|
||||
const char *line = strtok(&hstbuf[start + 1], "\n");
|
||||
|
||||
if (line == NULL) {
|
||||
free(hstbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
while (line != NULL && count--) {
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", line);
|
||||
line = strtok(NULL, "\n");
|
||||
}
|
||||
|
||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "");
|
||||
free(hstbuf);
|
||||
}
|
||||
|
||||
/* renames chatlog file replacing src with dest.
|
||||
Returns 0 on success or if no log exists, -1 on failure. */
|
||||
int rename_logfile(char *src, char *dest, const char *selfkey, const char *otherkey, int winnum)
|
||||
{
|
||||
ToxWindow *toxwin = get_window_ptr(winnum);
|
||||
struct chatlog *log = NULL;
|
||||
bool log_on = false;
|
||||
|
||||
/* disable log if necessary and save its state */
|
||||
if (toxwin != NULL) {
|
||||
log = toxwin->chatwin->log;
|
||||
log_on = log->log_on;
|
||||
}
|
||||
|
||||
if (log_on)
|
||||
log_disable(log);
|
||||
|
||||
char newpath[MAX_STR_SIZE];
|
||||
char oldpath[MAX_STR_SIZE];
|
||||
|
||||
if (get_log_path(oldpath, sizeof(oldpath), src, selfkey, otherkey, LOG_CHAT) == -1)
|
||||
goto on_error;
|
||||
|
||||
if (!file_exists(oldpath))
|
||||
return 0;
|
||||
|
||||
if (get_log_path(newpath, sizeof(newpath), dest, selfkey, otherkey, LOG_CHAT) == -1)
|
||||
goto on_error;
|
||||
|
||||
if (rename(oldpath, newpath) != 0)
|
||||
goto on_error;
|
||||
|
||||
if (log_on)
|
||||
log_enable(dest, selfkey, otherkey, log, LOG_CHAT);
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
if (log_on)
|
||||
log_enable(src, selfkey, otherkey, log, LOG_CHAT);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
23
src/log.h
23
src/log.h
@ -20,25 +20,36 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _log_h
|
||||
#define _log_h
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
struct chatlog {
|
||||
FILE *file;
|
||||
uint64_t lastwrite;
|
||||
char path[MAX_STR_SIZE];
|
||||
bool log_on; /* specific to current chat window */
|
||||
};
|
||||
|
||||
/* Creates/fetches log file by appending to the config dir the name and a pseudo-unique identity */
|
||||
void init_logging_session(char *name, const char *key, struct chatlog *log);
|
||||
enum {
|
||||
LOG_GROUP,
|
||||
LOG_PROMPT,
|
||||
LOG_CHAT,
|
||||
} LOG_TYPE;
|
||||
|
||||
/* formats/writes line to log file */
|
||||
void write_to_log(const char *msg, const char *name, struct chatlog *log, bool event);
|
||||
|
||||
/* enables logging for specified log and creates/fetches file if necessary */
|
||||
void log_enable(char *name, const char *key, struct chatlog *log);
|
||||
void log_enable(char *name, const char *selfkey, const char *otherkey, struct chatlog *log, int logtype);
|
||||
|
||||
/* disables logging for specified log and closes file */
|
||||
void log_disable(struct chatlog *log);
|
||||
|
||||
#endif /* #define _log_h */
|
||||
/* Loads previous history from chat log */
|
||||
void load_chat_history(ToxWindow *self, struct chatlog *log);
|
||||
|
||||
/* renames chatlog file replacing src with dest.
|
||||
Returns 0 on success or if no log exists, -1 on failure. */
|
||||
int rename_logfile(char *src, char *dest, const char *selfkey, const char *otherkey, int winnum);
|
||||
|
||||
#endif /* #define LOG_H */
|
||||
|
@ -20,6 +20,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MESSAGE_QUEUE_H
|
||||
#define MESSAGE_QUEUE_H
|
||||
|
||||
struct cqueue_msg {
|
||||
char message[MAX_STR_SIZE];
|
||||
int len;
|
||||
@ -44,3 +47,5 @@ void cqueue_try_send(ToxWindow *self, Tox *m);
|
||||
|
||||
/* removes message with matching receipt from queue, writes to log and updates line to show the message was received. */
|
||||
void cqueue_remove(ToxWindow *self, Tox *m, uint32_t receipt);
|
||||
|
||||
#endif /* #define MESSAGE_QUEUE_H */
|
@ -35,7 +35,7 @@
|
||||
#include "file_senders.h"
|
||||
|
||||
extern ToxWindow *prompt;
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
static uint64_t current_unix_time;
|
||||
|
||||
@ -82,12 +82,12 @@ struct tm *get_time(void)
|
||||
/*Puts the current time in buf in the format of [HH:mm:ss] */
|
||||
void get_time_str(char *buf, int bufsize)
|
||||
{
|
||||
if (user_settings_->timestamps == TIMESTAMPS_OFF) {
|
||||
if (user_settings->timestamps == TIMESTAMPS_OFF) {
|
||||
buf[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
const char *t = user_settings_->time == TIME_12 ? "[%-I:%M:%S] " : "[%H:%M:%S] ";
|
||||
const char *t = user_settings->time == TIME_12 ? "%I:%M:%S " : "%H:%M:%S ";
|
||||
strftime(buf, bufsize, t, get_time());
|
||||
}
|
||||
|
||||
@ -311,3 +311,33 @@ bool file_exists(const char *path)
|
||||
struct stat s;
|
||||
return stat(path, &s) == 0;
|
||||
}
|
||||
|
||||
/* returns file size or -1 on error */
|
||||
off_t file_size(const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (stat(path, &st) == -1)
|
||||
return -1;
|
||||
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
/* compares the first size bytes of fp to signature.
|
||||
Returns 0 if they are the same, 1 if they differ, and -1 on error.
|
||||
|
||||
On success this function will seek back to the beginning of fp */
|
||||
int check_file_signature(const char *signature, size_t size, FILE *fp)
|
||||
{
|
||||
char buf[size];
|
||||
|
||||
if (fread(buf, size, 1, fp) != 1)
|
||||
return -1;
|
||||
|
||||
int ret = memcmp(signature, buf, size);
|
||||
|
||||
if (fseek(fp, 0L, SEEK_SET) == -1)
|
||||
return -1;
|
||||
|
||||
return ret == 0 ? 0 : 1;
|
||||
}
|
||||
|
@ -19,8 +19,10 @@
|
||||
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifndef _misc_tools_h
|
||||
#define _misc_tools_h
|
||||
#ifndef MISC_TOOLS_H
|
||||
#define MISC_TOOLS_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "windows.h"
|
||||
#include "toxic.h"
|
||||
@ -112,4 +114,13 @@ void bytes_convert_str(char *buf, int size, uint64_t bytes);
|
||||
/* checks if a file exists. Returns true or false */
|
||||
bool file_exists(const char *path);
|
||||
|
||||
#endif /* #define _misc_tools_h */
|
||||
/* returns file size or -1 on error */
|
||||
off_t file_size(const char *path);
|
||||
|
||||
/* compares the first size bytes of fp and signature.
|
||||
Returns 0 if they are the same, 1 if they differ, and -1 on error.
|
||||
|
||||
On success this function will seek back to the beginning of fp */
|
||||
int check_file_signature(const char *signature, size_t size, FILE *fp);
|
||||
|
||||
#endif /* #define MISC_TOOLS_H */
|
||||
|
166
src/notify.c
166
src/notify.c
@ -20,12 +20,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "notify.h"
|
||||
#include "device.h"
|
||||
#include "settings.h"
|
||||
#include "line_info.h"
|
||||
#include "misc_tools.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -36,7 +30,13 @@
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_AUDIO) || defined(_SOUND_NOTIFY)
|
||||
#include "notify.h"
|
||||
#include "device.h"
|
||||
#include "settings.h"
|
||||
#include "line_info.h"
|
||||
#include "misc_tools.h"
|
||||
|
||||
#if defined(AUDIO) || defined(SOUND_NOTIFY)
|
||||
#ifdef __APPLE__
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
@ -48,16 +48,16 @@
|
||||
#include <AL/alext.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
#include <AL/alut.h> /* freealut packet */
|
||||
#endif
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#ifdef _X11
|
||||
#ifdef X11
|
||||
#include <X11/Xlib.h>
|
||||
#endif /* _X11 */
|
||||
#endif /* X11 */
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
#include <libnotify/notify.h>
|
||||
#endif
|
||||
|
||||
@ -65,36 +65,36 @@
|
||||
#define SOUNDS_SIZE 10
|
||||
#define ACTIVE_NOTIFS_MAX 50
|
||||
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
struct _Control {
|
||||
struct Control {
|
||||
time_t cooldown;
|
||||
time_t notif_timeout;
|
||||
#ifdef _X11
|
||||
#ifdef X11
|
||||
Display *display;
|
||||
unsigned long this_window;
|
||||
#endif /* _X11 */
|
||||
#endif /* X11 */
|
||||
|
||||
#if defined(_SOUND_NOTIFY) || defined(_BOX_NOTIFY)
|
||||
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
|
||||
pthread_mutex_t poll_mutex[1];
|
||||
bool poll_active;
|
||||
#endif
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
uint32_t device_idx; /* index of output device */
|
||||
char* sounds[SOUNDS_SIZE];
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
} Control = {0};
|
||||
|
||||
struct _ActiveNotifications {
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
uint32_t source;
|
||||
uint32_t buffer;
|
||||
bool looping;
|
||||
#endif
|
||||
bool active;
|
||||
int *id_indicator;
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
NotifyNotification* box;
|
||||
char messages[MAX_BOX_MSG_LEN + 1][MAX_BOX_MSG_LEN + 1];
|
||||
char title[24];
|
||||
@ -122,7 +122,7 @@ static void tab_notify(ToxWindow *self, uint64_t flags)
|
||||
self->alert = WINDOW_ALERT_2;
|
||||
}
|
||||
|
||||
#ifdef _X11
|
||||
#ifdef X11
|
||||
long unsigned int get_focused_window_id()
|
||||
{
|
||||
if (!Control.display) return 0;
|
||||
@ -132,12 +132,12 @@ long unsigned int get_focused_window_id()
|
||||
XGetInputFocus(Control.display, &focus, &revert);
|
||||
return focus;
|
||||
}
|
||||
#endif /* _X11 */
|
||||
#endif /* X11 */
|
||||
|
||||
static bool notifications_are_disabled(uint64_t flags)
|
||||
{
|
||||
bool res = flags & NT_RESTOL && Control.cooldown > get_unix_time();
|
||||
#ifdef _X11
|
||||
#ifdef X11
|
||||
return res || (flags & NT_NOFOCUS && Control.this_window == get_focused_window_id());
|
||||
#else
|
||||
return res;
|
||||
@ -146,19 +146,19 @@ static bool notifications_are_disabled(uint64_t flags)
|
||||
|
||||
static void control_lock()
|
||||
{
|
||||
#if defined(_SOUND_NOTIFY) || defined(_BOX_NOTIFY)
|
||||
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
|
||||
pthread_mutex_lock(Control.poll_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void control_unlock()
|
||||
{
|
||||
#if defined(_SOUND_NOTIFY) || defined(_BOX_NOTIFY)
|
||||
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
|
||||
pthread_mutex_unlock(Control.poll_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
bool is_playing(int source)
|
||||
{
|
||||
int ready;
|
||||
@ -166,6 +166,33 @@ bool is_playing(int source)
|
||||
return ready == AL_PLAYING;
|
||||
}
|
||||
|
||||
/* TODO maybe find better way to do this */
|
||||
/* cooldown is in seconds */
|
||||
#define DEVICE_COOLDOWN 5 /* TODO perhaps load this from config? */
|
||||
static bool device_opened = false;
|
||||
time_t last_opened_update = 0;
|
||||
|
||||
bool m_open_device()
|
||||
{
|
||||
last_opened_update = time(NULL);
|
||||
|
||||
if (device_opened) return true;
|
||||
|
||||
/* Blah error check */
|
||||
open_primary_device(output, &Control.device_idx, 48000, 20, 1);
|
||||
|
||||
return (device_opened = true);
|
||||
}
|
||||
|
||||
bool m_close_device()
|
||||
{
|
||||
if (!device_opened) return true;
|
||||
|
||||
close_device(output, Control.device_idx);
|
||||
|
||||
return !(device_opened = false);
|
||||
}
|
||||
|
||||
/* Terminate all sounds but wait for them to finish first */
|
||||
void graceful_clear()
|
||||
{
|
||||
@ -174,7 +201,7 @@ void graceful_clear()
|
||||
while (1) {
|
||||
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
|
||||
if (actives[i].active) {
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
if (actives[i].box) {
|
||||
GError* ignore;
|
||||
notify_notification_close(actives[i].box, &ignore);
|
||||
@ -195,6 +222,7 @@ void graceful_clear()
|
||||
}
|
||||
|
||||
if (i == ACTIVE_NOTIFS_MAX) {
|
||||
m_close_device(); /* In case it's opened */
|
||||
control_unlock();
|
||||
return;
|
||||
}
|
||||
@ -207,11 +235,19 @@ void* do_playing(void* _p)
|
||||
{
|
||||
(void)_p;
|
||||
int i;
|
||||
|
||||
bool has_looping = false;
|
||||
|
||||
while(Control.poll_active) {
|
||||
control_lock();
|
||||
|
||||
|
||||
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
|
||||
|
||||
if (actives[i].looping) has_looping = true;
|
||||
|
||||
if (actives[i].active && !actives[i].looping
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
&& !actives[i].box
|
||||
#endif
|
||||
) {
|
||||
@ -223,7 +259,7 @@ void* do_playing(void* _p)
|
||||
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
|
||||
}
|
||||
}
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
else if (actives[i].box && time(NULL) >= actives[i].n_timeout)
|
||||
{
|
||||
GError* ignore;
|
||||
@ -242,6 +278,14 @@ void* do_playing(void* _p)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* device is opened and no activity in under DEVICE_COOLDOWN time, close device*/
|
||||
if (device_opened && !has_looping &&
|
||||
(time(NULL) - last_opened_update) > DEVICE_COOLDOWN) {
|
||||
m_close_device();
|
||||
}
|
||||
has_looping = false;
|
||||
|
||||
control_unlock();
|
||||
usleep(10000);
|
||||
}
|
||||
@ -266,7 +310,7 @@ int play_source(uint32_t source, uint32_t buffer, bool looping)
|
||||
return i;
|
||||
}
|
||||
|
||||
#elif _BOX_NOTIFY
|
||||
#elif BOX_NOTIFY
|
||||
void* do_playing(void* _p)
|
||||
{
|
||||
(void)_p;
|
||||
@ -321,15 +365,16 @@ void graceful_clear()
|
||||
/* Opens primary device */
|
||||
int init_notify(int login_cooldown, int notification_timeout)
|
||||
{
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
alutInitWithoutContext(NULL, NULL);
|
||||
if (open_primary_device(output, &Control.device_idx, 48000, 20, 1) != de_None)
|
||||
return -1;
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
|
||||
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
|
||||
if (pthread_mutex_init(Control.poll_mutex, NULL) != 0)
|
||||
return -1;
|
||||
|
||||
#if defined(_SOUND_NOTIFY) || defined(_BOX_NOTIFY)
|
||||
pthread_mutex_init(Control.poll_mutex, NULL);
|
||||
pthread_t thread;
|
||||
|
||||
if (pthread_create(&thread, NULL, do_playing, NULL) != 0 || pthread_detach(thread) != 0 ) {
|
||||
pthread_mutex_destroy(Control.poll_mutex);
|
||||
return -1;
|
||||
@ -338,13 +383,13 @@ int init_notify(int login_cooldown, int notification_timeout)
|
||||
#endif
|
||||
|
||||
Control.cooldown = time(NULL) + login_cooldown;
|
||||
#ifdef _X11
|
||||
#ifdef X11
|
||||
Control.display = XOpenDisplay(NULL);
|
||||
Control.this_window = get_focused_window_id();
|
||||
#endif /* _X11 */
|
||||
#endif /* X11 */
|
||||
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
notify_init("toxic");
|
||||
#endif
|
||||
Control.notif_timeout = notification_timeout;
|
||||
@ -353,26 +398,25 @@ int init_notify(int login_cooldown, int notification_timeout)
|
||||
|
||||
void terminate_notify()
|
||||
{
|
||||
#if defined(_SOUND_NOTIFY) || defined(_BOX_NOTIFY)
|
||||
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
|
||||
if ( !Control.poll_active ) return;
|
||||
Control.poll_active = 0;
|
||||
|
||||
graceful_clear();
|
||||
#endif
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
int i = 0;
|
||||
for (; i < SOUNDS_SIZE; i ++) free(Control.sounds[i]);
|
||||
close_device(output, Control.device_idx);
|
||||
alutExit();
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
notify_uninit();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
int set_sound(Notification sound, const char* value)
|
||||
{
|
||||
if (sound == silent) return 0;
|
||||
@ -392,6 +436,8 @@ int play_sound_internal(Notification what, bool loop)
|
||||
uint32_t source;
|
||||
uint32_t buffer;
|
||||
|
||||
m_open_device();
|
||||
|
||||
alGenSources(1, &source);
|
||||
alGenBuffers(1, &buffer);
|
||||
buffer = alutCreateBufferFromFile(Control.sounds[what]);
|
||||
@ -428,7 +474,7 @@ int play_notify_sound(Notification notif, uint64_t flags)
|
||||
void stop_sound(int id)
|
||||
{
|
||||
if (id >= 0 && id < ACTIVE_NOTIFS_MAX && actives[id].looping && actives[id].active ) {
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
if (actives[id].box) {
|
||||
GError* ignore;
|
||||
notify_notification_close(actives[id].box, &ignore);
|
||||
@ -446,17 +492,17 @@ void stop_sound(int id)
|
||||
|
||||
static int m_play_sound(Notification notif, uint64_t flags)
|
||||
{
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
return play_notify_sound(notif, flags);
|
||||
#else
|
||||
if (notif != silent)
|
||||
beep();
|
||||
|
||||
return -1;
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
void m_notify_action(NotifyNotification *box, char *action, void* data)
|
||||
{
|
||||
}
|
||||
@ -472,13 +518,13 @@ int sound_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_in
|
||||
int id = -1;
|
||||
control_lock();
|
||||
|
||||
if (self && (!self->stb || self->stb->status != TOX_USERSTATUS_BUSY) && user_settings_->alerts == ALERTS_ENABLED)
|
||||
if (self && (!self->stb || self->stb->status != TOX_USERSTATUS_BUSY) && user_settings->alerts == ALERTS_ENABLED)
|
||||
id = m_play_sound(notif, flags);
|
||||
|
||||
else if (flags & NT_ALWAYS)
|
||||
id = m_play_sound(notif, flags);
|
||||
|
||||
#if defined(_BOX_NOTIFY) && !defined(_SOUND_NOTIFY)
|
||||
#if defined(BOX_NOTIFY) && !defined(SOUND_NOTIFY)
|
||||
|
||||
if (id == -1) {
|
||||
for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].box; id ++);
|
||||
@ -508,7 +554,7 @@ int sound_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id)
|
||||
return -1;
|
||||
|
||||
if (id < 0 || id >= ACTIVE_NOTIFS_MAX) return -1;
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
control_lock();
|
||||
|
||||
if (!actives[id].active || !Control.sounds[notif]) {
|
||||
@ -516,6 +562,8 @@ int sound_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_open_device();
|
||||
|
||||
alSourceStop(actives[id].source);
|
||||
alDeleteSources(1, &actives[id].source);
|
||||
alDeleteBuffers(1,&actives[id].buffer);
|
||||
@ -537,7 +585,7 @@ int sound_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id)
|
||||
beep();
|
||||
|
||||
return 0;
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
}
|
||||
|
||||
int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indicator, char* title, const char* format, ...)
|
||||
@ -547,13 +595,13 @@ int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indi
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
|
||||
int id = sound_notify(self, notif, flags, id_indicator);
|
||||
|
||||
control_lock();
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
if (id == -1) { /* Could not play */
|
||||
|
||||
for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].active; id ++);
|
||||
@ -601,7 +649,7 @@ int box_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id, con
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
|
||||
if (sound_notify2(self, notif, flags, id) == -1)
|
||||
return -1;
|
||||
@ -651,7 +699,7 @@ int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const
|
||||
if (notifications_are_disabled(flags))
|
||||
return -1;
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
|
||||
control_lock();
|
||||
|
||||
@ -701,7 +749,7 @@ int box_silent_notify2(ToxWindow* self, uint64_t flags, int id, const char* form
|
||||
if (notifications_are_disabled(flags))
|
||||
return -1;
|
||||
|
||||
#ifdef _BOX_NOTIFY
|
||||
#ifdef BOX_NOTIFY
|
||||
control_lock();
|
||||
|
||||
if (id < 0 || id >= ACTIVE_NOTIFS_MAX || !actives[id].box || actives[id].size >= MAX_BOX_MSG_LEN + 1 ) {
|
||||
|
10
src/notify.h
10
src/notify.h
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _notify_h
|
||||
#define _notify_h
|
||||
#ifndef NOTIFY_H
|
||||
#define NOTIFY_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "windows.h"
|
||||
@ -73,8 +73,8 @@ int box_notify2(ToxWindow* self, Notification notif, uint64_t flags, int id, con
|
||||
int box_silent_notify(ToxWindow* self, uint64_t flags, int* id_indicator, const char* title, const char* format, ...);
|
||||
int box_silent_notify2(ToxWindow* self, uint64_t flags, int id, const char* format, ...);
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
int set_sound(Notification sound, const char* value);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
|
||||
#endif /* _notify_h */
|
||||
#endif /* NOTIFY_H */
|
||||
|
46
src/prompt.c
46
src/prompt.c
@ -43,15 +43,16 @@
|
||||
#include "autocomplete.h"
|
||||
|
||||
extern ToxWindow *prompt;
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct _Winthread Winthread;
|
||||
extern struct user_settings *user_settings;
|
||||
extern struct Winthread Winthread;
|
||||
|
||||
_FriendRequests FriendRequests;
|
||||
FriendRequests FrndRequests;
|
||||
|
||||
/* Array of global command names used for tab completion. */
|
||||
const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/accept" },
|
||||
{ "/add" },
|
||||
{ "/avatar" },
|
||||
{ "/clear" },
|
||||
{ "/close" }, /* rm /close when groupchats gets its own list */
|
||||
{ "/connect" },
|
||||
@ -67,12 +68,12 @@ const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
|
||||
{ "/requests" },
|
||||
{ "/status" },
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
|
||||
{ "/lsdev" },
|
||||
{ "/sdev" },
|
||||
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
};
|
||||
|
||||
void kill_prompt_window(ToxWindow *self)
|
||||
@ -131,21 +132,21 @@ void prompt_update_connectionstatus(ToxWindow *prompt, bool is_connected)
|
||||
Returns request number on success, -1 if queue is full. */
|
||||
static int add_friend_request(const char *public_key, const char *data)
|
||||
{
|
||||
if (FriendRequests.max_idx >= MAX_FRIEND_REQUESTS)
|
||||
if (FrndRequests.max_idx >= MAX_FRIEND_REQUESTS)
|
||||
return -1;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= FriendRequests.max_idx; ++i) {
|
||||
if (!FriendRequests.request[i].active) {
|
||||
FriendRequests.request[i].active = true;
|
||||
memcpy(FriendRequests.request[i].key, public_key, TOX_CLIENT_ID_SIZE);
|
||||
snprintf(FriendRequests.request[i].msg, sizeof(FriendRequests.request[i].msg), "%s", data);
|
||||
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_CLIENT_ID_SIZE);
|
||||
snprintf(FrndRequests.request[i].msg, sizeof(FrndRequests.request[i].msg), "%s", data);
|
||||
|
||||
if (i == FriendRequests.max_idx)
|
||||
++FriendRequests.max_idx;
|
||||
if (i == FrndRequests.max_idx)
|
||||
++FrndRequests.max_idx;
|
||||
|
||||
++FriendRequests.num_requests;
|
||||
++FrndRequests.num_requests;
|
||||
|
||||
return i;
|
||||
}
|
||||
@ -183,7 +184,12 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
||||
|
||||
if (key == '\t') { /* TAB key: auto-completes command */
|
||||
if (ctx->len > 1 && ctx->line[0] == '/') {
|
||||
int diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);
|
||||
int diff = -1;
|
||||
|
||||
if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0)
|
||||
diff = dir_match(self, m, ctx->line, L"/avatar");
|
||||
else
|
||||
diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);
|
||||
|
||||
if (diff != -1) {
|
||||
if (x + diff > x2 - 1) {
|
||||
@ -271,7 +277,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
||||
} else {
|
||||
wprintw(statusbar->topline, " [Offline]");
|
||||
wattron(statusbar->topline, A_BOLD);
|
||||
wprintw(statusbar->topline, " %s ", statusbar->nick);
|
||||
wprintw(statusbar->topline, " %s", statusbar->nick);
|
||||
wattroff(statusbar->topline, A_BOLD);
|
||||
}
|
||||
|
||||
@ -299,7 +305,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
||||
}
|
||||
|
||||
if (statusbar->statusmsg[0])
|
||||
wprintw(statusbar->topline, " - %s", statusbar->statusmsg);
|
||||
wprintw(statusbar->topline, " : %s", statusbar->statusmsg);
|
||||
|
||||
mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);
|
||||
|
||||
@ -455,16 +461,16 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
|
||||
|
||||
line_info_init(ctx->hst);
|
||||
|
||||
if (user_settings_->autolog == AUTOLOG_ON) {
|
||||
if (user_settings->autolog == AUTOLOG_ON) {
|
||||
char myid[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(m, (uint8_t *) myid);
|
||||
log_enable(self->name, myid, ctx->log);
|
||||
log_enable(self->name, myid, NULL, ctx->log, LOG_PROMPT);
|
||||
}
|
||||
|
||||
scrollok(ctx->history, 0);
|
||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||
|
||||
if (user_settings_->show_welcome_msg == SHOW_WELCOME_MSG_ON)
|
||||
if (user_settings->show_welcome_msg == SHOW_WELCOME_MSG_ON)
|
||||
print_welcome_msg(self);
|
||||
}
|
||||
|
||||
|
20
src/prompt.h
20
src/prompt.h
@ -20,21 +20,21 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PROMPT_H_UZYGWFFL
|
||||
#define PROMPT_H_UZYGWFFL
|
||||
#ifndef PROMPT_H
|
||||
#define PROMPT_H
|
||||
|
||||
#include "toxic.h"
|
||||
#include "windows.h"
|
||||
|
||||
#ifdef _AUDIO
|
||||
#define AC_NUM_GLOB_COMMANDS 18
|
||||
#ifdef AUDIO
|
||||
#define AC_NUM_GLOB_COMMANDS 19
|
||||
#else
|
||||
#define AC_NUM_GLOB_COMMANDS 16
|
||||
#endif /* _AUDIO */
|
||||
#define AC_NUM_GLOB_COMMANDS 17
|
||||
#endif /* AUDIO */
|
||||
|
||||
#define MAX_FRIEND_REQUESTS 32
|
||||
|
||||
struct _friend_request {
|
||||
struct friend_request {
|
||||
bool active;
|
||||
char msg[MAX_STR_SIZE];
|
||||
uint8_t key[TOX_CLIENT_ID_SIZE];
|
||||
@ -43,8 +43,8 @@ struct _friend_request {
|
||||
typedef struct {
|
||||
int max_idx;
|
||||
int num_requests;
|
||||
struct _friend_request request[MAX_FRIEND_REQUESTS];
|
||||
} _FriendRequests;
|
||||
struct friend_request request[MAX_FRIEND_REQUESTS];
|
||||
} FriendRequests;
|
||||
|
||||
ToxWindow new_prompt(void);
|
||||
void prep_prompt_win(void);
|
||||
@ -55,4 +55,4 @@ void prompt_update_status(ToxWindow *prompt, uint8_t status);
|
||||
void prompt_update_connectionstatus(ToxWindow *prompt, bool is_connected);
|
||||
void kill_prompt_window(ToxWindow *self);
|
||||
|
||||
#endif /* end of include guard: PROMPT_H_UZYGWFFL */
|
||||
#endif /* end of include guard: PROMPT_H */
|
||||
|
@ -31,9 +31,9 @@
|
||||
#include "notify.h"
|
||||
#include "misc_tools.h"
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
#include "device.h"
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#include "settings.h"
|
||||
#include "line_info.h"
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
#define NO_SOUND "silent"
|
||||
|
||||
static struct _ui_strings {
|
||||
static struct ui_strings {
|
||||
const char* self;
|
||||
const char* timestamps;
|
||||
const char* alerts;
|
||||
@ -81,7 +81,7 @@ static void ui_defaults(struct user_settings* settings)
|
||||
settings->show_welcome_msg = SHOW_WELCOME_MSG_ON;
|
||||
}
|
||||
|
||||
static const struct _keys_strings {
|
||||
static const struct keys_strings {
|
||||
const char* self;
|
||||
const char* next_tab;
|
||||
const char* prev_tab;
|
||||
@ -119,24 +119,27 @@ static void key_defaults(struct user_settings* settings)
|
||||
settings->key_peer_list_down = T_KEY_C_RB;
|
||||
}
|
||||
|
||||
static const struct _tox_strings {
|
||||
static const struct tox_strings {
|
||||
const char* self;
|
||||
const char* download_path;
|
||||
const char* chatlogs_path;
|
||||
const char* avatar_path;
|
||||
} tox_strings = {
|
||||
"tox",
|
||||
"download_path",
|
||||
"chatlogs_path",
|
||||
"avatar_path",
|
||||
};
|
||||
|
||||
static void tox_defaults(struct user_settings* settings)
|
||||
{
|
||||
strcpy(settings->download_path, "");
|
||||
strcpy(settings->chatlogs_path, "");
|
||||
strcpy(settings->avatar_path, "");
|
||||
}
|
||||
|
||||
#ifdef _AUDIO
|
||||
static const struct _audio_strings {
|
||||
#ifdef AUDIO
|
||||
static const struct audio_strings {
|
||||
const char* self;
|
||||
const char* input_device;
|
||||
const char* output_device;
|
||||
@ -156,8 +159,8 @@ static void audio_defaults(struct user_settings* settings)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
static const struct _sound_strings {
|
||||
#ifdef SOUND_NOTIFY
|
||||
static const struct sound_strings {
|
||||
const char* self;
|
||||
const char* error;
|
||||
const char* self_log_in;
|
||||
@ -212,7 +215,7 @@ int settings_load(struct user_settings *s, const char *patharg)
|
||||
tox_defaults(s);
|
||||
key_defaults(s);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
audio_defaults(s);
|
||||
#endif
|
||||
|
||||
@ -280,6 +283,14 @@ int settings_load(struct user_settings *s, const char *patharg)
|
||||
else if (s->chatlogs_path[len - 1] != '/')
|
||||
strcat(&s->chatlogs_path[len - 1], "/");
|
||||
}
|
||||
|
||||
if ( config_setting_lookup_string(setting, tox_strings.avatar_path, &str) ) {
|
||||
snprintf(s->avatar_path, sizeof(s->avatar_path), "%s", str);
|
||||
int len = strlen(s->avatar_path);
|
||||
|
||||
if (len >= sizeof(s->avatar_path))
|
||||
s->avatar_path[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* keys */
|
||||
@ -296,7 +307,7 @@ int settings_load(struct user_settings *s, const char *patharg)
|
||||
if (config_setting_lookup_string(setting, key_strings.peer_list_down, &tmp)) s->key_peer_list_down = key_parse(&tmp);
|
||||
}
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
if ((setting = config_lookup(cfg, audio_strings.self)) != NULL) {
|
||||
config_setting_lookup_int(setting, audio_strings.input_device, &s->audio_in_dev);
|
||||
s->audio_in_dev = s->audio_in_dev < 0 || s->audio_in_dev > MAX_DEVICES ? 0 : s->audio_in_dev;
|
||||
@ -308,7 +319,7 @@ int settings_load(struct user_settings *s, const char *patharg)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
if ((setting = config_lookup(cfg, sound_strings.self)) != NULL) {
|
||||
if ( (config_setting_lookup_string(setting, sound_strings.error, &str) != CONFIG_TRUE) ||
|
||||
!set_sound(error, str) ) {
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _settings_h
|
||||
#define _settings_h
|
||||
#ifndef SETTINGS_H
|
||||
#define SETTINGS_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
@ -39,9 +39,10 @@ struct user_settings {
|
||||
|
||||
char download_path[PATH_MAX];
|
||||
char chatlogs_path[PATH_MAX];
|
||||
char avatar_path[PATH_MAX];
|
||||
|
||||
int key_next_tab; /* character code */
|
||||
int key_prev_tab; /* character code */
|
||||
int key_next_tab;
|
||||
int key_prev_tab;
|
||||
int key_scroll_line_up;
|
||||
int key_scroll_line_down;
|
||||
int key_half_page_up;
|
||||
@ -49,7 +50,8 @@ struct user_settings {
|
||||
int key_page_bottom;
|
||||
int key_peer_list_up;
|
||||
int key_peer_list_down;
|
||||
#ifdef _AUDIO
|
||||
|
||||
#ifdef AUDIO
|
||||
int audio_in_dev;
|
||||
int audio_out_dev;
|
||||
double VAD_treshold;
|
||||
@ -82,4 +84,4 @@ enum {
|
||||
} settings_values;
|
||||
|
||||
int settings_load(struct user_settings *s, const char *patharg);
|
||||
#endif /* #define _settings_h */
|
||||
#endif /* #define SETTINGS_H */
|
||||
|
79
src/toxic.c
79
src/toxic.c
@ -56,18 +56,19 @@
|
||||
#include "notify.h"
|
||||
#include "device.h"
|
||||
#include "message_queue.h"
|
||||
#include "execute.h"
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
#include "audio_call.h"
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#ifndef PACKAGE_DATADIR
|
||||
#define PACKAGE_DATADIR "."
|
||||
#endif
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
ToxAv *av;
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
/* Export for use in Callbacks */
|
||||
char *DATA_FILE = NULL;
|
||||
@ -76,15 +77,15 @@ ToxWindow *prompt = NULL;
|
||||
|
||||
#define AUTOSAVE_FREQ 60
|
||||
|
||||
struct _Winthread Winthread;
|
||||
struct _cqueue_thread cqueue_thread;
|
||||
struct Winthread Winthread;
|
||||
struct cqueue_thread cqueue_thread;
|
||||
struct arg_opts arg_opts;
|
||||
struct user_settings *user_settings_ = NULL;
|
||||
struct user_settings *user_settings = NULL;
|
||||
|
||||
#define MIN_PASSWORD_LEN 6
|
||||
#define MAX_PASSWORD_LEN 64
|
||||
|
||||
static struct _user_password {
|
||||
static struct user_password {
|
||||
bool data_is_encrypted;
|
||||
char pass[MAX_PASSWORD_LEN + 1];
|
||||
int len;
|
||||
@ -92,7 +93,7 @@ static struct _user_password {
|
||||
|
||||
static void catch_SIGINT(int sig)
|
||||
{
|
||||
Winthread.sig_exit_toxic = true;
|
||||
Winthread.sig_exit_toxic = 1;
|
||||
}
|
||||
|
||||
static void catch_SIGSEGV(int sig)
|
||||
@ -105,7 +106,7 @@ static void catch_SIGSEGV(int sig)
|
||||
|
||||
static void flag_window_resize(int sig)
|
||||
{
|
||||
Winthread.flag_resize = true;
|
||||
Winthread.flag_resize = 1;
|
||||
}
|
||||
|
||||
static void init_signal_catchers(void)
|
||||
@ -118,21 +119,21 @@ static void init_signal_catchers(void)
|
||||
void exit_toxic_success(Tox *m)
|
||||
{
|
||||
store_data(m, DATA_FILE);
|
||||
memset(&user_password, 0, sizeof(struct _user_password));
|
||||
memset(&user_password, 0, sizeof(struct user_password));
|
||||
close_all_file_senders(m);
|
||||
kill_all_windows(m);
|
||||
|
||||
free(DATA_FILE);
|
||||
free(BLOCK_FILE);
|
||||
free(user_settings_);
|
||||
free(user_settings);
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
// sound_notify(NULL, self_log_out, NT_ALWAYS, NULL);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
terminate_notify();
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
terminate_audio();
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
tox_kill(m);
|
||||
endwin();
|
||||
exit(EXIT_SUCCESS);
|
||||
@ -171,7 +172,7 @@ static void init_term(void)
|
||||
short bg_color = COLOR_BLACK;
|
||||
start_color();
|
||||
|
||||
if (user_settings_->colour_theme == NATIVE_COLS) {
|
||||
if (user_settings->colour_theme == NATIVE_COLS) {
|
||||
if (assume_default_colors(-1, -1) == OK)
|
||||
bg_color = -1;
|
||||
}
|
||||
@ -222,7 +223,7 @@ static void queue_init_message(const char *msg, ...)
|
||||
init_messages.msgs = new_msgs;
|
||||
}
|
||||
|
||||
/* called after messages have been printed to console and are no longer needed */
|
||||
/* called after messages have been printed to prompt and are no longer needed */
|
||||
static void cleanup_init_messages(void)
|
||||
{
|
||||
if (init_messages.num <= 0)
|
||||
@ -324,7 +325,7 @@ static Tox *init_tox(void)
|
||||
#define MAXNODES 50
|
||||
#define NODELEN (MAX_NODE_LINE - TOX_CLIENT_ID_SIZE - 7)
|
||||
|
||||
static struct _toxNodes {
|
||||
static struct toxNodes {
|
||||
int lines;
|
||||
char nodes[MAXNODES][NODELEN];
|
||||
uint16_t ports[MAXNODES];
|
||||
@ -629,9 +630,12 @@ static void load_data(Tox *m, char *path)
|
||||
FILE *fd;
|
||||
|
||||
if ((fd = fopen(path, "rb")) != NULL) {
|
||||
fseek(fd, 0, SEEK_END);
|
||||
int len = ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
off_t len = file_size(path);
|
||||
|
||||
if (len == -1) {
|
||||
fclose(fd);
|
||||
exit_toxic_err("failed in load_data", FATALERR_FILEOP);
|
||||
}
|
||||
|
||||
char *buf = malloc(len);
|
||||
|
||||
@ -643,7 +647,7 @@ static void load_data(Tox *m, char *path)
|
||||
if (fread(buf, len, 1, fd) != 1) {
|
||||
free(buf);
|
||||
fclose(fd);
|
||||
exit_toxic_err("failed in load_data", FATALERR_FREAD);
|
||||
exit_toxic_err("failed in load_data", FATALERR_FILEOP);
|
||||
}
|
||||
|
||||
bool is_encrypted = tox_is_data_encrypted((uint8_t *) buf);
|
||||
@ -720,6 +724,7 @@ void *thread_winref(void *data)
|
||||
{
|
||||
Tox *m = (Tox *) data;
|
||||
uint8_t draw_count = 0;
|
||||
init_signal_catchers();
|
||||
|
||||
while (true) {
|
||||
draw_active_window(m);
|
||||
@ -727,7 +732,7 @@ void *thread_winref(void *data)
|
||||
|
||||
if (Winthread.flag_resize) {
|
||||
on_window_resize();
|
||||
Winthread.flag_resize = false;
|
||||
Winthread.flag_resize = 0;
|
||||
} else if (draw_count >= INACTIVE_WIN_REFRESH_RATE) {
|
||||
refresh_inactive_windows();
|
||||
draw_count = 0;
|
||||
@ -963,7 +968,6 @@ static useconds_t optimal_msleepval(uint64_t *looptimer, uint64_t *loopcount, ui
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
init_signal_catchers();
|
||||
parse_args(argc, argv);
|
||||
|
||||
if (arg_opts.encrypt_data && arg_opts.unencrypt_data) {
|
||||
@ -990,13 +994,13 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* init user_settings struct and load settings from conf file */
|
||||
user_settings_ = calloc(1, sizeof(struct user_settings));
|
||||
user_settings = calloc(1, sizeof(struct user_settings));
|
||||
|
||||
if (user_settings_ == NULL)
|
||||
if (user_settings == NULL)
|
||||
exit_toxic_err("failed in main", FATALERR_MEMORY);
|
||||
|
||||
const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
|
||||
int settings_err = settings_load(user_settings_, p);
|
||||
int settings_err = settings_load(user_settings, p);
|
||||
|
||||
Tox *m = init_tox();
|
||||
|
||||
@ -1026,24 +1030,24 @@ int main(int argc, char *argv[])
|
||||
if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
|
||||
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
|
||||
av = init_audio(prompt, m);
|
||||
|
||||
set_primary_device(input, user_settings_->audio_in_dev);
|
||||
set_primary_device(output, user_settings_->audio_out_dev);
|
||||
set_primary_device(input, user_settings->audio_in_dev);
|
||||
set_primary_device(output, user_settings->audio_out_dev);
|
||||
|
||||
#elif _SOUND_NOTIFY
|
||||
#elif SOUND_NOTIFY
|
||||
if ( init_devices() == de_InternalError )
|
||||
queue_init_message("Failed to init audio devices");
|
||||
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
init_notify(60, 3000);
|
||||
|
||||
#ifdef _SOUND_NOTIFY
|
||||
#ifdef SOUND_NOTIFY
|
||||
// sound_notify(prompt, self_log_in, 0, NULL);
|
||||
#endif /* _SOUND_NOTIFY */
|
||||
#endif /* SOUND_NOTIFY */
|
||||
|
||||
const char *msg;
|
||||
|
||||
@ -1058,6 +1062,11 @@ int main(int argc, char *argv[])
|
||||
print_init_messages(prompt);
|
||||
cleanup_init_messages();
|
||||
|
||||
/* set user avatar from config file. if no path is supplied tox_unset_avatar is called */
|
||||
char avatarstr[MAX_STR_SIZE];
|
||||
snprintf(avatarstr, sizeof(avatarstr), "/avatar \"%s\"", user_settings->avatar_path);
|
||||
execute(prompt->chatwin->history, prompt, m, avatarstr, GLOBAL_COMMAND_MODE);
|
||||
|
||||
uint64_t last_save = (uint64_t) time(NULL);
|
||||
uint64_t looptimer = last_save;
|
||||
useconds_t msleepval = 40000;
|
||||
|
16
src/toxic.h
16
src/toxic.h
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _toxic_h
|
||||
#define _toxic_h
|
||||
#ifndef TOXIC_H
|
||||
#define TOXIC_H
|
||||
|
||||
#ifndef TOXICVER
|
||||
#define TOXICVER "NOVER_" /* Use the -D flag to set this */
|
||||
@ -45,7 +45,7 @@
|
||||
#define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH
|
||||
#define MAX_CMDNAME_SIZE 64
|
||||
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */
|
||||
#define KEY_IDENT_DIGITS 2 /* number of hex digits to display for the pub-key based identifier */
|
||||
#define KEY_IDENT_DIGITS 3 /* number of hex digits to display for the pub-key based identifier */
|
||||
#define TIME_STR_SIZE 16
|
||||
|
||||
/* ASCII key codes */
|
||||
@ -69,9 +69,9 @@
|
||||
|
||||
typedef enum _FATAL_ERRS {
|
||||
FATALERR_MEMORY = -1, /* heap memory allocation failed */
|
||||
FATALERR_FREAD = -2, /* fread() failed on critical read */
|
||||
FATALERR_THREAD_CREATE = -3, /* thread creation failed */
|
||||
FATALERR_MUTEX_INIT = -4, /* mutex init failed */
|
||||
FATALERR_FILEOP = -2, /* critical file operation failed */
|
||||
FATALERR_THREAD_CREATE = -3, /* thread creation failed for critical thread */
|
||||
FATALERR_MUTEX_INIT = -4, /* mutex init for critical thread failed */
|
||||
FATALERR_THREAD_ATTR = -5, /* thread attr object init failed */
|
||||
FATALERR_LOCALE_SET = -6, /* system locale not set */
|
||||
FATALERR_STORE_DATA = -7, /* store_data failed in critical section */
|
||||
@ -101,7 +101,7 @@ void on_statusmessagechange(Tox *m, int32_t friendnumber, const uint8_t *string,
|
||||
void on_friendadded(Tox *m, int32_t friendnumber, bool sort);
|
||||
void on_groupmessage(Tox *m, int groupnumber, int peernumber, const uint8_t *message, uint16_t length, void *userdata);
|
||||
void on_groupaction(Tox *m, int groupnumber, int peernumber, const uint8_t *action, uint16_t length, void *userdata);
|
||||
void on_groupinvite(Tox *m, int32_t friendnumber, const uint8_t *group_pub_key, void *userdata);
|
||||
void on_groupinvite(Tox *m, int32_t friendnumber, const uint8_t *group_pub_key, uint16_t length, void *userdata);
|
||||
void on_group_namelistchange(Tox *m, int groupnumber, int peernumber, uint8_t change, void *userdata);
|
||||
void on_file_sendrequest(Tox *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, const uint8_t *pathname,
|
||||
uint16_t pathname_length, void *userdata);
|
||||
@ -111,4 +111,4 @@ void on_file_data(Tox *m, int32_t friendnumber, uint8_t filenumber, const uint8_
|
||||
void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *userdata);
|
||||
void on_read_receipt(Tox *m, int32_t, uint32_t, void *userdata);
|
||||
|
||||
#endif /* #define _toxic_h */
|
||||
#endif /* #define TOXIC_H */
|
||||
|
@ -20,8 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _toxic_strings_h
|
||||
#define _toxic_strings_h
|
||||
#ifndef TOXIC_STRINGS_H
|
||||
#define TOXIC_STRINGS_H
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
@ -61,4 +61,4 @@ void add_line_to_hist(ChatContext *ctx);
|
||||
resets line if at end of history */
|
||||
void fetch_hist_item(ChatContext *ctx, int key_dir);
|
||||
|
||||
#endif /* #define _toxic_strings_h */
|
||||
#endif /* #define TOXIC_STRINGS_H */
|
||||
|
@ -35,12 +35,12 @@
|
||||
|
||||
#include "settings.h"
|
||||
extern char *DATA_FILE;
|
||||
extern struct _Winthread Winthread;
|
||||
extern struct Winthread Winthread;
|
||||
static ToxWindow windows[MAX_WINDOWS_NUM];
|
||||
static ToxWindow *active_window;
|
||||
|
||||
extern ToxWindow *prompt;
|
||||
extern struct user_settings *user_settings_;
|
||||
extern struct user_settings *user_settings;
|
||||
|
||||
static int num_active_windows;
|
||||
|
||||
@ -67,7 +67,7 @@ void on_connectionchange(Tox *m, int32_t friendnumber, uint8_t status, void *use
|
||||
|
||||
void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *userdata)
|
||||
{
|
||||
if (user_settings_->show_typing_other == SHOW_TYPING_OFF)
|
||||
if (user_settings->show_typing_other == SHOW_TYPING_OFF)
|
||||
return;
|
||||
|
||||
int i;
|
||||
@ -164,13 +164,13 @@ void on_groupaction(Tox *m, int groupnumber, int peernumber, const uint8_t *acti
|
||||
}
|
||||
}
|
||||
|
||||
void on_groupinvite(Tox *m, int32_t friendnumber, const uint8_t *group_pub_key, void *userdata)
|
||||
void on_groupinvite(Tox *m, int32_t friendnumber, const uint8_t *group_pub_key, uint16_t length, void *userdata)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||
if (windows[i].onGroupInvite != NULL)
|
||||
windows[i].onGroupInvite(&windows[i], m, friendnumber, (const char *) group_pub_key);
|
||||
windows[i].onGroupInvite(&windows[i], m, friendnumber, (const char *) group_pub_key, length);
|
||||
}
|
||||
}
|
||||
|
||||
@ -278,7 +278,7 @@ void set_next_window(int ch)
|
||||
ToxWindow *inf = active_window;
|
||||
|
||||
while (true) {
|
||||
if (ch == user_settings_->key_next_tab) {
|
||||
if (ch == user_settings->key_next_tab) {
|
||||
if (++active_window > end)
|
||||
active_window = windows;
|
||||
} else if (--active_window < windows)
|
||||
@ -366,12 +366,12 @@ void on_window_resize(void)
|
||||
w->stb->topline = subwin(w->window, 2, x2, 0, 0);
|
||||
}
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
if (w->chatwin->infobox.active) {
|
||||
delwin(w->chatwin->infobox.win);
|
||||
w->chatwin->infobox.win = newwin(INFOBOX_HEIGHT, INFOBOX_WIDTH + 1, 1, x2 - INFOBOX_WIDTH);
|
||||
}
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
scrollok(w->chatwin->history, 0);
|
||||
}
|
||||
@ -462,7 +462,7 @@ void draw_active_window(Tox *m)
|
||||
ltr = isprint(ch);
|
||||
#endif /* HAVE_WIDECHAR */
|
||||
|
||||
if (!ltr && (ch == user_settings_->key_next_tab || ch == user_settings_->key_prev_tab)) {
|
||||
if (!ltr && (ch == user_settings->key_next_tab || ch == user_settings->key_prev_tab)) {
|
||||
set_next_window((int) ch);
|
||||
} else {
|
||||
pthread_mutex_lock(&Winthread.lock);
|
||||
|
@ -20,18 +20,19 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _windows_h
|
||||
#define _windows_h
|
||||
#ifndef WINDOWS_H
|
||||
#define WINDOWS_H
|
||||
|
||||
#include <pthread.h>
|
||||
#include <wctype.h>
|
||||
#include <wchar.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
#include <tox/toxav.h>
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#include "toxic.h"
|
||||
|
||||
@ -64,14 +65,14 @@ typedef enum {
|
||||
Uncomment if necessary */
|
||||
/* #define URXVT_FIX */
|
||||
|
||||
struct _Winthread {
|
||||
struct Winthread {
|
||||
pthread_t tid;
|
||||
pthread_mutex_t lock;
|
||||
bool sig_exit_toxic;
|
||||
bool flag_resize;
|
||||
volatile sig_atomic_t sig_exit_toxic;
|
||||
volatile sig_atomic_t flag_resize;
|
||||
};
|
||||
|
||||
struct _cqueue_thread {
|
||||
struct cqueue_thread {
|
||||
pthread_t tid;
|
||||
};
|
||||
|
||||
@ -114,7 +115,7 @@ struct ToxWindow {
|
||||
void(*onAction)(ToxWindow *, Tox *, int32_t, const char *, uint16_t);
|
||||
void(*onGroupMessage)(ToxWindow *, Tox *, int, int, const char *, uint16_t);
|
||||
void(*onGroupAction)(ToxWindow *, Tox *, int, int, const char *, uint16_t);
|
||||
void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, const char *);
|
||||
void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, const char *, uint16_t);
|
||||
void(*onGroupNamelistChange)(ToxWindow *, Tox *, int, int, uint8_t);
|
||||
void(*onFileSendRequest)(ToxWindow *, Tox *, int32_t, uint8_t, uint64_t, const char *, uint16_t);
|
||||
void(*onFileControl)(ToxWindow *, Tox *, int32_t, uint8_t, uint8_t, uint8_t, const char *, uint16_t);
|
||||
@ -122,7 +123,7 @@ struct ToxWindow {
|
||||
void(*onTypingChange)(ToxWindow *, Tox *, int32_t, uint8_t);
|
||||
void(*onReadReceipt)(ToxWindow *, Tox *, int32_t, uint32_t);
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
|
||||
void(*onInvite)(ToxWindow *, ToxAv *, int);
|
||||
void(*onRinging)(ToxWindow *, ToxAv *, int);
|
||||
@ -141,7 +142,7 @@ struct ToxWindow {
|
||||
int device_selection[2]; /* -1 if not set, if set uses these selections instead of primary device */
|
||||
|
||||
int ringing_sound;
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
int active_box; /* For box notify */
|
||||
|
||||
@ -175,7 +176,7 @@ struct StatusBar {
|
||||
bool is_online;
|
||||
};
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
|
||||
|
||||
#define INFOBOX_HEIGHT 7
|
||||
@ -194,7 +195,7 @@ struct infobox {
|
||||
|
||||
WINDOW *win;
|
||||
};
|
||||
#endif /* _AUDIO */
|
||||
#endif /* AUDIO */
|
||||
|
||||
#define MAX_LINE_HIST 128
|
||||
|
||||
@ -216,7 +217,7 @@ struct ChatContext {
|
||||
struct chatlog *log;
|
||||
struct chat_queue *cqueue;
|
||||
|
||||
#ifdef _AUDIO
|
||||
#ifdef AUDIO
|
||||
struct infobox infobox;
|
||||
#endif
|
||||
|
||||
@ -247,4 +248,4 @@ ToxWindow *get_window_ptr(int i);
|
||||
call at least once per second */
|
||||
void refresh_inactive_windows(void);
|
||||
|
||||
#endif /* #define _windows_h */
|
||||
#endif /* #define WINDOWS_H */
|
||||
|
Reference in New Issue
Block a user