1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-26 15:03:27 +01:00

Merge pull request #187 from mannol1/master

Added sound notifications, libconfig support, and more...
This commit is contained in:
mannol1 2014-07-21 12:08:19 +02:00
commit 7abd8d5ee5
36 changed files with 906 additions and 428 deletions

View File

@ -1,26 +1,51 @@
# 24 or 12 hour time // SAMPLE TOXIC CONFIGURATION
time:24; // USES LIBCONFIG-ACCEPTED SYNTAX
# 1 to enable timestamps, 0 to disable ui = {
timestamps:1; // true to enable timestamps, false to disable
timestamps:true;
# 1 to enable autologging, 0 to disable // true to disabale terminal alerts on messages, false to enable
autolog:0; alerts:true;
# 1 to disbale terminal alerts on messages, 0 to enable // true to use native terminal colours, false to use toxic default colour theme
alerts:1; native_colors:true;
# maximum lines for chat window history // true to enable autologging, false to disable
history_size:700; autolog:false;
# 1 to use native terminal colours, 0 to use toxic default colour theme // 24 or 12 hour time
colour_theme:0; time_format=24;
# preferred audio input device; numbers correspond to /lsdev in // maximum lines for chat window history
audio_in_dev:0; history_size=700;
};
# preferred audio output device; numbers correspond to /lsdev out audio = {
audio_out_dev:0; // preferred audio input device; numbers correspond to /lsdev in
input_device=2;
# preferred path for downloads // preferred audio output device; numbers correspond to /lsdev out
download_path:/home/USERNAME/Downloads/; output_device=0;
// default VAD treshold; float (recommended values are around 40)
VAD_treshold=40.0;
};
tox = {
// where to store received files
download_path="/home/USERNAME/Downloads/";
};
sounds = {
error="/usr/local/toxic/sounds/Error.wav";
self_log_in="/usr/local/toxic/sounds/Log In.wav";
self_log_out="/usr/local/toxic/sounds/Log Out.wav";
user_log_in="/usr/local/toxic/sounds/Contact Logs In.wav";
user_log_out="/usr/local/toxic/sounds/Contact Logs Out.wav";
call_incoming="/usr/local/toxic/sounds/Incoming Call.wav";
call_outgoing="/usr/local/toxic/sounds/Outgoing Call.wav";
generic_message="/usr/local/toxic/sounds/New Message.wav";
transfer_pending="/usr/local/toxic/sounds/Transfer Pending.wav";
transfer_completed="/usr/local/toxic/sounds/Transfer Complete.wav";
};

BIN
sounds/Contact Logs In.wav Executable file

Binary file not shown.

BIN
sounds/Contact Logs Out.wav Executable file

Binary file not shown.

BIN
sounds/Error.wav Executable file

Binary file not shown.

BIN
sounds/Incoming Call.wav Executable file

Binary file not shown.

BIN
sounds/Log In.wav Executable file

Binary file not shown.

BIN
sounds/Log Out.wav Executable file

Binary file not shown.

BIN
sounds/New Message.wav Executable file

Binary file not shown.

BIN
sounds/Outgoing Call.wav Executable file

Binary file not shown.

BIN
sounds/Transfer Complete.wav Executable file

Binary file not shown.

BIN
sounds/Transfer Pending.wav Executable file

Binary file not shown.

1
sounds/license Normal file
View File

@ -0,0 +1 @@
Tox's sounds are licensed under the "Creative Commons Attribution 3.0 Unported", all credit attributed to Adam Reid.

View File

@ -27,6 +27,7 @@
#include "chat_commands.h" #include "chat_commands.h"
#include "global_commands.h" #include "global_commands.h"
#include "line_info.h" #include "line_info.h"
#include "notify.h"
#include <curses.h> #include <curses.h>
#include <string.h> #include <string.h>
@ -82,17 +83,17 @@ struct _ASettings {
Call calls[MAX_CALLS]; Call calls[MAX_CALLS];
} ASettins; } ASettins;
void callback_recv_invite ( int32_t call_index, void *arg ); void callback_recv_invite ( void* av, int32_t call_index, void *arg );
void callback_recv_ringing ( int32_t call_index, void *arg ); void callback_recv_ringing ( void* av, int32_t call_index, void *arg );
void callback_recv_starting ( int32_t call_index, void *arg ); void callback_recv_starting ( void* av, int32_t call_index, void *arg );
void callback_recv_ending ( int32_t call_index, void *arg ); void callback_recv_ending ( void* av, int32_t call_index, void *arg );
void callback_recv_error ( int32_t call_index, void *arg ); void callback_call_started ( void* av, int32_t call_index, void *arg );
void callback_call_started ( int32_t call_index, void *arg ); void callback_call_canceled ( void* av, int32_t call_index, void *arg );
void callback_call_canceled ( int32_t call_index, void *arg ); void callback_call_rejected ( void* av, int32_t call_index, void *arg );
void callback_call_rejected ( int32_t call_index, void *arg ); void callback_call_ended ( void* av, int32_t call_index, void *arg );
void callback_call_ended ( int32_t call_index, void *arg ); void callback_requ_timeout ( void* av, int32_t call_index, void *arg );
void callback_requ_timeout ( int32_t call_index, void *arg ); void callback_peer_timeout ( void* av, int32_t call_index, void *arg );
void callback_peer_timeout ( int32_t call_index, void *arg ); void callback_media_change ( void* av, int32_t call_index, void *arg );
int stop_transmission(int call_index); int stop_transmission(int call_index);
void write_device_callback(ToxAv* av, int32_t call_index, int16_t* data, int size); void write_device_callback(ToxAv* av, int32_t call_index, int16_t* data, int size);
@ -127,19 +128,19 @@ ToxAv *init_audio(ToxWindow *self, Tox *tox)
return ASettins.av = NULL; return ASettins.av = NULL;
} }
toxav_register_callstate_callback(callback_call_started, av_OnStart, self); toxav_register_callstate_callback(ASettins.av, callback_call_started, av_OnStart, self);
toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, self); toxav_register_callstate_callback(ASettins.av, callback_call_canceled, av_OnCancel, self);
toxav_register_callstate_callback(callback_call_rejected, av_OnReject, self); toxav_register_callstate_callback(ASettins.av, callback_call_rejected, av_OnReject, self);
toxav_register_callstate_callback(callback_call_ended, av_OnEnd, self); toxav_register_callstate_callback(ASettins.av, callback_call_ended, av_OnEnd, self);
toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, self); toxav_register_callstate_callback(ASettins.av, callback_recv_invite, av_OnInvite, self);
toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, self); toxav_register_callstate_callback(ASettins.av, callback_recv_ringing, av_OnRinging, self);
toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, self); toxav_register_callstate_callback(ASettins.av, callback_recv_starting, av_OnStarting, self);
toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, self); toxav_register_callstate_callback(ASettins.av, callback_recv_ending, av_OnEnding, self);
toxav_register_callstate_callback(callback_recv_error, av_OnError, self); toxav_register_callstate_callback(ASettins.av, callback_requ_timeout, av_OnRequestTimeout, self);
toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, self); toxav_register_callstate_callback(ASettins.av, callback_peer_timeout, av_OnPeerTimeout, self);
toxav_register_callstate_callback(callback_peer_timeout, av_OnPeerTimeout, self); toxav_register_callstate_callback(ASettins.av, callback_media_change, av_OnMediaChange, self);
toxav_register_audio_recv_callback(ASettins.av, write_device_callback); toxav_register_audio_recv_callback(ASettins.av, write_device_callback);
@ -240,15 +241,15 @@ int stop_transmission(int call_index)
#define CB_BODY(call_idx, Arg, onFunc) do { ToxWindow* windows = (Arg); int i;\ #define CB_BODY(call_idx, Arg, onFunc) do { ToxWindow* windows = (Arg); int i;\
for (i = 0; i < MAX_WINDOWS_NUM; ++i) if (windows[i].onFunc != NULL) windows[i].onFunc(&windows[i], ASettins.av, call_idx); } while (0) for (i = 0; i < MAX_WINDOWS_NUM; ++i) if (windows[i].onFunc != NULL) windows[i].onFunc(&windows[i], ASettins.av, call_idx); } while (0)
void callback_recv_invite ( int32_t call_index, void* arg ) void callback_recv_invite ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onInvite); CB_BODY(call_index, arg, onInvite);
} }
void callback_recv_ringing ( int32_t call_index, void* arg ) void callback_recv_ringing ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onRinging); CB_BODY(call_index, arg, onRinging);
} }
void callback_recv_starting ( int32_t call_index, void* arg ) void callback_recv_starting ( void* av, int32_t call_index, void* arg )
{ {
ToxWindow* windows = arg; ToxWindow* windows = arg;
int i; int i;
@ -261,17 +262,13 @@ void callback_recv_starting ( int32_t call_index, void* arg )
return; return;
} }
} }
void callback_recv_ending ( int32_t call_index, void* arg ) void callback_recv_ending ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onEnding); CB_BODY(call_index, arg, onEnding);
stop_transmission(call_index); stop_transmission(call_index);
} }
void callback_recv_error ( int32_t call_index, void* arg )
{ void callback_call_started ( void* av, int32_t call_index, void* arg )
CB_BODY(call_index, arg, onError);
stop_transmission(call_index);
}
void callback_call_started ( int32_t call_index, void* arg )
{ {
ToxWindow* windows = arg; ToxWindow* windows = arg;
int i; int i;
@ -284,28 +281,28 @@ void callback_call_started ( int32_t call_index, void* arg )
} }
} }
} }
void callback_call_canceled ( int32_t call_index, void* arg ) void callback_call_canceled ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onCancel); CB_BODY(call_index, arg, onCancel);
/* In case call is active */ /* In case call is active */
stop_transmission(call_index); stop_transmission(call_index);
} }
void callback_call_rejected ( int32_t call_index, void* arg ) void callback_call_rejected ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onReject); CB_BODY(call_index, arg, onReject);
} }
void callback_call_ended ( int32_t call_index, void* arg ) void callback_call_ended ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onEnd); CB_BODY(call_index, arg, onEnd);
stop_transmission(call_index); stop_transmission(call_index);
} }
void callback_requ_timeout ( int32_t call_index, void* arg ) void callback_requ_timeout ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onRequestTimeout); CB_BODY(call_index, arg, onRequestTimeout);
} }
void callback_peer_timeout ( int32_t call_index, void* arg ) void callback_peer_timeout ( void* av, int32_t call_index, void* arg )
{ {
CB_BODY(call_index, arg, onPeerTimeout); CB_BODY(call_index, arg, onPeerTimeout);
stop_transmission(call_index); stop_transmission(call_index);
@ -314,6 +311,10 @@ void callback_peer_timeout ( int32_t call_index, void* arg )
*/ */
toxav_stop_call(ASettins.av, call_index); toxav_stop_call(ASettins.av, call_index);
} }
void callback_media_change(void* av, int32_t call_index, void* arg)
{
/*... TODO cancel all media change requests */
}
/* /*
* End of Callbacks * End of Callbacks
*/ */
@ -476,6 +477,10 @@ void cmd_cancel(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
goto on_error; goto on_error;
} }
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
/* Callback will print status... */ /* Callback will print status... */
return; return;

