1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-22 20:23:01 +01:00

show info box for audio calls

This commit is contained in:
Jfreegman 2014-06-23 18:54:23 -04:00
parent 52b7719180
commit 63ea6154f4
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
11 changed files with 208 additions and 53 deletions

View File

@ -61,7 +61,7 @@ typedef struct _Call {
} Call;
void set_call(Call* call, _Bool start)
void set_call(ToxWindow *self, Call* call, _Bool start)
{
call->in_idx = -1;
call->out_idx = -1;
@ -76,7 +76,7 @@ void set_call(Call* call, _Bool start)
}
}
struct _ASettings {
struct _ASettins {
AudioError errors;
ToxAv *av;
@ -98,7 +98,6 @@ void callback_call_ended ( int32_t call_index, void *arg );
void callback_requ_timeout ( int32_t call_index, void *arg );
void callback_peer_timeout ( int32_t call_index, void *arg );
static void print_err (ToxWindow *self, uint8_t *error_str)
{
line_info_add(self, NULL, NULL, NULL, error_str, SYS_MSG, 0, 0);
@ -230,7 +229,7 @@ cleanup:
if ( this_call->out_idx != -1 ) if ( close_device(output, this_call->out_idx) != de_None )
line_info_add(self, NULL, NULL, NULL, "Failed to close output device!", SYS_MSG, 0, 0);
set_call(this_call, _False);
set_call(self, this_call, _False);
_cbend;
}
@ -248,7 +247,7 @@ int start_transmission(ToxWindow *self)
!toxav_capability_supported(ASettins.av, self->call_idx, AudioEncoding) )
return -1;
set_call(&ASettins.calls[self->call_idx], _True);
set_call(self, &ASettins.calls[self->call_idx], _True);
if ( 0 != pthread_create(&ASettins.calls[self->call_idx].ttid, NULL, transmission, self ) &&
0 != pthread_detach(ASettins.calls[self->call_idx].ttid) ) {
@ -696,7 +695,13 @@ void cmd_mute(WINDOW * window, ToxWindow * self, Tox *m, int argc, char (*argv)[
Call* this_call = &ASettins.calls[self->call_idx];
pthread_mutex_lock(&this_call->mutex);
device_mute(type, type == input ? this_call->in_idx : this_call->out_idx);
if (type == input) {
device_mute(type, this_call->in_idx);
self->chatwin->infobox.in_is_muted ^= 1;
} else {
self->chatwin->infobox.out_is_muted ^= 1;
device_mute(type, this_call->out_idx);
}
pthread_mutex_unlock(&this_call->mutex);
}
@ -727,10 +732,16 @@ void cmd_sense(WINDOW * window, ToxWindow * self, Tox *m, int argc, char (*argv)
}
/* Call must be active */
if ( self->call_idx > -1) device_set_VAD_treshold(ASettins.calls[self->call_idx].in_idx, value);
if ( self->call_idx > -1) {
device_set_VAD_treshold(ASettins.calls[self->call_idx].in_idx, value);
self->chatwin->infobox.vad_lvl = value;
}
return;
on_error:
print_err (self, error_str);
}
/*
* end of commands
*/

View File

@ -26,6 +26,9 @@
#include <tox/toxav.h>
#include "device.h"
#include "windows.h"
#define VAD_THRESHOLD_DEFAULT 40.0
typedef enum _AudioError {
ae_None = 0,
@ -34,7 +37,6 @@ typedef enum _AudioError {
ae_StartingCoreAudio = 1 << 2
} AudioError;
/* You will have to pass pointer to first member of 'windows'
* declared in windows.c otherwise undefined behaviour will
*/
@ -44,5 +46,4 @@ void terminate_audio();
int start_transmission(ToxWindow *self);
int stop_transmission(int call_index);
#endif /* _audio_h */

View File

@ -40,6 +40,7 @@
#include "log.h"
#include "line_info.h"
#include "settings.h"
#include "chat.h"
#ifdef _SUPPORT_AUDIO
#include "audio_call.h"
@ -53,6 +54,11 @@ extern ToxicFriend friends[MAX_FRIENDS_NUM];
extern struct _Winthread Winthread;
extern struct user_settings *user_settings;
#ifdef _SUPPORT_AUDIO
static void init_infobox(ToxWindow *self);
static void kill_infobox(ToxWindow *self);
#endif /* _SUPPORT_AUDIO */
#ifdef _SUPPORT_AUDIO
#define AC_NUM_CHAT_COMMANDS 26
#else
@ -139,7 +145,7 @@ static void chat_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *msg, u
nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, nick, NULL, msg, IN_MSG, 0, 0);
@ -188,7 +194,7 @@ static void chat_onAction(ToxWindow *self, Tox *m, int32_t num, uint8_t *action,
nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, nick, NULL, action, ACTION, 0, 0);
write_to_log(action, nick, ctx->log, true);
@ -453,6 +459,8 @@ void chat_onStarting (ToxWindow *self, ToxAv *av, int call_index)
if ( self->call_idx != call_index || self->num != toxav_get_peer_id(av, call_index, 0))
return;
init_infobox(self);
line_info_add(self, NULL, NULL, NULL, "Call started! Type: \"/hangup\" to end it.", SYS_MSG, 0, 0);
}
@ -461,6 +469,7 @@ void chat_onEnding (ToxWindow *self, ToxAv *av, int call_index)
if (self->call_idx != call_index || self->num != toxav_get_peer_id(av, call_index, 0))
return;
kill_infobox(self);
self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0);
}
@ -479,6 +488,8 @@ void chat_onStart (ToxWindow *self, ToxAv *av, int call_index)
if ( self->call_idx != call_index || self->num != toxav_get_peer_id(av, call_index, 0))
return;
init_infobox(self);
line_info_add(self, NULL, NULL, NULL, "Call started! Type: \"/hangup\" to end it.", SYS_MSG, 0, 0);
}
@ -487,6 +498,7 @@ void chat_onCancel (ToxWindow *self, ToxAv *av, int call_index)
if ( self->call_idx != call_index || self->num != toxav_get_peer_id(av, call_index, 0))
return;
kill_infobox(self);
self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Call canceled!", SYS_MSG, 0, 0);
}
@ -505,6 +517,7 @@ void chat_onEnd (ToxWindow *self, ToxAv *av, int call_index)
if (self->call_idx != call_index || self->num != toxav_get_peer_id(av, call_index, 0))
return;
kill_infobox(self);
self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Call ended!", SYS_MSG, 0, 0);
}
@ -523,10 +536,94 @@ void chat_onPeerTimeout (ToxWindow *self, ToxAv *av, int call_index)
if (self->call_idx != call_index || self->num != toxav_get_peer_id(av, call_index, 0))
return;
kill_infobox(self);
self->call_idx = -1;
line_info_add(self, NULL, NULL, NULL, "Peer disconnected; call ended!", SYS_MSG, 0, 0);
}
#define INFOBOX_HEIGHT 7
#define INFOBOX_WIDTH 21
static void init_infobox(ToxWindow *self)
{
int x2, y2;
getmaxyx(self->window, y2, x2);
memset(&self->chatwin->infobox, 0, sizeof(struct infobox));
self->chatwin->infobox.win = newwin(INFOBOX_HEIGHT, INFOBOX_WIDTH + 1, 1, x2 - INFOBOX_WIDTH);
self->chatwin->infobox.calltime = get_unix_time();
self->chatwin->infobox.vad_lvl = VAD_THRESHOLD_DEFAULT;
self->chatwin->infobox.active = true;
strcpy(self->chatwin->infobox.timestr, "00:00:00");
}
static void kill_infobox(ToxWindow *self)
{
if (!self->chatwin->infobox.win)
return;
delwin(self->chatwin->infobox.win);
memset(&self->chatwin->infobox, 0, sizeof(struct infobox));
}
/* update infobox info and draw in respective chat window */
static void draw_infobox(ToxWindow *self)
{
struct infobox infobox = self->chatwin->infobox;
if (infobox.win == NULL)
return;
int x2, y2;
getmaxyx(self->window, y2, x2);
if (x2 < INFOBOX_WIDTH || y2 < INFOBOX_HEIGHT)
return;
uint64_t curtime = get_unix_time();
/* update elapsed time string once per second */
if (curtime > infobox.deltatime) {
infobox.calltime = curtime - infobox.calltime;
get_elapsed_time_str(infobox.timestr, sizeof(infobox.timestr), infobox.calltime);
}
infobox.deltatime = curtime;
const char *in_is_muted = infobox.in_is_muted ? "yes" : "no";
const char *out_is_muted = infobox.out_is_muted ? "yes" : "no";
wmove(infobox.win, 1, 1);
wattron(infobox.win, COLOR_PAIR(RED) | A_BOLD);
wprintw(infobox.win, " Call Active\n");
wattroff(infobox.win, COLOR_PAIR(RED) | A_BOLD);
wattron(infobox.win, A_BOLD);
wprintw(infobox.win, " Time: ");
wattroff(infobox.win, A_BOLD);
wprintw(infobox.win, "%s\n", infobox.timestr);
wattron(infobox.win, A_BOLD);
wprintw(infobox.win, " In muted: ");
wattroff(infobox.win, A_BOLD);
wprintw(infobox.win, "%s\n", in_is_muted);
wattron(infobox.win, A_BOLD);
wprintw(infobox.win, " Out muted: ");
wattroff(infobox.win, A_BOLD);
wprintw(infobox.win, "%s\n", out_is_muted);
wattron(infobox.win, A_BOLD);
wprintw(infobox.win, " VAD level: ");
wattroff(infobox.win, A_BOLD);
wprintw(infobox.win, "%.2f\n", infobox.vad_lvl);
wborder(infobox.win, ACS_VLINE, ' ', ACS_HLINE, ACS_HLINE, ACS_TTEE, ' ', ACS_LLCORNER, ' ');
wrefresh(infobox.win);
}
#endif /* _SUPPORT_AUDIO */
static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *action)
@ -539,7 +636,7 @@ static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *acti
selfname[len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, selfname, NULL, action, ACTION, 0, 0);
@ -740,7 +837,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
selfname[len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, selfname, NULL, line, OUT_MSG, 0, 0);
@ -874,6 +971,14 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
wprintw(statusbar->topline, "}\n");
mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x2);
#ifdef _SUPPORT_AUDIO
wrefresh(self->window);
if (ctx->infobox.active)
draw_infobox(self);
#endif
}
static void chat_onInit(ToxWindow *self, Tox *m)