View File

@ -42,10 +42,12 @@
#include "input.h" #include "input.h"
#include "help.h" #include "help.h"
#include "autocomplete.h" #include "autocomplete.h"
#include "notify.h"
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#include "audio_call.h" #include "audio_call.h"
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
extern char *DATA_FILE; extern char *DATA_FILE;
@ -53,18 +55,18 @@ extern FileSender file_senders[MAX_FILES];
extern ToxicFriend friends[MAX_FRIENDS_NUM]; extern ToxicFriend friends[MAX_FRIENDS_NUM];
extern struct _Winthread Winthread; extern struct _Winthread Winthread;
extern struct user_settings *user_settings; extern struct user_settings *user_settings_;
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
static void init_infobox(ToxWindow *self); static void init_infobox(ToxWindow *self);
static void kill_infobox(ToxWindow *self); static void kill_infobox(ToxWindow *self);
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#define AC_NUM_CHAT_COMMANDS 26 #define AC_NUM_CHAT_COMMANDS 26
#else #else
#define AC_NUM_CHAT_COMMANDS 18 #define AC_NUM_CHAT_COMMANDS 18
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
/* Array of chat command names used for tab completion. */ /* Array of chat command names used for tab completion. */
static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = { static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
@ -87,7 +89,7 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/sendfile" }, { "/sendfile" },
{ "/status" }, { "/status" },
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
{ "/call" }, { "/call" },
{ "/cancel" }, { "/cancel" },
@ -98,7 +100,7 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/mute" }, { "/mute" },
{ "/sense" }, { "/sense" },
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
}; };
static void set_typingstatus(ToxWindow *self, Tox *m, uint8_t is_typing) static void set_typingstatus(ToxWindow *self, Tox *m, uint8_t is_typing)
@ -127,7 +129,7 @@ void kill_chat_window(ToxWindow *self)
log_disable(ctx->log); log_disable(ctx->log);
line_info_cleanup(ctx->hst); line_info_cleanup(ctx->hst);
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
stop_current_call(self); stop_current_call(self);
#endif #endif
@ -160,7 +162,8 @@ static void chat_onMessage(ToxWindow *self, Tox *m, int32_t num, const char *msg
line_info_add(self, timefrmt, nick, NULL, msg, IN_MSG, 0, 0); line_info_add(self, timefrmt, nick, NULL, msg, IN_MSG, 0, 0);
write_to_log(msg, nick, ctx->log, false); write_to_log(msg, nick, ctx->log, false);
alert_window(self, WINDOW_ALERT_1, true);
notify(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS);
} }
static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status) static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_t status)
@ -170,12 +173,14 @@ static void chat_onConnectionChange(ToxWindow *self, Tox *m, int32_t num, uint8_
StatusBar *statusbar = self->stb; StatusBar *statusbar = self->stb;
if (status == 1) { if (status == 1) { /* Friend shows online */
statusbar->is_online = true; statusbar->is_online = true;
friends[num].is_typing = tox_get_is_typing(m, num); friends[num].is_typing = tox_get_is_typing(m, num);
} else { notify(self, user_log_in, NT_NOFOCUS);
} else { /* Friend goes offline */
statusbar->is_online = false; statusbar->is_online = false;
friends[num].is_typing = 0; friends[num].is_typing = 0;
notify(self, user_log_out, NT_NOFOCUS);
} }
} }
@ -202,7 +207,7 @@ static void chat_onAction(ToxWindow *self, Tox *m, int32_t num, const char *acti
line_info_add(self, timefrmt, nick, NULL, action, ACTION, 0, 0); line_info_add(self, timefrmt, nick, NULL, action, ACTION, 0, 0);
write_to_log(action, nick, ctx->log, true); write_to_log(action, nick, ctx->log, true);
alert_window(self, WINDOW_ALERT_1, true); notify(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS);
} }
static void chat_onNickChange(ToxWindow *self, Tox *m, int32_t num, const char *nick, uint16_t len) static void chat_onNickChange(ToxWindow *self, Tox *m, int32_t num, const char *nick, uint16_t len)
@ -272,9 +277,9 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
} }
/* use specified path in config if possible */ /* use specified path in config if possible */
if (user_settings->download_path[0]) { if (user_settings_->download_path[0]) {
snprintf(filename_path, sizeof(filename_path), "%s%s", user_settings->download_path, filename_nopath); snprintf(filename_path, sizeof(filename_path), "%s%s", user_settings_->download_path, filename_nopath);
len += strlen(user_settings->download_path); len += strlen(user_settings_->download_path);
} }
if (len >= sizeof(friends[num].file_receiver.filenames[filenum])) { if (len >= sizeof(friends[num].file_receiver.filenames[filenum])) {
@ -322,7 +327,7 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
friends[num].file_receiver.size[filenum] = filesize; friends[num].file_receiver.size[filenum] = filesize;
strcpy(friends[num].file_receiver.filenames[filenum], filename); strcpy(friends[num].file_receiver.filenames[filenum], filename);
alert_window(self, WINDOW_ALERT_2, true); notify(self, transfer_pending, NT_WNDALERT_2 | NT_NOFOCUS);
} }
static void chat_close_file_receiver(int32_t num, uint8_t filenum) static void chat_close_file_receiver(int32_t num, uint8_t filenum)
@ -361,6 +366,7 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
if (receive_send == 1) { if (receive_send == 1) {
snprintf(msg, sizeof(msg), "File transfer for '%s' accepted (%.1f%%)", filename, 0.0); snprintf(msg, sizeof(msg), "File transfer for '%s' accepted (%.1f%%)", filename, 0.0);
file_senders[i].line_id = self->chatwin->hst->line_end->id + 1; file_senders[i].line_id = self->chatwin->hst->line_end->id + 1;
notify(self, silent, NT_NOFOCUS | NT_BEEP | NT_WNDALERT_2);
} }
break; break;
@ -371,19 +377,20 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
if (receive_send == 0) if (receive_send == 0)
chat_close_file_receiver(num, filenum); chat_close_file_receiver(num, filenum);
notify(self, error, NT_NOFOCUS | NT_WNDALERT_2);
break; break;
case TOX_FILECONTROL_FINISHED: case TOX_FILECONTROL_FINISHED:
if (receive_send == 0) { if (receive_send == 0) {
snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename); snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename);
chat_close_file_receiver(num, filenum); chat_close_file_receiver(num, filenum);
notify(self, transfer_completed, NT_NOFOCUS | NT_WNDALERT_2);
} }
break; break;
} }
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
alert_window(self, WINDOW_ALERT_2, true);
} }
static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, const char *data, static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, const char *data,
@ -436,11 +443,12 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, co
sizeof(friends[friendnumber].groupchat_key)); sizeof(friends[friendnumber].groupchat_key));
friends[friendnumber].groupchat_pending = true; friends[friendnumber].groupchat_pending = true;
alert_window(self, WINDOW_ALERT_2, true);
notify(self, generic_message, NT_WNDALERT_2);
} }
/* Av Stuff */ /* Av Stuff */
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
void chat_onInvite (ToxWindow *self, ToxAv *av, int call_index) void chat_onInvite (ToxWindow *self, ToxAv *av, int call_index)
{ {
@ -451,7 +459,11 @@ void chat_onInvite (ToxWindow *self, ToxAv *av, int call_index)
self->call_idx = call_index; self->call_idx = call_index;
line_info_add(self, NULL, NULL, NULL, "Incoming audio call! Type: \"/answer\" or \"/reject\"", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Incoming audio call! Type: \"/answer\" or \"/reject\"", SYS_MSG, 0, 0);
alert_window(self, WINDOW_ALERT_0, true);
#ifdef _SOUND_NOTIFY
if (self->active_sound == -1)
self->active_sound = notify(self, call_incoming, NT_LOOP | NT_WNDALERT_0);
#endif /* _SOUND_NOTIFY */
} }
void chat_onRinging (ToxWindow *self, ToxAv *av, int call_index) void chat_onRinging (ToxWindow *self, ToxAv *av, int call_index)
@ -460,6 +472,11 @@ void chat_onRinging (ToxWindow *self, ToxAv *av, int call_index)
return; return;
line_info_add(self, NULL, NULL, NULL, "Ringing...\"cancel\" ?", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Ringing...\"cancel\" ?", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
if (self->active_sound == -1)
self->active_sound = notify(self, call_outgoing, NT_LOOP);
#endif /* _SOUND_NOTIFY */
} }
void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index) void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index)
@ -470,6 +487,11 @@ void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index)
init_infobox(self); init_infobox(self);
line_info_add(self, NULL, NULL, NULL, "Call started! Type: \"/hangup\" to end it.", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Call started! Type: \"/hangup\" to end it.", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index) void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index)
@ -480,6 +502,11 @@ void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index)
kill_infobox(self); kill_infobox(self);
self->call_idx = -1; self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onError (ToxWindow *self, ToxAv *av, int call_index) void chat_onError (ToxWindow *self, ToxAv *av, int call_index)
@ -489,6 +516,11 @@ void chat_onError (ToxWindow *self, ToxAv *av, int call_index)
self->call_idx = -1; self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Error!", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Error!", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onStart (ToxWindow *self, ToxAv *av, int call_index) void chat_onStart (ToxWindow *self, ToxAv *av, int call_index)
@ -499,6 +531,11 @@ void chat_onStart (ToxWindow *self, ToxAv *av, int call_index)
init_infobox(self); init_infobox(self);
line_info_add(self, NULL, NULL, NULL, "Call started! Type: \"/hangup\" to end it.", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Call started! Type: \"/hangup\" to end it.", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index) void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index)
@ -509,6 +546,11 @@ void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index)
kill_infobox(self); kill_infobox(self);
self->call_idx = -1; self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Call canceled!", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Call canceled!", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onReject (ToxWindow *self, ToxAv *av, int call_index) void chat_onReject (ToxWindow *self, ToxAv *av, int call_index)
@ -518,6 +560,11 @@ void chat_onReject (ToxWindow *self, ToxAv *av, int call_index)
self->call_idx = -1; self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Rejected!", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Rejected!", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index) void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index)
@ -528,6 +575,11 @@ void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index)
kill_infobox(self); kill_infobox(self);
self->call_idx = -1; self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onRequestTimeout (ToxWindow *self, ToxAv *av, int call_index) void chat_onRequestTimeout (ToxWindow *self, ToxAv *av, int call_index)
@ -537,6 +589,11 @@ void chat_onRequestTimeout (ToxWindow *self, ToxAv *av, int call_index)
self->call_idx = -1; self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "No answer!", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "No answer!", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index) void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index)
@ -547,6 +604,11 @@ void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index)
kill_infobox(self); kill_infobox(self);
self->call_idx = -1; self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Peer disconnected; call ended!", SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, "Peer disconnected; call ended!", SYS_MSG, 0, 0);
#ifdef _SOUND_NOTIFY
stop_sound(self->active_sound);
self->active_sound = -1;
#endif /* _SOUND_NOTIFY */
} }
static void init_infobox(ToxWindow *self) static void init_infobox(ToxWindow *self)
@ -631,7 +693,7 @@ static void draw_infobox(ToxWindow *self)
wrefresh(infobox->win); wrefresh(infobox->win);
} }
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action) static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action)
{ {
@ -702,7 +764,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1; ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
} }
} else { } else {
beep(); notify(self, error, 0);
} }
} else if (key == '\n') { } else if (key == '\n') {
@ -860,7 +922,7 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wrefresh(self->window); wrefresh(self->window);
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
if (ctx->infobox.active) { if (ctx->infobox.active) {
draw_infobox(self); draw_infobox(self);
wrefresh(self->window); wrefresh(self->window);
@ -942,7 +1004,7 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
ret.onFileControl = &chat_onFileControl; ret.onFileControl = &chat_onFileControl;
ret.onFileData = &chat_onFileData; ret.onFileData = &chat_onFileData;
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
ret.onInvite = &chat_onInvite; ret.onInvite = &chat_onInvite;
ret.onRinging = &chat_onRinging; ret.onRinging = &chat_onRinging;
ret.onStarting = &chat_onStarting; ret.onStarting = &chat_onStarting;
@ -957,7 +1019,11 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
ret.call_idx = -1; ret.call_idx = -1;
ret.device_selection[0] = ret.device_selection[1] = -1; ret.device_selection[0] = ret.device_selection[1] = -1;
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#ifdef _SOUND_NOTIFY
ret.active_sound = -1;
#endif /* _SOUND_NOTIFY */
char nick[TOX_MAX_NAME_LENGTH]; char nick[TOX_MAX_NAME_LENGTH];
int n_len = get_nick_truncate(m, nick, friendnum); int n_len = get_nick_truncate(m, nick, friendnum);

View File

@ -31,7 +31,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_savefile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_sendfile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_sendfile(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
void cmd_call(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); 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_answer(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_reject(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_reject(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
@ -40,6 +40,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_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_mute(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_sense(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_sense(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#endif /* #define _chat_commands_h */ #endif /* #define _chat_commands_h */

View File

@ -66,7 +66,9 @@ static int size[2]; /* Size of above containers */
Device *running[2][MAX_DEVICES]; /* Running devices */ Device *running[2][MAX_DEVICES]; /* Running devices */
uint32_t primary_device[2]; /* Primary device */ uint32_t primary_device[2]; /* Primary device */
#ifdef _AUDIO
static ToxAv* av = NULL; static ToxAv* av = NULL;
#endif /* _AUDIO */
/* q_mutex */ /* q_mutex */
#define lock pthread_mutex_lock(&mutex) #define lock pthread_mutex_lock(&mutex)
@ -79,7 +81,11 @@ _Bool thread_running = _True,
void* thread_poll(void*); void* thread_poll(void*);
/* Meet devices */ /* Meet devices */
#ifdef _AUDIO
DeviceError init_devices(ToxAv* av_) DeviceError init_devices(ToxAv* av_)
#else
DeviceError init_devices()
#endif /* _AUDIO */
{ {
const char *stringed_device_list; const char *stringed_device_list;
@ -115,7 +121,9 @@ DeviceError init_devices(ToxAv* av_)
if ( pthread_create(&thread_id, NULL, thread_poll, NULL) != 0 || pthread_detach(thread_id) != 0) if ( pthread_create(&thread_id, NULL, thread_poll, NULL) != 0 || pthread_detach(thread_id) != 0)
return de_InternalError; return de_InternalError;
#ifdef _AUDIO
av = av_; av = av_;
#endif /* _AUDIO */
return (DeviceError) ae_None; return (DeviceError) ae_None;
} }
@ -391,8 +399,11 @@ void* thread_poll (void* arg) // TODO: maybe use thread for every input source
int16_t frame[4096]; int16_t frame[4096];
alcCaptureSamples(device->dhndl, frame, f_size); alcCaptureSamples(device->dhndl, frame, f_size);
if ( device->muted || if ( device->muted
(device->enable_VAD && !toxav_has_activity(av, device->call_idx, frame, f_size, device->VAD_treshold))) #ifdef _AUDIO
|| (device->enable_VAD && !toxav_has_activity(av, device->call_idx, frame, f_size, device->VAD_treshold))
#endif /* _AUDIO */
)
{ unlock; continue; } /* Skip if no voice activity */ { unlock; continue; } /* Skip if no voice activity */
if ( device->cb ) device->cb(frame, f_size, device->cb_data); if ( device->cb ) device->cb(frame, f_size, device->cb_data);

View File

@ -56,7 +56,12 @@ typedef enum DeviceError {
typedef void (*DataHandleCallback) (const int16_t*, uint32_t size, void* data); typedef void (*DataHandleCallback) (const int16_t*, uint32_t size, void* data);
#ifdef _AUDIO
DeviceError init_devices(ToxAv* av); DeviceError init_devices(ToxAv* av);
#else
DeviceError init_devices();
#endif /* _AUDIO */
DeviceError terminate_devices(); DeviceError terminate_devices();
/* Callback handles ready data from INPUT device */ /* Callback handles ready data from INPUT device */

View File

@ -31,6 +31,7 @@
#include "global_commands.h" #include "global_commands.h"
#include "line_info.h" #include "line_info.h"
#include "misc_tools.h" #include "misc_tools.h"
#include "notify.h"
struct cmd_func { struct cmd_func {
const char *name; const char *name;
@ -53,10 +54,10 @@ static struct cmd_func global_commands[] = {
{ "/quit", cmd_quit }, { "/quit", cmd_quit },
{ "/status", cmd_status }, { "/status", cmd_status },
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
{ "/lsdev", cmd_list_devices }, { "/lsdev", cmd_list_devices },
{ "/sdev", cmd_change_device }, { "/sdev", cmd_change_device },
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
}; };
static struct cmd_func chat_commands[] = { static struct cmd_func chat_commands[] = {
@ -65,7 +66,7 @@ static struct cmd_func chat_commands[] = {
{ "/savefile", cmd_savefile }, { "/savefile", cmd_savefile },
{ "/sendfile", cmd_sendfile }, { "/sendfile", cmd_sendfile },
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
{ "/call", cmd_call }, { "/call", cmd_call },
{ "/cancel", cmd_cancel }, { "/cancel", cmd_cancel },
{ "/answer", cmd_answer }, { "/answer", cmd_answer },
@ -74,7 +75,7 @@ static struct cmd_func chat_commands[] = {
{ "/sdev", cmd_ccur_device }, { "/sdev", cmd_ccur_device },
{ "/mute", cmd_mute }, { "/mute", cmd_mute },
{ "/sense", cmd_sense }, { "/sense", cmd_sense },
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
}; };
/* Parses input command and puts args into arg array. /* Parses input command and puts args into arg array.
@ -165,5 +166,7 @@ void execute(WINDOW *w, ToxWindow *self, Tox *m, const char *input, int mode)
if (do_command(w, self, m, num_args, GLOBAL_NUM_COMMANDS, global_commands, args) == 0) if (do_command(w, self, m, num_args, GLOBAL_NUM_COMMANDS, global_commands, args) == 0)
return; return;
line_info_add(self, NULL, NULL, NULL, "Invalid command.", SYS_MSG, 0, 0); /* Just play sound instead */
/*line_info_add(self, NULL, NULL, NULL, "Invalid command.", SYS_MSG, 0, 0);*/
notify(self, error, 0);
} }

View File

@ -28,13 +28,13 @@
#define MAX_NUM_ARGS 4 /* Includes command */ #define MAX_NUM_ARGS 4 /* Includes command */
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#define GLOBAL_NUM_COMMANDS 16 #define GLOBAL_NUM_COMMANDS 16
#define CHAT_NUM_COMMANDS 12 #define CHAT_NUM_COMMANDS 12
#else #else
#define GLOBAL_NUM_COMMANDS 14 #define GLOBAL_NUM_COMMANDS 14
#define CHAT_NUM_COMMANDS 4 #define CHAT_NUM_COMMANDS 4
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
enum { enum {
GLOBAL_COMMAND_MODE, GLOBAL_COMMAND_MODE,

View File

@ -30,6 +30,7 @@
#include "file_senders.h" #include "file_senders.h"
#include "line_info.h" #include "line_info.h"
#include "misc_tools.h" #include "misc_tools.h"
#include "notify.h"
FileSender file_senders[MAX_FILES]; FileSender file_senders[MAX_FILES];
uint8_t max_file_senders_index; uint8_t max_file_senders_index;
@ -48,10 +49,9 @@ static void set_max_file_senders_index(void)
static void close_file_sender(ToxWindow *self, Tox *m, int i, char *msg, int CTRL, int filenum, int32_t friendnum) static void close_file_sender(ToxWindow *self, Tox *m, int i, char *msg, int CTRL, int filenum, int32_t friendnum)
{ {
if (self->chatwin != NULL) { if (self->chatwin != NULL)
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
alert_window(file_senders[i].toxwin, WINDOW_ALERT_2, true);
}
tox_file_send_control(m, friendnum, 0, filenum, CTRL, 0, 0); tox_file_send_control(m, friendnum, 0, filenum, CTRL, 0, 0);
fclose(file_senders[i].file); fclose(file_senders[i].file);
@ -94,6 +94,7 @@ void do_file_senders(Tox *m)
if (timed_out(file_senders[i].timestamp, get_unix_time(), TIMEOUT_FILESENDER)) { if (timed_out(file_senders[i].timestamp, get_unix_time(), TIMEOUT_FILESENDER)) {
snprintf(msg, sizeof(msg), "File transfer for '%s' timed out.", pathname); snprintf(msg, sizeof(msg), "File transfer for '%s' timed out.", pathname);
close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, friendnum); close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, friendnum);
notify(self, error, NT_NOFOCUS | NT_WNDALERT_2);
continue; continue;
} }
@ -122,6 +123,7 @@ void do_file_senders(Tox *m)
if (file_senders[i].piecelen == 0) { if (file_senders[i].piecelen == 0) {
snprintf(msg, sizeof(msg), "File '%s' successfuly sent.", pathname); snprintf(msg, sizeof(msg), "File '%s' successfuly sent.", pathname);
close_file_sender(self, m, i, msg, TOX_FILECONTROL_FINISHED, filenum, friendnum); close_file_sender(self, m, i, msg, TOX_FILECONTROL_FINISHED, filenum, friendnum);
notify(self, transfer_completed, NT_NOFOCUS | NT_WNDALERT_2);
break; break;
} }
} }

View File

@ -34,11 +34,13 @@
#include "misc_tools.h" #include "misc_tools.h"
#include "line_info.h" #include "line_info.h"
#include "settings.h" #include "settings.h"
#include "notify.h"
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#include "audio_call.h" #include "audio_call.h"
#endif #endif
extern char *DATA_FILE; extern char *DATA_FILE;
extern ToxWindow *prompt; extern ToxWindow *prompt;
@ -47,7 +49,7 @@ static int num_selected = 0;
static int num_friends = 0; static int num_friends = 0;
extern struct _Winthread Winthread; extern struct _Winthread Winthread;
extern struct user_settings *user_settings; extern struct user_settings *user_settings_;
ToxicFriend friends[MAX_FRIENDS_NUM]; ToxicFriend friends[MAX_FRIENDS_NUM];
static int friendlist_index[MAX_FRIENDS_NUM] = {0}; static int friendlist_index[MAX_FRIENDS_NUM] = {0};
@ -91,7 +93,7 @@ static void update_friend_last_online(int32_t num, uint64_t timestamp)
friends[num].last_online.tm = *localtime((const time_t*)&timestamp); friends[num].last_online.tm = *localtime((const time_t*)&timestamp);
/* if the format changes make sure TIME_STR_SIZE is the correct size */ /* 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[num].last_online.hour_min_str, TIME_STR_SIZE, t, strftime(friends[num].last_online.hour_min_str, TIME_STR_SIZE, t,
&friends[num].last_online.tm); &friends[num].last_online.tm);
} }
@ -104,6 +106,7 @@ static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, const cha
if (friends[num].chatwin == -1) { if (friends[num].chatwin == -1) {
if (get_num_active_windows() < MAX_WINDOWS_NUM) { if (get_num_active_windows() < MAX_WINDOWS_NUM) {
friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); friends[num].chatwin = add_window(m, new_chat(m, friends[num].num));
notify(self, generic_message, NT_NOFOCUS);
} else { } else {
char nick[TOX_MAX_NAME_LENGTH]; char nick[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, nick, num); get_nick_truncate(m, nick, num);
@ -115,7 +118,7 @@ static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, const cha
char *msg = "* Warning: Too many windows are open."; char *msg = "* Warning: Too many windows are open.";
line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED);
alert_window(prompt, WINDOW_ALERT_1, true); notify(prompt, error, NT_WNDALERT_1);
} }
} }
} }
@ -126,6 +129,7 @@ static void friendlist_onConnectionChange(ToxWindow *self, Tox *m, int32_t num,
return; return;
friends[num].online = status; friends[num].online = status;
notify(self, status==1 ? user_log_in : user_log_out, NT_RESTOL | NT_NOTIFWND );
update_friend_last_online(num, get_unix_time()); update_friend_last_online(num, get_unix_time());
store_data(m, DATA_FILE); store_data(m, DATA_FILE);
sort_friendlist_index(); sort_friendlist_index();
@ -176,7 +180,7 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort)
friends[i].chatwin = -1; friends[i].chatwin = -1;
friends[i].online = false; friends[i].online = false;
friends[i].status = TOX_USERSTATUS_NONE; friends[i].status = TOX_USERSTATUS_NONE;
friends[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON; friends[i].logging_on = (bool) user_settings_->autolog == AUTOLOG_ON;
tox_get_client_id(m, num, (uint8_t *) friends[i].pub_key); tox_get_client_id(m, num, (uint8_t *) friends[i].pub_key);
update_friend_last_online(i, tox_get_last_online(m, i)); update_friend_last_online(i, tox_get_last_online(m, i));
@ -213,6 +217,7 @@ static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, u
if (friends[num].chatwin == -1) { if (friends[num].chatwin == -1) {
if (get_num_active_windows() < MAX_WINDOWS_NUM) { if (get_num_active_windows() < MAX_WINDOWS_NUM) {
friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); friends[num].chatwin = add_window(m, new_chat(m, friends[num].num));
notify(self, transfer_pending, NT_NOFOCUS);
} else { } else {
tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0); tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0);
@ -223,7 +228,7 @@ static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, u
snprintf(msg, sizeof(msg), "* File transfer from %s failed: too many windows are open.", nick); snprintf(msg, sizeof(msg), "* File transfer from %s failed: too many windows are open.", nick);
line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED);
alert_window(prompt, WINDOW_ALERT_1, true); notify(prompt, error, NT_WNDALERT_1);
} }
} }
} }
@ -236,6 +241,8 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const
if (friends[num].chatwin == -1) { if (friends[num].chatwin == -1) {
if (get_num_active_windows() < MAX_WINDOWS_NUM) { if (get_num_active_windows() < MAX_WINDOWS_NUM) {
friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); friends[num].chatwin = add_window(m, new_chat(m, friends[num].num));
notify(self, generic_message, NT_NOFOCUS);
} else { } else {
char nick[TOX_MAX_NAME_LENGTH]; char nick[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, nick, num); get_nick_truncate(m, nick, num);
@ -244,7 +251,7 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const
snprintf(msg, sizeof(msg), "* Group chat invite from %s failed: too many windows are open.", nick); snprintf(msg, sizeof(msg), "* Group chat invite from %s failed: too many windows are open.", nick);
line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED);
alert_window(prompt, WINDOW_ALERT_1, true); notify(prompt, error, NT_WNDALERT_1);
} }
} }
} }
@ -348,7 +355,7 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
char *msg = "* Warning: Too many windows are open."; char *msg = "* Warning: Too many windows are open.";
line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED);
alert_window(prompt, WINDOW_ALERT_1, true); notify(prompt, error, NT_WNDALERT_1);
} }
} else if (key == KEY_DC) { } else if (key == KEY_DC) {
del_friend_activate(self, m, f); del_friend_activate(self, m, f);
@ -545,7 +552,7 @@ void disable_chatwin(int32_t f_num)
friends[f_num].chatwin = -1; friends[f_num].chatwin = -1;
} }
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index) static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index)
{ {
int id = toxav_get_peer_id(av, call_index, 0); int id = toxav_get_peer_id(av, call_index, 0);
@ -558,8 +565,9 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index)
if (friends[id].chatwin == -1) { if (friends[id].chatwin == -1) {
if (get_num_active_windows() < MAX_WINDOWS_NUM) { if (get_num_active_windows() < MAX_WINDOWS_NUM) {
if (toxav_get_call_state(av, call_index) == av_CallStarting) /* Only open windows when call is incoming */ if (toxav_get_call_state(av, call_index) == av_CallStarting) { /* Only open windows when call is incoming */
friends[id].chatwin = add_window(m, new_chat(m, friends[id].num)); friends[id].chatwin = add_window(m, new_chat(m, friends[id].num));
}
} else { } else {
char nick[TOX_MAX_NAME_LENGTH]; char nick[TOX_MAX_NAME_LENGTH];
get_nick_truncate(m, nick, friends[id].num); get_nick_truncate(m, nick, friends[id].num);
@ -571,11 +579,11 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index)
char *errmsg = "* Warning: Too many windows are open."; char *errmsg = "* Warning: Too many windows are open.";
line_info_add(prompt, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED); line_info_add(prompt, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED);
alert_window(prompt, WINDOW_ALERT_0, true); notify(prompt, error, NT_WNDALERT_1);
} }
} }
} }
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
ToxWindow new_friendlist(void) ToxWindow new_friendlist(void)
{ {
@ -597,7 +605,7 @@ ToxWindow new_friendlist(void)
ret.onFileSendRequest = &friendlist_onFileSendRequest; ret.onFileSendRequest = &friendlist_onFileSendRequest;
ret.onGroupInvite = &friendlist_onGroupInvite; ret.onGroupInvite = &friendlist_onGroupInvite;
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
ret.onInvite = &friendlist_onAv; ret.onInvite = &friendlist_onAv;
ret.onRinging = &friendlist_onAv; ret.onRinging = &friendlist_onAv;
ret.onStarting = &friendlist_onAv; ret.onStarting = &friendlist_onAv;
@ -612,7 +620,11 @@ ToxWindow new_friendlist(void)
ret.call_idx = -1; ret.call_idx = -1;
ret.device_selection[0] = ret.device_selection[1] = -1; ret.device_selection[0] = ret.device_selection[1] = -1;
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#ifdef _SOUND_NOTIFY
ret.active_sound = -1;
#endif /* _SOUND_NOTIFY */
strcpy(ret.name, "contacts"); strcpy(ret.name, "contacts");
return ret; return ret;

View File

@ -41,9 +41,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); void cmd_add_helper(ToxWindow *self, Tox *m, char *id_bin, char *msg);
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
void cmd_list_devices(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]); 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]); void cmd_change_device(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#endif /* #define _global_commands_h */ #endif /* #define _global_commands_h */

View File

@ -41,6 +41,7 @@
#include "settings.h" #include "settings.h"
#include "input.h" #include "input.h"
#include "help.h" #include "help.h"
#include "notify.h"
#include "autocomplete.h" #include "autocomplete.h"
extern char *DATA_FILE; extern char *DATA_FILE;
@ -48,7 +49,7 @@ extern char *DATA_FILE;
static GroupChat groupchats[MAX_GROUPCHAT_NUM]; static GroupChat groupchats[MAX_GROUPCHAT_NUM];
static int max_groupchat_index = 0; 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 */ /* temporary until group chats have unique commands */
extern const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE]; extern const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE];
@ -135,25 +136,18 @@ static void groupchat_onGroupMessage(ToxWindow *self, Tox *m, int groupnum, int
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); /* enforce client max name length */ n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); /* enforce client max name length */
nick[n_len] = '\0'; nick[n_len] = '\0';
/* check if message contains own name and alert appropriately */
int alert_type = WINDOW_ALERT_1;
bool beep = false;
char selfnick[TOX_MAX_NAME_LENGTH]; char selfnick[TOX_MAX_NAME_LENGTH];
uint16_t sn_len = tox_get_self_name(m, (uint8_t *) selfnick); uint16_t sn_len = tox_get_self_name(m, (uint8_t *) selfnick);
selfnick[sn_len] = '\0'; selfnick[sn_len] = '\0';
int nick_clr = strcmp(nick, selfnick) == 0 ? GREEN : CYAN; int nick_clr = strcmp(nick, selfnick) == 0 ? GREEN : CYAN;
bool nick_match = strcasestr(msg, selfnick) && strncmp(selfnick, nick, TOXIC_MAX_NAME_LENGTH - 1); /* Only play sound if mentioned */
if (strcasestr(msg, selfnick) && strncmp(selfnick, nick, TOXIC_MAX_NAME_LENGTH - 1)) {
if (nick_match) { notify(self, generic_message, NT_WNDALERT_0);
alert_type = WINDOW_ALERT_0;
beep = true;
nick_clr = RED; nick_clr = RED;
} }
else notify(self, silent, NT_WNDALERT_1);
alert_window(self, alert_type, beep);
char timefrmt[TIME_STR_SIZE]; char timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt, sizeof(timefrmt)); get_time_str(timefrmt, sizeof(timefrmt));
@ -170,22 +164,14 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
/* check if message contains own name and alert appropriately */
int alert_type = WINDOW_ALERT_1;
bool beep = false;
char selfnick[TOX_MAX_NAME_LENGTH]; char selfnick[TOX_MAX_NAME_LENGTH];
uint16_t n_len = tox_get_self_name(m, (uint8_t *) selfnick); uint16_t n_len = tox_get_self_name(m, (uint8_t *) selfnick);
selfnick[n_len] = '\0'; selfnick[n_len] = '\0';
const char *nick_match = strcasestr(action, selfnick); if (strcasestr(action, selfnick)) {
notify(self, generic_message, NT_WNDALERT_0);
if (nick_match) {
alert_type = WINDOW_ALERT_0;
beep = true;
} }
else notify(self, silent, NT_WNDALERT_1);
alert_window(self, alert_type, beep);
char nick[TOX_MAX_NAME_LENGTH]; char nick[TOX_MAX_NAME_LENGTH];
n_len = tox_group_peername(m, groupnum, peernum, (uint8_t *) nick); n_len = tox_group_peername(m, groupnum, peernum, (uint8_t *) nick);
@ -318,7 +304,7 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
break; break;
} }
alert_window(self, WINDOW_ALERT_2, false); notify(self, silent, NT_WNDALERT_2);
} }
static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action) static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, char *action)
@ -501,7 +487,7 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
line_info_init(ctx->hst); line_info_init(ctx->hst);
if (user_settings->autolog == AUTOLOG_ON) if (user_settings_->autolog == AUTOLOG_ON)
log_enable(self->name, NULL, ctx->log); log_enable(self->name, NULL, ctx->log);
execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE);