View File

@ -192,7 +192,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
if (type == input) {
device->dhndl = alcCaptureOpenDevice(devices_names[type][selection],
av_DefaultSettings.audio_sample_rate, AL_FORMAT_MONO16, frame_size * 4);
device->VAD_treshold = 40.0;
device->VAD_treshold = VAD_THRESHOLD_DEFAULT;
}
else {
device->dhndl = alcOpenDevice(devices_names[type][selection]);

View File

@ -83,7 +83,7 @@ static struct _dns_thread {
static int dns_error(ToxWindow *self, uint8_t *errmsg)
{
uint8_t msg[MAX_STR_SIZE];
snprintf(msg, sizeof(msg), "DNS lookup failed: %s", errmsg);
snprintf(msg, sizeof(msg), "User lookup failed: %s", errmsg);
pthread_mutex_lock(&dns_thread.lock);
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
@ -116,13 +116,13 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, uint
ans_pt += len;
if (ans_pt > ans_end - 4)
return dns_error(self, "Reply was too short.");
return dns_error(self, "DNS reply was too short.");
int type;
GETSHORT(type, ans_pt);
if (type != T_TXT)
return dns_error(self, "Broken reply.");
return dns_error(self, "Broken DNS reply.");
ans_pt += INT16SZ; /* class */
@ -139,7 +139,7 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, uint
ans_pt += len;
if (ans_pt > ans_end - 10)
return dns_error(self, "Reply was too short.");
return dns_error(self, "DNS reply was too short.");
GETSHORT(type, ans_pt);
ans_pt += INT16SZ;
@ -152,7 +152,7 @@ static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, uint
} while (type == T_CNAME);
if (type != T_TXT)
return dns_error(self, "Not a TXT record.");
return dns_error(self, "DNS response failed.");
uint32_t txt_len = *ans_pt;
@ -234,7 +234,7 @@ void *dns3_lookup_thread(void *data)
int str_len = tox_generate_dns3_string(dns_obj, string, sizeof(string), &request_id, name, namelen);
if (str_len == -1) {
dns_error(self, "Core failed to generate dns3 string.");
dns_error(self, "Core failed to generate DNS3 string.");
kill_dns_thread(dns_obj);
}
@ -248,7 +248,7 @@ void *dns3_lookup_thread(void *data)
int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer));
if (ans_len <= 0) {
dns_error(self, "Query failed.");
dns_error(self, "DNS query failed.");
kill_dns_thread(dns_obj);
}
@ -263,14 +263,14 @@ void *dns3_lookup_thread(void *data)
/* extract the encrypted ID from TXT response */
if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) {
dns_error(self, "Bad dns3 TXT response.");
dns_error(self, "Bad DNS3 TXT response.");
kill_dns_thread(dns_obj);
}
memcpy(encrypted_id, ans_id + prfx_len, ans_len - prfx_len);
if (tox_decrypt_dns3_TXT(dns_obj, t_data.id_bin, encrypted_id, strlen(encrypted_id), request_id) == -1) {
dns_error(self, "Core failed to decrypt response.");
dns_error(self, "Core failed to decrypt DNS response.");
kill_dns_thread(dns_obj);
}