View File

@ -144,14 +144,14 @@ static void help_draw_global(ToxWindow *self)
wprintw(win, " /close : Close the current chat window\n"); wprintw(win, " /close : Close the current chat window\n");
wprintw(win, " /quit or /exit : Exit Toxic\n"); wprintw(win, " /quit or /exit : Exit Toxic\n");
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
wattron(win, A_BOLD); wattron(win, A_BOLD);
wprintw(win, "\n Audio:\n"); wprintw(win, "\n Audio:\n");
wattroff(win, A_BOLD); wattroff(win, A_BOLD);
wprintw(win, " /lsdev <type> : List devices where type: in|out\n"); wprintw(win, " /lsdev <type> : List devices where type: in|out\n");
wprintw(win, " /sdev <type> <id> : Set active device\n"); wprintw(win, " /sdev <type> <id> : Set active device\n");
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
help_draw_bottom_menu(win); help_draw_bottom_menu(win);
@ -174,7 +174,7 @@ static void help_draw_chat(ToxWindow *self)
wprintw(win, " /sendfile <path> : Send a file\n"); wprintw(win, " /sendfile <path> : Send a file\n");
wprintw(win, " /savefile <n> : Receive a file\n"); wprintw(win, " /savefile <n> : Receive a file\n");
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
wattron(win, A_BOLD); wattron(win, A_BOLD);
wprintw(win, "\n Audio:\n"); wprintw(win, "\n Audio:\n");
wattroff(win, A_BOLD); wattroff(win, A_BOLD);
@ -187,7 +187,7 @@ static void help_draw_chat(ToxWindow *self)
wprintw(win, " /sdev <type> <id> : Change active device\n"); wprintw(win, " /sdev <type> <id> : Change active device\n");
wprintw(win, " /mute <type> : Mute active device if in call\n"); wprintw(win, " /mute <type> : Mute active device if in call\n");
wprintw(win, " /sense <n> : VAD sensitivity treshold\n"); wprintw(win, " /sense <n> : VAD sensitivity treshold\n");
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
help_draw_bottom_menu(win); help_draw_bottom_menu(win);
@ -226,7 +226,7 @@ void help_onKey(ToxWindow *self, wint_t key)
break; break;
case 'c': case 'c':
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
help_init_window(self, 19, 80); help_init_window(self, 19, 80);
#else #else
help_init_window(self, 9, 80); help_init_window(self, 9, 80);
@ -235,7 +235,7 @@ void help_onKey(ToxWindow *self, wint_t key)
break; break;
case 'g': case 'g':
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
help_init_window(self, 21, 80); help_init_window(self, 21, 80);
#else #else
help_init_window(self, 17, 80); help_init_window(self, 17, 80);