View File

@ -59,6 +59,7 @@ static int friendlist_index[MAX_FRIENDS_NUM] = {0};
static struct _pendingDel {
int num;
bool active;
WINDOW *popup;
} pendingdelete;
#define S_WEIGHT 100
@ -116,7 +117,7 @@ static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *
nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(prompt, timefrmt, nick, NULL, str, IN_MSG, 0, 0);
@ -298,7 +299,7 @@ static void del_friend_activate(ToxWindow *self, Tox *m, int32_t f_num)
{
int x2, y2;
getmaxyx(self->window, y2, x2);
self->popup = newwin(3, 22 + TOXIC_MAX_NAME_LENGTH, 8, 8);
pendingdelete.popup = newwin(3, 22 + TOXIC_MAX_NAME_LENGTH, 8, 8);
pendingdelete.active = true;
pendingdelete.num = f_num;
@ -310,30 +311,29 @@ static void del_friend_deactivate(ToxWindow *self, Tox *m, wint_t key)
if (key == 'y')
delete_friend(m, pendingdelete.num);
delwin(pendingdelete.popup);
memset(&pendingdelete, 0, sizeof(pendingdelete));
delwin(self->popup);
self->popup = NULL;
clear();
refresh();
}
static void draw_popup(ToxWindow *self, Tox *m)
static void draw_popup(void)
{
if (self->popup == NULL)
if (!pendingdelete.active)
return;
wattron(self->popup, A_BOLD);
box(self->popup, ACS_VLINE, ACS_HLINE);
wattroff(self->popup, A_BOLD);
wattron(pendingdelete.popup, A_BOLD);
box(pendingdelete.popup, ACS_VLINE, ACS_HLINE);
wattroff(pendingdelete.popup, A_BOLD);
wmove(self->popup, 1, 1);
wprintw(self->popup, "Delete contact ");
wattron(self->popup, A_BOLD);
wprintw(self->popup, "%s", friends[pendingdelete.num].name);
wattroff(self->popup, A_BOLD);
wprintw(self->popup, "? y/n");
wmove(pendingdelete.popup, 1, 1);
wprintw(pendingdelete.popup, "Delete contact ");
wattron(pendingdelete.popup, A_BOLD);
wprintw(pendingdelete.popup, "%s", friends[pendingdelete.num].name);
wattroff(pendingdelete.popup, A_BOLD);
wprintw(pendingdelete.popup, "? y/n");
wrefresh(self->popup);
wrefresh(pendingdelete.popup);
}
static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
@ -540,7 +540,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
self->x = x2;
wrefresh(self->window);
draw_popup(self, m);
draw_popup();
if (num_friends) {
wmove(self->window, y2 - 1, 1);

View File

@ -200,7 +200,7 @@ static void groupchat_onGroupMessage(ToxWindow *self, Tox *m, int groupnum, int
alert_window(self, alert_type, beep);
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, nick, NULL, msg, IN_MSG, 0, nick_clr);
write_to_log(msg, nick, ctx->log, false);
@ -240,7 +240,7 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p
nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
line_info_add(self, timefrmt, nick, NULL, action, ACTION, 0, 0);
write_to_log(action, nick, ctx->log, true);
@ -339,7 +339,7 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
uint8_t *event;
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
switch (change) {
case TOX_CHAT_CHANGE_PEER_ADD:

View File

@ -59,10 +59,24 @@ struct tm *get_time(void)
return timeinfo;
}
void get_time_str(uint8_t *buf)
/*Puts the current time in buf in the format of [Hour:Min:Sec] */
void get_time_str(uint8_t *buf, int bufsize)
{
const char *t = user_settings->time == TIME_12 ? "[%-I:%M:%S] " : "[%H:%M:%S] ";
strftime(buf, TIME_STR_SIZE, t, get_time());
strftime(buf, bufsize, t, get_time());
}
/* Converts seconds to hours:minutes:seconds string */
void get_elapsed_time_str(uint8_t *buf, int bufsize, uint64_t secs)
{
if (!secs)
return;
uint64_t seconds = secs % 60;
uint64_t minutes = (secs % 3600) / 60;
uint64_t hours = secs / 3600;
snprintf(buf, bufsize, "%.2ld:%.2ld:%.2ld", hours, minutes, seconds);
}
char *hex_string_to_bin(const char *hex_string)

View File

@ -40,7 +40,10 @@ char *hex_string_to_bin(const char *hex_string);
uint64_t get_unix_time(void);
/*Puts the current time in buf in the format of [Hour:Min:Sec] */
void get_time_str(uint8_t *buf);
void get_time_str(uint8_t *buf, int bufsize);
/* Converts seconds to hours:minutes:seconds string */
void get_elapsed_time_str(uint8_t *buf, int bufsize, uint64_t secs);
/* get the current local time */
struct tm *get_time(void);

View File

@ -372,7 +372,7 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum
nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
uint8_t *msg;
if (status == 1) {
@ -393,7 +393,7 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const uint8_t *key,
ChatContext *ctx = self->chatwin;
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
get_time_str(timefrmt, sizeof(timefrmt));
uint8_t msg[MAX_STR_SIZE];
snprintf(msg, sizeof(msg), "Friend request with the message '%s'", data);

View File

@ -110,6 +110,7 @@ struct ToxWindow {
int call_idx; /* If in a call will have this index set, otherwise it's -1.
* Don't modify outside av callbacks. */
int device_selection[2]; /* -1 if not set, if set uses these selections instead of primary device */
#endif /* _SUPPORT_AUDIO */
char name[TOX_MAX_NAME_LENGTH];
@ -129,7 +130,6 @@ struct ToxWindow {
ChatContext *chatwin;
StatusBar *stb;
WINDOW *popup;
WINDOW *window;
};
@ -144,6 +144,23 @@ struct StatusBar {
bool is_online;
};
#ifdef _SUPPORT_AUDIO
/* holds display info for audio calls */
struct infobox {
float vad_lvl;
bool in_is_muted;
bool out_is_muted;
bool hide;
bool active;
uint64_t calltime;
uint64_t deltatime;
char timestr[TIME_STR_SIZE];
WINDOW *win;
};
#endif
#define MAX_LINE_HIST 128
/* chat and groupchat window/buffer holder */
@ -160,6 +177,10 @@ struct ChatContext {
struct history *hst;
struct chatlog *log;
#ifdef _SUPPORT_AUDIO
struct infobox infobox;
#endif
uint8_t self_is_typing;
WINDOW *history;