View File

@ -30,7 +30,7 @@
#include "groupchat.h" #include "groupchat.h"
#include "settings.h" #include "settings.h"
extern struct user_settings *user_settings; extern struct user_settings *user_settings_;
void line_info_init(struct history *hst) void line_info_init(struct history *hst)
{ {
@ -207,7 +207,7 @@ static void line_info_check_queue(ToxWindow *self)
if (line == NULL) if (line == NULL)
return; return;
if (hst->start_id > user_settings->history_size) if (hst->start_id > user_settings_->history_size)
line_info_root_fwd(hst); line_info_root_fwd(hst);
line->id = hst->line_end->id + 1; line->id = hst->line_end->id + 1;

View File

@ -31,7 +31,7 @@
#include "log.h" #include "log.h"
#include "settings.h" #include "settings.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 */ /* Creates/fetches log file by appending to the config dir the name and a pseudo-unique identity */
void init_logging_session(char *name, char *key, struct chatlog *log) void init_logging_session(char *name, char *key, struct chatlog *log)
@ -99,7 +99,7 @@ void write_to_log(const char *msg, char *name, struct chatlog *log, bool event)
else else
snprintf(name_frmt, sizeof(name_frmt), "%s:", name); 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]; char s[MAX_STR_SIZE];
strftime(s, MAX_STR_SIZE, t, get_time()); strftime(s, MAX_STR_SIZE, t, get_time());
fprintf(log->file, "%s %s %s\n", s, name_frmt, msg); fprintf(log->file, "%s %s %s\n", s, name_frmt, msg);

View File

@ -33,7 +33,7 @@
#include "settings.h" #include "settings.h"
extern ToxWindow *prompt; extern ToxWindow *prompt;
extern struct user_settings *user_settings; extern struct user_settings *user_settings_;
static uint64_t current_unix_time; static uint64_t current_unix_time;
@ -65,12 +65,12 @@ struct tm *get_time(void)
/*Puts the current time in buf in the format of [HH:mm:ss] */ /*Puts the current time in buf in the format of [HH:mm:ss] */
void get_time_str(char *buf, int bufsize) void get_time_str(char *buf, int bufsize)
{ {
if (user_settings->timestamps == TIMESTAMPS_OFF) { if (user_settings_->timestamps == TIMESTAMPS_OFF) {
buf[0] = '\0'; buf[0] = '\0';
return; 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()); strftime(buf, bufsize, t, get_time());
} }
@ -142,29 +142,6 @@ int wcs_to_mbs_buf(char *buf, const wchar_t *string, size_t n)
return len; return len;
} }
/* Colours the window tab according to type. Beeps if is_beep is true */
void alert_window(ToxWindow *self, int type, bool is_beep)
{
switch (type) {
case WINDOW_ALERT_0:
self->alert0 = true;
break;
case WINDOW_ALERT_1:
self->alert1 = true;
break;
case WINDOW_ALERT_2:
self->alert2 = true;
break;
}
StatusBar *stb = prompt->stb;
if (is_beep && stb->status != TOX_USERSTATUS_BUSY && user_settings->alerts == ALERTS_ENABLED)
beep();
}
/* case-insensitive string compare function for use with qsort */ /* case-insensitive string compare function for use with qsort */
int qsort_strcasecmp_hlpr(const void *nick1, const void *nick2) int qsort_strcasecmp_hlpr(const void *nick1, const void *nick2)
{ {

333
src/notify.c Normal file
View File

@ -0,0 +1,333 @@
/* notify.c
*
*
* Copyright (C) 2014 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Toxic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "notify.h"
#include "device.h"
#include "settings.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#ifdef _SOUND_NOTIFY
#include <OpenAL/alut.h> /* Is this good? */
#endif
#else
#include <AL/al.h>
#include <AL/alc.h>
#ifdef _SOUND_NOTIFY
#include <AL/alut.h> /* freealut packet */
#endif
#endif
#ifdef _X11
#include <X11/Xlib.h>
#endif /* _X11 */
#define SOUNDS_SIZE 10
#define ACTIVE_SOUNDS_MAX 50
extern struct user_settings *user_settings_;
struct _Control {
time_t cooldown;
unsigned long this_window;
#ifdef _X11
Display *display;
#endif /* _X11 */
#ifdef _SOUND_NOTIFY
pthread_mutex_t poll_mutex[1];
uint32_t device_idx; /* index of output device */
_Bool poll_active;
char* sounds[SOUNDS_SIZE];
#endif /* _SOUND_NOTIFY */
} Control = {0};
#ifdef _SOUND_NOTIFY
struct _ActiveSounds {
uint32_t source;
uint32_t buffer;
_Bool active;
_Bool looping;
} actives[ACTIVE_SOUNDS_MAX] = {0};
#endif
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
long unsigned int get_focused_window_id()
{
#ifdef _X11
if (!Control.display) return 0;
Window focus;
int revert;
XGetInputFocus(Control.display, &focus, &revert);
return focus;
#else
return 0;
#endif /* _X11 */
}
#ifdef _SOUND_NOTIFY
_Bool is_playing(int source)
{
int ready;
alGetSourcei(source, AL_SOURCE_STATE, &ready);
return ready == AL_PLAYING;
}
/* Terminate all sounds but wait them to finish first */
void graceful_clear()
{
int i;
pthread_mutex_lock(Control.poll_mutex);
while (1) {
for (i = 0; i < ACTIVE_SOUNDS_MAX; i ++) {
if (actives[i].active) {
if ( actives[i].looping ) {
stop_sound(i);
} else {
if (!is_playing(actives[i].source))
memset(&actives[i], 0, sizeof(struct _ActiveSounds));
else break;
}
}
}
if (i == ACTIVE_SOUNDS_MAX) {
pthread_mutex_unlock(Control.poll_mutex);
return;
}
usleep(1000);
}
}
void* do_playing(void* _p)
{
(void)_p;
int i;
while(Control.poll_active) {
pthread_mutex_lock(Control.poll_mutex);
for (i = 0; i < ACTIVE_SOUNDS_MAX; i ++) {
if (actives[i].active && !actives[i].looping) {
if (!is_playing(actives[i].source)) {
/* Close */
alSourceStop(actives[i].source);
alDeleteSources(1, &actives[i].source);
alDeleteBuffers(1,&actives[i].buffer);
memset(&actives[i], 0, sizeof(struct _ActiveSounds));
}
}
}
pthread_mutex_unlock(Control.poll_mutex);
usleep(10000);
}
}
int play_source(uint32_t source, uint32_t buffer, _Bool looping)
{
pthread_mutex_lock(Control.poll_mutex);
int i = 0;
for (; i < ACTIVE_SOUNDS_MAX && actives[i].active; i ++);
if ( i == ACTIVE_SOUNDS_MAX ) {
pthread_mutex_unlock(Control.poll_mutex);
return -1; /* Full */
}
alSourcePlay(source);
actives[i].active = 1;
actives[i].source = source;
actives[i].buffer = buffer;
actives[i].looping = looping;
pthread_mutex_unlock(Control.poll_mutex);
return i;
}
#endif
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/* Opens primary device */
int init_notify(int login_cooldown)
{
#ifdef _SOUND_NOTIFY
if (open_primary_device(output, &Control.device_idx) != de_None)
return -1;
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;
}
Control.poll_active = 1;
#endif /* _SOUND_NOTIFY */
Control.cooldown = time(NULL) + login_cooldown;
#ifdef _X11
Control.display = XOpenDisplay(NULL);
Control.this_window = get_focused_window_id();
#else
Control.this_window = 1;
#endif /* _X11 */
return 1;
}
void terminate_notify()
{
#ifdef _SOUND_NOTIFY
if ( !Control.poll_active ) return;
Control.poll_active = 0;
int i = 0;
for (; i < SOUNDS_SIZE; i ++) free(Control.sounds[i]);
graceful_clear();
close_device(output, Control.device_idx);
#endif /* _SOUND_NOTIFY */
}
#ifdef _SOUND_NOTIFY
void set_sound(Notification sound, const char* value)
{
free(Control.sounds[sound]);
size_t len = strlen(value) + 1;
Control.sounds[sound] = calloc(1, len);
memcpy(Control.sounds[sound], value, len);
}
int play_sound_internal(Notification what, _Bool loop)
{
char* data;
int format;
int clockrate;
int buffer_size;
char loop_;
uint32_t source;
uint32_t buffer;
alutLoadWAVFile(Control.sounds[what], &format, (void**)&data, &buffer_size, &clockrate, &loop_);
alGenSources(1, &source);
alGenBuffers(1, &buffer);
alBufferData(buffer, format, data, buffer_size, clockrate);
alSourcei(source, AL_BUFFER, buffer);
alSourcei(source, AL_LOOPING, loop);
alutUnloadWAV(format, data, buffer_size, clockrate);
int rc = play_source(source, buffer, loop);
if (rc < 0) {
alSourceStop(source);
alDeleteSources(1, &source);
alDeleteBuffers(1,&buffer);
return -1;
}
return rc;
}
int play_notify_sound(Notification notif, uint64_t flags)
{
int rc = 0;
if (flags & NT_BEEP) beep();
else if (notif != silent) {
if ( !Control.poll_active || (flags & NT_RESTOL && Control.cooldown > time(NULL)) || !Control.sounds[notif] )
return -1;
rc = play_sound_internal(notif, flags & NT_LOOP ? 1 : 0);
}
return rc;
}
void stop_sound(int sound)
{
if (sound >= 0 && sound < ACTIVE_SOUNDS_MAX && actives[sound].looping && actives[sound].active) {
alSourcei(actives[sound].source, AL_LOOPING, false);
alSourceStop(actives[sound].source);
alDeleteSources(1, &actives[sound].source);
alDeleteBuffers(1,&actives[sound].buffer);
memset(&actives[sound], 0, sizeof(struct _ActiveSounds));
}
}
#endif
static int m_play_sound(Notification notif, uint64_t flags)
{
#ifdef _SOUND_NOTIFY
return play_notify_sound(notif, flags);
#else
beep();
return -1;
#endif /* _SOUND_NOTIFY */
}
int notify(ToxWindow* self, Notification notif, uint64_t flags)
{
if (flags & NT_NOFOCUS && Control.this_window == get_focused_window_id())
return -1;
int rc = -1;
if (self && (!self->stb || self->stb->status != TOX_USERSTATUS_BUSY) && user_settings_->alerts == ALERTS_ENABLED)
rc = m_play_sound(notif, flags);
else if (flags & NT_ALWAYS)
rc = m_play_sound(notif, flags);
if (flags & NT_NOTIFWND) {
/* TODO: pop notify window */
}
if (self && self->alert == WINDOW_ALERT_NONE) {
if (flags & NT_WNDALERT_0) self->alert = WINDOW_ALERT_0;
else if (flags & NT_WNDALERT_1) self->alert = WINDOW_ALERT_1;
else if (flags & NT_WNDALERT_2) self->alert = WINDOW_ALERT_2;
}
return rc;
}

73
src/notify.h Normal file
View File

@ -0,0 +1,73 @@
/* notify.h
*
*
* Copyright (C) 2014 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Toxic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _notify_h
#define _notify_h
#include <inttypes.h>
#include "windows.h"
typedef enum _Notification
{
silent = -1,
error,
self_log_in,
self_log_out,
user_log_in,
user_log_out,
call_incoming,
call_outgoing,
generic_message,
transfer_pending,
transfer_completed,
} Notification;
typedef enum _Flags {
NT_NOFOCUS = 1 << 0, /* Notify when focus is not on this terminal. NOTE: only works with x11,
* if no x11 present this flag is ignored
*/
NT_BEEP = 1 << 1, /* Play native sound instead: \a */
NT_LOOP = 1 << 2, /* Loop sound. If this setting active, notify() will return id of the sound
* so it could be stopped. It will return 0 if error or NT_NATIVE flag is set and play \a instead
*/
NT_RESTOL = 1 << 3, /* Respect tolerance. Usually used to stop flood at toxic startup
* Only works if login_cooldown is true when calling init_notify()
*/
NT_NOTIFWND = 1 << 4, /* Pop notify window. NOTE: only works(/WILL WORK) if libnotify is present */
NT_WNDALERT_0 = 1 << 5, /* Alert toxic */
NT_WNDALERT_1 = 1 << 6, /* Alert toxic */
NT_WNDALERT_2 = 1 << 7, /* Alert toxic */
NT_ALWAYS = 1 << 8, /* Force sound to play */
} Flags;
int init_notify(int login_cooldown);
void terminate_notify();
int notify(ToxWindow* self, Notification notif, uint64_t flags);
#ifdef _SOUND_NOTIFY
void set_sound(Notification sound, const char* value);
void stop_sound(int sound);
#endif /* _SOUND_NOTIFY */
#endif /* _notify_h */

View File

@ -39,6 +39,7 @@
#include "settings.h" #include "settings.h"
#include "input.h" #include "input.h"
#include "help.h" #include "help.h"
#include "notify.h"
#include "autocomplete.h" #include "autocomplete.h"
char pending_frnd_requests[MAX_FRIENDS_NUM][TOX_CLIENT_ID_SIZE]; char pending_frnd_requests[MAX_FRIENDS_NUM][TOX_CLIENT_ID_SIZE];
@ -46,7 +47,7 @@ uint16_t num_frnd_requests = 0;
extern ToxWindow *prompt; extern ToxWindow *prompt;
struct _Winthread Winthread; struct _Winthread Winthread;
extern struct user_settings *user_settings; extern struct user_settings *user_settings_;
/* Array of global command names used for tab completion. */ /* Array of global command names used for tab completion. */
const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = { const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
@ -66,12 +67,12 @@ const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/quit" }, { "/quit" },
{ "/status" }, { "/status" },
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
{ "/lsdev" }, { "/lsdev" },
{ "/sdev" }, { "/sdev" },
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
}; };
void kill_prompt_window(ToxWindow *self) void kill_prompt_window(ToxWindow *self)
@ -308,11 +309,13 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum
msg = "has come online"; msg = "has come online";
line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, GREEN); line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, GREEN);
write_to_log(msg, nick, ctx->log, true); write_to_log(msg, nick, ctx->log, true);
alert_window(self, WINDOW_ALERT_2, false); notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
} else { } else {
msg = "has gone offline"; msg = "has gone offline";
line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, RED); line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, RED);
write_to_log(msg, nick, ctx->log, true); write_to_log(msg, nick, ctx->log, true);
notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
} }
} }
@ -340,7 +343,7 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, con
snprintf(msg, sizeof(msg), "Type \"/accept %d\" to accept it.", n); snprintf(msg, sizeof(msg), "Type \"/accept %d\" to accept it.", n);
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
alert_window(self, WINDOW_ALERT_1, true); notify(self, generic_message, NT_WNDALERT_1 | NT_NOTIFWND);
} }
void prompt_init_statusbar(ToxWindow *self, Tox *m) void prompt_init_statusbar(ToxWindow *self, Tox *m)
@ -419,7 +422,7 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
line_info_init(ctx->hst); line_info_init(ctx->hst);
if (user_settings->autolog == AUTOLOG_ON) { if (user_settings_->autolog == AUTOLOG_ON) {
char myid[TOX_FRIEND_ADDRESS_SIZE]; char myid[TOX_FRIEND_ADDRESS_SIZE];
tox_get_address(m, (uint8_t *) myid); tox_get_address(m, (uint8_t *) myid);
log_enable(self->name, myid, ctx->log); log_enable(self->name, myid, ctx->log);

View File

@ -26,11 +26,11 @@
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#define AC_NUM_GLOB_COMMANDS 17 #define AC_NUM_GLOB_COMMANDS 17
#else #else
#define AC_NUM_GLOB_COMMANDS 15 #define AC_NUM_GLOB_COMMANDS 15
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
ToxWindow new_prompt(void); ToxWindow new_prompt(void);
void prep_prompt_win(void); void prep_prompt_win(void);

View File

@ -22,207 +22,194 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <libconfig.h>
#include "toxic.h" #include "toxic.h"
#include "windows.h" #include "windows.h"
#include "configdir.h" #include "configdir.h"
#include "notify.h"
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#include "device.h" #include "device.h"
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#include "settings.h" #include "settings.h"
#include "line_info.h" #include "line_info.h"
static void uset_autolog(struct user_settings *s, const char *val); const struct _ui_strings {
static void uset_time(struct user_settings *s, const char *val); const char* self;
static void uset_timestamps(struct user_settings *s, const char *val); const char* timestamps;
static void uset_alerts(struct user_settings *s, const char *val); const char* alerts;
static void uset_colours(struct user_settings *s, const char *val); const char* native_colors;
static void uset_hst_size(struct user_settings *s, const char *val); const char* autolog;
static void uset_dwnld_path(struct user_settings *s, const char *val); const char* time_format;
const char* history_size;
} ui_strings = {
"ui",
"timestamps",
"alerts",
"native_colors",
"autolog",
"time_format",
"history_size"
};
static void ui_defaults(struct user_settings* settings)
{
settings->timestamps = TIMESTAMPS_ON;
settings->time = TIME_24;
settings->autolog = AUTOLOG_OFF;
settings->alerts = ALERTS_ENABLED;
settings->colour_theme = DFLT_COLS;
settings->history_size = 700;
}
#ifdef _SUPPORT_AUDIO const struct _tox_strings {
static void uset_ain_dev(struct user_settings *s, const char *val); const char* self;
static void uset_aout_dev(struct user_settings *s, const char *val); const char* download_path;
#endif } tox_strings = {
"tox",
struct { "download_path",
const char *key;
void (*func)(struct user_settings *s, const char *val);
} user_settings_list[] = {
{ "autolog", uset_autolog },
{ "time", uset_time },
{ "timestamps", uset_timestamps },
{ "alerts", uset_alerts },
{ "colour_theme", uset_colours },
{ "history_size", uset_hst_size },
{ "download_path", uset_dwnld_path },
#ifdef _SUPPORT_AUDIO
{ "audio_in_dev", uset_ain_dev },
{ "audio_out_dev", uset_aout_dev },
#endif
}; };
static void uset_autolog(struct user_settings *s, const char *val) static void tox_defaults(struct user_settings* settings)
{ {
int n = atoi(val); /*settings->download_path;*/ /* TODO: Set this? */
/* default off if invalid value */
s->autolog = n == AUTOLOG_ON ? AUTOLOG_ON : AUTOLOG_OFF;
} }
static void uset_time(struct user_settings *s, const char *val) #ifdef _AUDIO
const struct _audio_strings {
const char* self;
const char* input_device;
const char* output_device;
const char* VAD_treshold;
} audio_strings = {
"audio",
"input_device",
"output_device",
"VAD_treshold",
};
static void audio_defaults(struct user_settings* settings)
{ {
int n = atoi(val); settings->audio_in_dev = 0;
settings->audio_out_dev = 0;
/* default to 24 hour time if invalid value */ settings->VAD_treshold = 40.0;
s->time = n == TIME_12 ? TIME_12 : TIME_24;
} }
static void uset_timestamps(struct user_settings *s, const char *val)
{
int n = atoi(val);
/* default on if invalid value */
s->timestamps = n == TIMESTAMPS_OFF ? TIMESTAMPS_OFF : TIMESTAMPS_ON;
}
static void uset_alerts(struct user_settings *s, const char *val)
{
int n = atoi(val);
/* alerts default on if invalid value */
s->alerts = n == ALERTS_DISABLED ? ALERTS_DISABLED : ALERTS_ENABLED;
}
static void uset_colours(struct user_settings *s, const char *val)
{
int n = atoi(val);
/* use default toxic colours if invalid value */
s->colour_theme = n == NATIVE_COLS ? NATIVE_COLS : DFLT_COLS;
}
#ifdef _SUPPORT_AUDIO
static void uset_ain_dev(struct user_settings *s, const char *val)
{
int n = atoi(val);
if (n < 0 || n > MAX_DEVICES)
n = (long int) 0;
s->audio_in_dev = (long int) n;
}
static void uset_aout_dev(struct user_settings *s, const char *val)
{
int n = atoi(val);
if (n < 0 || n > MAX_DEVICES)
n = (long int) 0;
s->audio_out_dev = (long int) n;
}
#endif /* _SUPPORT_AUDIO */
static void uset_hst_size(struct user_settings *s, const char *val)
{
int n = atoi(val);
/* if val is out of range use default history size */
s->history_size = (n > MAX_HISTORY || n < MIN_HISTORY) ? DFLT_HST_SIZE : n;
}
static void uset_dwnld_path(struct user_settings *s, const char *val)
{
memset(s->download_path, 0, sizeof(s->download_path));
if (val == NULL)
return;
int len = strlen(val);
if (len >= sizeof(s->download_path) - 2) /* leave room for null and '/' */
return;
FILE *fp = fopen(val, "r");
if (fp == NULL)
return;
strcpy(s->download_path, val);
if (val[len - 1] != '/')
strcat(s->download_path, "/");
}
static void set_default_settings(struct user_settings *s)
{
/* see settings_values enum in settings.h for defaults */
uset_autolog(s, "0");
uset_time(s, "24");
uset_timestamps(s, "1");
uset_alerts(s, "1");
uset_colours(s, "0");
uset_hst_size(s, "700");
uset_dwnld_path(s, NULL);
#ifdef _SUPPORT_AUDIO
uset_ain_dev(s, "0");
uset_aout_dev(s, "0");
#endif #endif
}
#ifdef _SOUND_NOTIFY
const struct _sound_strings {
const char* self;
const char* error;
const char* self_log_in;
const char* self_log_out;
const char* user_log_in;
const char* user_log_out;
const char* call_incoming;
const char* call_outgoing;
const char* generic_message;
const char* transfer_pending;
const char* transfer_completed;
} sound_strings = {
"sounds",
"error",
"self_log_in",
"self_log_out",
"user_log_in",
"user_log_out",
"call_incoming",
"call_outgoing",
"generic_message",
"transfer_pending",
"transfer_completed",
};
#endif
int settings_load(struct user_settings *s, char *path) int settings_load(struct user_settings *s, char *path)
{ {
char *user_config_dir = get_user_config_dir(); config_t cfg[1];
FILE *fp = NULL; config_setting_t *setting;
char dflt_path[MAX_STR_SIZE]; const char *str;
if (path) { /* Load default settings */
fp = fopen(path, "r"); ui_defaults(s);
} else { tox_defaults(s);
snprintf(dflt_path, sizeof(dflt_path), "%s%stoxic.conf", user_config_dir, CONFIGDIR); #ifdef _AUDIO
fp = fopen(dflt_path, "r"); audio_defaults(s);
} #endif
free(user_config_dir); config_init(cfg);
set_default_settings(s); if(!config_read_file(cfg, path))
{
if (fp == NULL && !path) { config_destroy(cfg);
if ((fp = fopen(dflt_path, "w")) == NULL)
return -1;
} else if (fp == NULL && path) {
return -1; return -1;
} }
char line[MAX_STR_SIZE]; /* ui */
if ((setting = config_lookup(cfg, ui_strings.self)) != NULL) {
config_setting_lookup_bool(setting, ui_strings.timestamps, &s->timestamps);
config_setting_lookup_bool(setting, ui_strings.alerts, &s->alerts);
config_setting_lookup_bool(setting, ui_strings.autolog, &s->autolog);
config_setting_lookup_bool(setting, ui_strings.native_colors, &s->colour_theme);
while (fgets(line, sizeof(line), fp)) { config_setting_lookup_int(setting, ui_strings.history_size, &s->history_size);
if (line[0] == '#' || !line[0]) config_setting_lookup_int(setting, ui_strings.time_format, &s->time);
continue; s->time = s->time == TIME_24 || s->time == TIME_12 ? s->time : TIME_24; /* Check defaults */
const char *key = strtok(line, ":");
const char *val = strtok(NULL, ";");
if (key == NULL || val == NULL)
continue;
int i;
for (i = 0; i < NUM_SETTINGS; ++i) {
if (strcmp(user_settings_list[i].key, key) == 0) {
(user_settings_list[i].func)(s, val);
break;
}
}
} }
fclose(fp); if ((setting = config_lookup(cfg, tox_strings.self)) != NULL) {
if ( config_setting_lookup_string(setting, tox_strings.download_path, &str) ) {
s->download_path = calloc(1, strlen(str) + 1);
strcpy(s->download_path, str);
}
}
#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;
config_setting_lookup_int(setting, audio_strings.output_device, &s->audio_out_dev);
s->audio_out_dev = s->audio_out_dev < 0 || s->audio_out_dev > MAX_DEVICES ? 0 : s->audio_out_dev;
config_setting_lookup_float(setting, audio_strings.VAD_treshold, &s->VAD_treshold);
}
#endif
#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);
if ( config_setting_lookup_string(setting, sound_strings.user_log_in, &str) )
set_sound(user_log_in, str);
if ( config_setting_lookup_string(setting, sound_strings.self_log_in, &str) )
set_sound(self_log_in, str);
if ( config_setting_lookup_string(setting, sound_strings.user_log_out, &str) )
set_sound(user_log_out, str);
if ( config_setting_lookup_string(setting, sound_strings.self_log_out, &str) )
set_sound(self_log_out, str);
if ( config_setting_lookup_string(setting, sound_strings.call_incoming, &str) )
set_sound(call_incoming, str);
if ( config_setting_lookup_string(setting, sound_strings.call_outgoing, &str) )
set_sound(call_outgoing, str);
if ( config_setting_lookup_string(setting, sound_strings.generic_message, &str) )
set_sound(generic_message, str);
if ( config_setting_lookup_string(setting, sound_strings.transfer_pending, &str) )
set_sound(transfer_pending, str);
if ( config_setting_lookup_string(setting, sound_strings.transfer_completed, &str) )
set_sound(transfer_completed, str);
}
#endif
config_destroy(cfg);
return 0; return 0;
} }

View File

@ -23,14 +23,6 @@
#ifndef _settings_h #ifndef _settings_h
#define _settings_h #define _settings_h
#include "toxic.h"
#ifdef _SUPPORT_AUDIO
#define NUM_SETTINGS 9
#else
#define NUM_SETTINGS 7
#endif /* _SUPPORT_AUDIO */
/* holds user setting values */ /* holds user setting values */
struct user_settings { struct user_settings {
int autolog; /* boolean */ int autolog; /* boolean */
@ -39,11 +31,12 @@ struct user_settings {
int timestamps; /* boolean */ int timestamps; /* boolean */
int colour_theme; /* boolean (0 for default toxic colours) */ int colour_theme; /* boolean (0 for default toxic colours) */
int history_size; /* int between MIN_HISTORY and MAX_HISTORY */ int history_size; /* int between MIN_HISTORY and MAX_HISTORY */
char download_path[MAX_STR_SIZE]; char* download_path;
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
long int audio_in_dev; int audio_in_dev;
long int audio_out_dev; int audio_out_dev;
double VAD_treshold;
#endif #endif
}; };

View File

@ -50,18 +50,20 @@
#include "line_info.h" #include "line_info.h"
#include "settings.h" #include "settings.h"
#include "log.h" #include "log.h"
#include "notify.h"
#include "device.h"
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#include "audio_call.h" #include "audio_call.h"
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#ifndef PACKAGE_DATADIR #ifndef PACKAGE_DATADIR
#define PACKAGE_DATADIR "." #define PACKAGE_DATADIR "."
#endif #endif
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
ToxAv *av; ToxAv *av;
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
/* Export for use in Callbacks */ /* Export for use in Callbacks */
char *DATA_FILE = NULL; char *DATA_FILE = NULL;
@ -78,7 +80,7 @@ struct arg_opts {
} arg_opts; } arg_opts;
struct _Winthread Winthread; struct _Winthread Winthread;
struct user_settings *user_settings = NULL; struct user_settings *user_settings_ = NULL;
static void catch_SIGINT(int sig) static void catch_SIGINT(int sig)
{ {
@ -97,11 +99,13 @@ void exit_toxic_success(Tox *m)
kill_all_windows(); kill_all_windows();
free(DATA_FILE); free(DATA_FILE);
free(user_settings); free(user_settings_);
#ifdef _SUPPORT_AUDIO notify(NULL, self_log_out, NT_ALWAYS);
terminate_notify();
#ifdef _AUDIO
terminate_audio(); terminate_audio();
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
tox_kill(m); tox_kill(m);
endwin(); endwin();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -141,7 +145,7 @@ static void init_term(void)
short bg_color = COLOR_BLACK; short bg_color = COLOR_BLACK;
start_color(); start_color();
if (user_settings->colour_theme == NATIVE_COLS) { if (user_settings_->colour_theme == NATIVE_COLS) {
if (assume_default_colors(-1, -1) == OK) if (assume_default_colors(-1, -1) == OK)
bg_color = -1; bg_color = -1;
} }
@ -564,7 +568,7 @@ int main(int argc, char *argv[])
/* Make sure all written files are read/writeable only by the current user. */ /* Make sure all written files are read/writeable only by the current user. */
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
signal(SIGINT, catch_SIGINT); // signal(SIGINT, catch_SIGINT);
config_err = create_user_config_dir(user_config_dir); config_err = create_user_config_dir(user_config_dir);
@ -589,15 +593,13 @@ int main(int argc, char *argv[])
free(user_config_dir); free(user_config_dir);
/* init user_settings struct and load settings from conf file */ /* init user_settings struct and load settings from conf file */
user_settings = malloc(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); exit_toxic_err("failed in main", FATALERR_MEMORY);
memset(user_settings, 0, sizeof(struct user_settings));
char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL; 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(arg_opts.use_ipv4); Tox *m = init_tox(arg_opts.use_ipv4);
init_term(); init_term();
@ -619,15 +621,20 @@ int main(int argc, char *argv[])
char *msg; char *msg;
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
av = init_audio(prompt, m); av = init_audio(prompt, m);
set_primary_device(input, user_settings->audio_in_dev); set_primary_device(input, user_settings_->audio_in_dev);
set_primary_device(output, user_settings->audio_out_dev); set_primary_device(output, user_settings_->audio_out_dev);
#elif _SOUND_NOTIFY
if ( init_devices() == de_InternalError )
line_info_add(prompt, NULL, NULL, NULL, "Failed to init devices", SYS_MSG, 0, 0);
#endif /* _AUDIO */
#endif /* _SUPPORT_AUDIO */ init_notify(60);
notify(prompt, self_log_in, 0);
if (config_err) { if (config_err) {
msg = "Unable to determine configuration directory. Defaulting to 'data' for a keyfile..."; msg = "Unable to determine configuration directory. Defaulting to 'data' for a keyfile...";

View File

@ -355,12 +355,12 @@ void on_window_resize(void)
w->stb->topline = subwin(w->window, 2, x2, 0, 0); w->stb->topline = subwin(w->window, 2, x2, 0, 0);
} }
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
if (w->chatwin->infobox.active) { if (w->chatwin->infobox.active) {
delwin(w->chatwin->infobox.win); delwin(w->chatwin->infobox.win);
w->chatwin->infobox.win = newwin(INFOBOX_HEIGHT, INFOBOX_WIDTH + 1, 1, x2 - INFOBOX_WIDTH); w->chatwin->infobox.win = newwin(INFOBOX_HEIGHT, INFOBOX_WIDTH + 1, 1, x2 - INFOBOX_WIDTH);
} }
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
scrollok(w->chatwin->history, 0); scrollok(w->chatwin->history, 0);
} }
@ -368,23 +368,11 @@ void on_window_resize(void)
static void draw_window_tab(ToxWindow toxwin) static void draw_window_tab(ToxWindow toxwin)
{ {
/* alert0 takes priority */ if (toxwin.alert) attron(COLOR_PAIR(toxwin.alert));
if (toxwin.alert0)
attron(COLOR_PAIR(GREEN));
else if (toxwin.alert1)
attron(COLOR_PAIR(RED));
else if (toxwin.alert2)
attron(COLOR_PAIR(MAGENTA));
clrtoeol(); clrtoeol();
printw(" [%s]", toxwin.name); printw(" [%s]", toxwin.name);
if (toxwin.alert0) if (toxwin.alert) attroff(COLOR_PAIR(toxwin.alert));
attroff(COLOR_PAIR(GREEN));
else if (toxwin.alert1)
attroff(COLOR_PAIR(RED));
else if (toxwin.alert2)
attroff(COLOR_PAIR(MAGENTA));
} }
static void draw_bar(void) static void draw_bar(void)
@ -432,9 +420,7 @@ static void draw_bar(void)
void draw_active_window(Tox *m) void draw_active_window(Tox *m)
{ {
ToxWindow *a = active_window; ToxWindow *a = active_window;
a->alert0 = false; a->alert = WINDOW_ALERT_NONE;
a->alert1 = false;
a->alert2 = false;
wint_t ch = 0; wint_t ch = 0;

View File

@ -29,9 +29,9 @@
#include <tox/tox.h> #include <tox/tox.h>
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#include <tox/toxav.h> #include <tox/toxav.h>
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#include "toxic.h" #include "toxic.h"
@ -53,10 +53,11 @@ enum {
} C_COLOURS; } C_COLOURS;
/* tab alert types: lower types take priority */ /* tab alert types: lower types take priority */
enum { typedef enum {
WINDOW_ALERT_0, WINDOW_ALERT_NONE = 0,
WINDOW_ALERT_1, WINDOW_ALERT_0 = GREEN,
WINDOW_ALERT_2, WINDOW_ALERT_1 = RED,
WINDOW_ALERT_2 = MAGENTA,
} WINDOW_ALERTS; } WINDOW_ALERTS;
/* Fixes text color problem on some terminals. /* Fixes text color problem on some terminals.
@ -97,7 +98,7 @@ struct ToxWindow {
void(*onFileData)(ToxWindow *, Tox *, int32_t, uint8_t, const char *, uint16_t); void(*onFileData)(ToxWindow *, Tox *, int32_t, uint8_t, const char *, uint16_t);
void(*onTypingChange)(ToxWindow *, Tox *, int32_t, uint8_t); void(*onTypingChange)(ToxWindow *, Tox *, int32_t, uint8_t);
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
void(*onInvite)(ToxWindow *, ToxAv *, int); void(*onInvite)(ToxWindow *, ToxAv *, int);
void(*onRinging)(ToxWindow *, ToxAv *, int); void(*onRinging)(ToxWindow *, ToxAv *, int);
@ -115,7 +116,11 @@ struct ToxWindow {
* Don't modify outside av callbacks. */ * Don't modify outside av callbacks. */
int device_selection[2]; /* -1 if not set, if set uses these selections instead of primary device */ int device_selection[2]; /* -1 if not set, if set uses these selections instead of primary device */
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#ifdef _SOUND_NOTIFY
int active_sound;
#endif
char name[TOXIC_MAX_NAME_LENGTH]; char name[TOXIC_MAX_NAME_LENGTH];
int32_t num; /* corresponds to friendnumber in chat windows */ int32_t num; /* corresponds to friendnumber in chat windows */
@ -127,9 +132,7 @@ struct ToxWindow {
bool is_prompt; bool is_prompt;
bool is_friendlist; bool is_friendlist;
bool alert0; WINDOW_ALERTS alert;
bool alert1;
bool alert2;
ChatContext *chatwin; ChatContext *chatwin;
StatusBar *stb; StatusBar *stb;
@ -149,7 +152,7 @@ struct StatusBar {
bool is_online; bool is_online;
}; };
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
#define INFOBOX_HEIGHT 7 #define INFOBOX_HEIGHT 7
@ -168,7 +171,7 @@ struct infobox {
WINDOW *win; WINDOW *win;
}; };
#endif /* _SUPPORT_AUDIO */ #endif /* _AUDIO */
#define MAX_LINE_HIST 128 #define MAX_LINE_HIST 128
@ -189,7 +192,7 @@ struct ChatContext {
struct history *hst; struct history *hst;
struct chatlog *log; struct chatlog *log;
#ifdef _SUPPORT_AUDIO #ifdef _AUDIO
struct infobox infobox; struct infobox infobox;
#endif #endif