mirror of
https://github.com/Tha14/toxic.git
synced 2024-12-23 16:43:24 +01:00
Merge remote-tracking branch 'origin/master' into keybinds
This commit is contained in:
commit
a0cde4ae8c
Binary file not shown.
Binary file not shown.
BIN
sounds/Error.wav
BIN
sounds/Error.wav
Binary file not shown.
Binary file not shown.
BIN
sounds/LogIn.wav
BIN
sounds/LogIn.wav
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -78,7 +78,7 @@ struct _ASettings {
|
|||||||
|
|
||||||
ToxAv *av;
|
ToxAv *av;
|
||||||
|
|
||||||
ToxAvCodecSettings cs;
|
ToxAvCSettings cs;
|
||||||
|
|
||||||
Call calls[MAX_CALLS];
|
Call calls[MAX_CALLS];
|
||||||
} ASettins;
|
} ASettins;
|
||||||
@ -173,8 +173,11 @@ void read_device_callback (const int16_t* captured, uint32_t size, void* data)
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (ASettins.calls[call_index].ttas)
|
if (call_index >= 0 && ASettins.calls[call_index].ttas) {
|
||||||
write_out(ASettins.calls[call_index].out_idx, data, size, 1);
|
ToxAvCSettings csettings = ASettins.cs;
|
||||||
|
toxav_get_peer_csettings(av, call_index, 0, &csettings);
|
||||||
|
write_out(ASettins.calls[call_index].out_idx, data, size, csettings.audio_channels);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int start_transmission(ToxWindow *self)
|
int start_transmission(ToxWindow *self)
|
||||||
@ -182,7 +185,7 @@ int start_transmission(ToxWindow *self)
|
|||||||
if ( !ASettins.av || self->call_idx == -1 ) return -1;
|
if ( !ASettins.av || self->call_idx == -1 ) return -1;
|
||||||
|
|
||||||
/* Don't provide support for video */
|
/* Don't provide support for video */
|
||||||
if ( 0 != toxav_prepare_transmission(ASettins.av, self->call_idx, &ASettins.cs, 0) ) {
|
if ( 0 != toxav_prepare_transmission(ASettins.av, self->call_idx, av_jbufdc * 2, av_VADd, 0) ) {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Could not prepare transmission");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Could not prepare transmission");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,8 +195,11 @@ int start_transmission(ToxWindow *self)
|
|||||||
|
|
||||||
set_call(&ASettins.calls[self->call_idx], _True);
|
set_call(&ASettins.calls[self->call_idx], _True);
|
||||||
|
|
||||||
|
ToxAvCSettings csettings;
|
||||||
|
toxav_get_peer_csettings(ASettins.av, self->call_idx, 0, &csettings);
|
||||||
|
|
||||||
if ( open_primary_device(input, &ASettins.calls[self->call_idx].in_idx,
|
if ( open_primary_device(input, &ASettins.calls[self->call_idx].in_idx,
|
||||||
av_DefaultSettings.audio_sample_rate, av_DefaultSettings.audio_frame_duration) != de_None )
|
csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None )
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open input device!");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open input device!");
|
||||||
|
|
||||||
if ( register_device_callback(self->call_idx, ASettins.calls[self->call_idx].in_idx,
|
if ( register_device_callback(self->call_idx, ASettins.calls[self->call_idx].in_idx,
|
||||||
@ -202,7 +208,7 @@ int start_transmission(ToxWindow *self)
|
|||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to register input handler!");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to register input handler!");
|
||||||
|
|
||||||
if ( open_primary_device(output, &ASettins.calls[self->call_idx].out_idx,
|
if ( open_primary_device(output, &ASettins.calls[self->call_idx].out_idx,
|
||||||
av_DefaultSettings.audio_sample_rate, av_DefaultSettings.audio_frame_duration) != de_None ) {
|
csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels) != de_None ) {
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open output device!");
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to open output device!");
|
||||||
ASettins.calls[self->call_idx].has_output = 0;
|
ASettins.calls[self->call_idx].has_output = 0;
|
||||||
}
|
}
|
||||||
@ -345,7 +351,7 @@ void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
|
|||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToxAvError error = toxav_call(ASettins.av, &self->call_idx, self->num, TypeAudio, 30);
|
ToxAvError error = toxav_call(ASettins.av, &self->call_idx, self->num, &ASettins.cs, 30);
|
||||||
|
|
||||||
if ( error != ErrorNone ) {
|
if ( error != ErrorNone ) {
|
||||||
if ( error == ErrorAlreadyInCall ) error_str = "Already in a call!";
|
if ( error == ErrorAlreadyInCall ) error_str = "Already in a call!";
|
||||||
@ -376,7 +382,7 @@ void cmd_answer(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
|
|||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToxAvError error = toxav_answer(ASettins.av, self->call_idx, TypeAudio);
|
ToxAvError error = toxav_answer(ASettins.av, self->call_idx, &ASettins.cs);
|
||||||
|
|
||||||
if ( error != ErrorNone ) {
|
if ( error != ErrorNone ) {
|
||||||
if ( error == ErrorInvalidState ) error_str = "Cannot answer in invalid state!";
|
if ( error == ErrorInvalidState ) error_str = "Cannot answer in invalid state!";
|
||||||
@ -615,19 +621,23 @@ void cmd_ccur_device(WINDOW * window, ToxWindow * self, Tox *m, int argc, char (
|
|||||||
if ( self->call_idx > -1) {
|
if ( self->call_idx > -1) {
|
||||||
Call* this_call = &ASettins.calls[self->call_idx];
|
Call* this_call = &ASettins.calls[self->call_idx];
|
||||||
if (this_call->ttas) {
|
if (this_call->ttas) {
|
||||||
|
|
||||||
|
ToxAvCSettings csettings;
|
||||||
|
toxav_get_peer_csettings(ASettins.av, self->call_idx, 0, &csettings);
|
||||||
|
|
||||||
if (type == output) {
|
if (type == output) {
|
||||||
pthread_mutex_lock(&this_call->mutex);
|
pthread_mutex_lock(&this_call->mutex);
|
||||||
close_device(output, this_call->out_idx);
|
close_device(output, this_call->out_idx);
|
||||||
this_call->has_output = open_device(output, selection, &this_call->out_idx,
|
this_call->has_output = open_device(output, selection, &this_call->out_idx,
|
||||||
av_DefaultSettings.audio_sample_rate, av_DefaultSettings.audio_frame_duration)
|
csettings.audio_sample_rate, csettings.audio_frame_duration, csettings.audio_channels)
|
||||||
== de_None ? 1 : 0;
|
== de_None ? 1 : 0;
|
||||||
pthread_mutex_unlock(&this_call->mutex);
|
pthread_mutex_unlock(&this_call->mutex);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* TODO: check for failure */
|
/* TODO: check for failure */
|
||||||
close_device(input, this_call->in_idx);
|
close_device(input, this_call->in_idx);
|
||||||
open_device(input, selection, &this_call->in_idx,
|
open_device(input, selection, &this_call->in_idx, csettings.audio_sample_rate,
|
||||||
av_DefaultSettings.audio_sample_rate, av_DefaultSettings.audio_frame_duration);
|
csettings.audio_frame_duration, csettings.audio_channels);
|
||||||
/* Set VAD as true for all; TODO: Make it more dynamic */
|
/* Set VAD as true for all; TODO: Make it more dynamic */
|
||||||
register_device_callback(self->call_idx, this_call->in_idx, read_device_callback, &self->call_idx, _True);
|
register_device_callback(self->call_idx, this_call->in_idx, read_device_callback, &self->call_idx, _True);
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* transforms a sendfile tab complete contaning the shorthand "~/" into the full home directory.*/
|
/* transforms a sendfile tab complete contaning the shorthand "~/" into the full home directory.*/
|
||||||
static void complt_home_dir(ToxWindow *self, char *path)
|
static void complt_home_dir(ToxWindow *self, char *path, int pathsize)
|
||||||
{
|
{
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
@ -210,8 +210,8 @@ static void complt_home_dir(ToxWindow *self, char *path)
|
|||||||
get_home_dir(homedir, sizeof(homedir));
|
get_home_dir(homedir, sizeof(homedir));
|
||||||
|
|
||||||
char newline[MAX_STR_SIZE];
|
char newline[MAX_STR_SIZE];
|
||||||
const char *isqt = !strchr(path, '\"') ? "\"" : "";
|
snprintf(newline, sizeof(newline), "/sendfile \"%s%s", homedir, path + 1);
|
||||||
snprintf(newline, sizeof(newline), "/sendfile %s%s/", isqt, homedir);
|
snprintf(path, pathsize, "%s", &newline[11]);
|
||||||
|
|
||||||
wchar_t wline[MAX_STR_SIZE];
|
wchar_t wline[MAX_STR_SIZE];
|
||||||
|
|
||||||
@ -231,22 +231,20 @@ static void complt_home_dir(ToxWindow *self, char *path)
|
|||||||
/* attempts to match /sendfile "<incomplete-dir>" line to matching directories.
|
/* attempts to match /sendfile "<incomplete-dir>" line to matching directories.
|
||||||
|
|
||||||
if only one match, auto-complete line.
|
if only one match, auto-complete line.
|
||||||
return diff between old len and new len of ctx->line, -1 if no matches
|
return diff between old len and new len of ctx->line, -1 if no matches or > 1 match */
|
||||||
*/
|
#define MAX_DIRS 512
|
||||||
#define MAX_DIRS 256
|
|
||||||
|
|
||||||
int dir_match(ToxWindow *self, Tox *m, wchar_t *line)
|
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line)
|
||||||
{
|
{
|
||||||
char b_path[MAX_STR_SIZE];
|
char b_path[MAX_STR_SIZE];
|
||||||
char b_name[MAX_STR_SIZE];
|
char b_name[MAX_STR_SIZE];
|
||||||
|
const wchar_t *tmpline = &line[11]; /* start after "/sendfile \"" */
|
||||||
|
|
||||||
if (wcs_to_mbs_buf(b_path, line, sizeof(b_path)) == -1)
|
if (wcs_to_mbs_buf(b_path, tmpline, sizeof(b_path)) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!strncmp(b_path, "\"~/", 3) || !strncmp(b_path, "~/", 2)) {
|
if (!strncmp(b_path, "~/", 2))
|
||||||
complt_home_dir(self, b_path);
|
complt_home_dir(self, b_path, sizeof(b_path));
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int si = char_rfind(b_path, '/', strlen(b_path));
|
int si = char_rfind(b_path, '/', strlen(b_path));
|
||||||
|
|
||||||
|
@ -33,11 +33,10 @@
|
|||||||
Returns the difference between the old len and new len of line on success, -1 if error */
|
Returns the difference between the old len and new len of line on success, -1 if error */
|
||||||
int complete_line(ToxWindow *self, const void *list, int n_items, int size);
|
int complete_line(ToxWindow *self, const void *list, int n_items, int size);
|
||||||
|
|
||||||
/* matches /sendfile "<incomplete-dir>" line to matching directories.
|
/* attempts to match /sendfile "<incomplete-dir>" line to matching directories.
|
||||||
|
|
||||||
if only one match, auto-complete line.
|
if only one match, auto-complete line.
|
||||||
return diff between old len and new len of ctx->line, or -1 if no matches
|
return diff between old len and new len of ctx->line, -1 if no matches or > 1 match */
|
||||||
*/
|
|
||||||
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line);
|
int dir_match(ToxWindow *self, Tox *m, const wchar_t *line);
|
||||||
|
|
||||||
#endif /* #define _autocomplete_h */
|
#endif /* #define _autocomplete_h */
|
@ -423,7 +423,7 @@ static void chat_onFileData(ToxWindow *self, Tox *m, int32_t num, uint8_t filenu
|
|||||||
if (!remain || timed_out(friends[num].file_receiver.last_progress[filenum], curtime, 1)) {
|
if (!remain || timed_out(friends[num].file_receiver.last_progress[filenum], curtime, 1)) {
|
||||||
friends[num].file_receiver.last_progress[filenum] = curtime;
|
friends[num].file_receiver.last_progress[filenum] = curtime;
|
||||||
uint64_t size = friends[num].file_receiver.size[filenum];
|
uint64_t size = friends[num].file_receiver.size[filenum];
|
||||||
double pct_remain = remain ? (1 - (remain / size)) * 100 : 100;
|
double pct_remain = remain > 0 ? (1 - (remain / size)) * 100 : 100;
|
||||||
print_progress_bar(self, filenum, num, pct_remain);
|
print_progress_bar(self, filenum, num, pct_remain);
|
||||||
friends[num].file_receiver.bps[filenum] = 0;
|
friends[num].file_receiver.bps[filenum] = 0;
|
||||||
}
|
}
|
||||||
@ -756,10 +756,9 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
|
|
||||||
if (key == '\t' && ctx->len > 1 && ctx->line[0] == '/') { /* TAB key: auto-complete */
|
if (key == '\t' && ctx->len > 1 && ctx->line[0] == '/') { /* TAB key: auto-complete */
|
||||||
int diff = -1;
|
int diff = -1;
|
||||||
int sf_len = 11;
|
|
||||||
|
|
||||||
if (wcsncmp(ctx->line, L"/sendfile \"", sf_len) == 0) {
|
if (wcsncmp(ctx->line, L"/sendfile \"", wcslen(L"/sendfile \"")) == 0) {
|
||||||
diff = dir_match(self, m, &ctx->line[sf_len]);
|
diff = dir_match(self, m, ctx->line);
|
||||||
} else {
|
} else {
|
||||||
diff = complete_line(self, chat_cmd_list, AC_NUM_CHAT_COMMANDS, MAX_CMDNAME_SIZE);
|
diff = complete_line(self, chat_cmd_list, AC_NUM_CHAT_COMMANDS, MAX_CMDNAME_SIZE);
|
||||||
}
|
}
|
||||||
@ -770,7 +769,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') {
|
||||||
|
@ -37,6 +37,7 @@ extern ToxicFriend friends[MAX_FRIENDS_NUM];
|
|||||||
|
|
||||||
extern FileSender file_senders[MAX_FILES];
|
extern FileSender file_senders[MAX_FILES];
|
||||||
extern uint8_t max_file_senders_index;
|
extern uint8_t max_file_senders_index;
|
||||||
|
extern uint8_t num_active_file_senders;
|
||||||
|
|
||||||
void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_groupinvite(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
@ -209,6 +210,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
|
|
||||||
for (i = 0; i < MAX_FILES; ++i) {
|
for (i = 0; i < MAX_FILES; ++i) {
|
||||||
if (!file_senders[i].active) {
|
if (!file_senders[i].active) {
|
||||||
|
file_senders[i].queue_pos = num_active_file_senders;
|
||||||
memcpy(file_senders[i].pathname, path, path_len + 1);
|
memcpy(file_senders[i].pathname, path, path_len + 1);
|
||||||
file_senders[i].active = true;
|
file_senders[i].active = true;
|
||||||
file_senders[i].toxwin = self;
|
file_senders[i].toxwin = self;
|
||||||
@ -223,6 +225,8 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
|
|||||||
const char *msg = "Sending file: '%s'";
|
const char *msg = "Sending file: '%s'";
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg, path);
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg, path);
|
||||||
|
|
||||||
|
++num_active_file_senders;
|
||||||
|
|
||||||
if (i == max_file_senders_index)
|
if (i == max_file_senders_index)
|
||||||
++max_file_senders_index;
|
++max_file_senders_index;
|
||||||
|
|
||||||
|
18
src/device.c
18
src/device.c
@ -63,6 +63,7 @@ typedef struct _Device {
|
|||||||
pthread_mutex_t mutex[1];
|
pthread_mutex_t mutex[1];
|
||||||
uint32_t sample_rate;
|
uint32_t sample_rate;
|
||||||
uint32_t frame_duration;
|
uint32_t frame_duration;
|
||||||
|
int32_t sound_mode;
|
||||||
#ifdef _AUDIO
|
#ifdef _AUDIO
|
||||||
float VAD_treshold; /* 40 is usually recommended value */
|
float VAD_treshold; /* 40 is usually recommended value */
|
||||||
#endif
|
#endif
|
||||||
@ -194,17 +195,19 @@ DeviceError set_primary_device(DeviceType type, int32_t selection)
|
|||||||
return de_None;
|
return de_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceError open_primary_device(DeviceType type, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration)
|
DeviceError open_primary_device(DeviceType type, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration, uint8_t channels)
|
||||||
{
|
{
|
||||||
return open_device(type, primary_device[type], device_idx, sample_rate, frame_duration);
|
return open_device(type, primary_device[type], device_idx, sample_rate, frame_duration, channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: generate buffers separately
|
// TODO: generate buffers separately
|
||||||
DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration)
|
DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration, uint8_t channels)
|
||||||
{
|
{
|
||||||
if (size[type] <= selection || selection < 0) return de_InvalidSelection;
|
if (size[type] <= selection || selection < 0) return de_InvalidSelection;
|
||||||
|
|
||||||
|
if (channels != 1 && channels != 2) return de_UnsupportedMode;
|
||||||
|
|
||||||
lock;
|
lock;
|
||||||
|
|
||||||
const uint32_t frame_size = (sample_rate * frame_duration / 1000);
|
const uint32_t frame_size = (sample_rate * frame_duration / 1000);
|
||||||
@ -220,6 +223,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
|||||||
|
|
||||||
device->sample_rate = sample_rate;
|
device->sample_rate = sample_rate;
|
||||||
device->frame_duration = frame_duration;
|
device->frame_duration = frame_duration;
|
||||||
|
device->sound_mode = channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
||||||
|
|
||||||
for (i = 0; i < *device_idx; i ++) { /* Check if any previous has the same selection */
|
for (i = 0; i < *device_idx; i ++) { /* Check if any previous has the same selection */
|
||||||
if ( running[type][i]->selection == selection ) {
|
if ( running[type][i]->selection == selection ) {
|
||||||
@ -238,7 +242,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
|||||||
|
|
||||||
if (type == input) {
|
if (type == input) {
|
||||||
device->dhndl = alcCaptureOpenDevice(devices_names[type][selection],
|
device->dhndl = alcCaptureOpenDevice(devices_names[type][selection],
|
||||||
sample_rate, AL_FORMAT_MONO16, frame_size * 2);
|
sample_rate, device->sound_mode, frame_size * 2);
|
||||||
#ifdef _AUDIO
|
#ifdef _AUDIO
|
||||||
device->VAD_treshold = user_settings_->VAD_treshold;
|
device->VAD_treshold = user_settings_->VAD_treshold;
|
||||||
#endif
|
#endif
|
||||||
@ -263,7 +267,7 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
|||||||
memset(zeros, 0, frame_size*2);
|
memset(zeros, 0, frame_size*2);
|
||||||
|
|
||||||
for ( i =0; i < OPENAL_BUFS; ++i) {
|
for ( i =0; i < OPENAL_BUFS; ++i) {
|
||||||
alBufferData(device->buffers[i], AL_FORMAT_MONO16, zeros, frame_size*2, sample_rate);
|
alBufferData(device->buffers[i], device->sound_mode, zeros, frame_size*2, sample_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
alSourceQueueBuffers(device->source, OPENAL_BUFS, device->buffers);
|
alSourceQueueBuffers(device->source, OPENAL_BUFS, device->buffers);
|
||||||
@ -372,7 +376,7 @@ inline__ DeviceError write_out(uint32_t device_idx, int16_t* data, uint32_t leng
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
alBufferData(bufid, AL_FORMAT_MONO16, data, lenght * 2 * channels, device->sample_rate);
|
alBufferData(bufid, device->sound_mode, data, lenght * 2 * channels, device->sample_rate);
|
||||||
alSourceQueueBuffers(device->source, 1, &bufid);
|
alSourceQueueBuffers(device->source, 1, &bufid);
|
||||||
|
|
||||||
ALint state;
|
ALint state;
|
||||||
@ -415,7 +419,7 @@ void* thread_poll (void* arg) // TODO: maybe use thread for every input source
|
|||||||
}
|
}
|
||||||
Device* device = running[input][i];
|
Device* device = running[input][i];
|
||||||
|
|
||||||
int16_t frame[4096];
|
int16_t frame[16000];
|
||||||
alcCaptureSamples(device->dhndl, frame, f_size);
|
alcCaptureSamples(device->dhndl, frame, f_size);
|
||||||
|
|
||||||
if ( device->muted
|
if ( device->muted
|
||||||
|
@ -50,7 +50,8 @@ typedef enum DeviceError {
|
|||||||
de_AllDevicesBusy = -5,
|
de_AllDevicesBusy = -5,
|
||||||
de_DeviceNotActive = -6,
|
de_DeviceNotActive = -6,
|
||||||
de_BufferError = -7,
|
de_BufferError = -7,
|
||||||
de_AlError = -8,
|
de_UnsupportedMode = -8,
|
||||||
|
de_AlError = -9,
|
||||||
} DeviceError;
|
} DeviceError;
|
||||||
|
|
||||||
typedef void (*DataHandleCallback) (const int16_t*, uint32_t size, void* data);
|
typedef void (*DataHandleCallback) (const int16_t*, uint32_t size, void* data);
|
||||||
@ -76,9 +77,9 @@ DeviceError device_set_VAD_treshold(uint32_t device_idx, float value);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DeviceError set_primary_device(DeviceType type, int32_t selection);
|
DeviceError set_primary_device(DeviceType type, int32_t selection);
|
||||||
DeviceError open_primary_device(DeviceType type, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration);
|
DeviceError open_primary_device(DeviceType type, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration, uint8_t channels);
|
||||||
/* Start device */
|
/* Start device */
|
||||||
DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration);
|
DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx, uint32_t sample_rate, uint32_t frame_duration, uint8_t channels);
|
||||||
/* Stop device */
|
/* Stop device */
|
||||||
DeviceError close_device(DeviceType type, uint32_t device_idx);
|
DeviceError close_device(DeviceType type, uint32_t device_idx);
|
||||||
|
|
||||||
|
@ -35,13 +35,15 @@
|
|||||||
|
|
||||||
FileSender file_senders[MAX_FILES];
|
FileSender file_senders[MAX_FILES];
|
||||||
uint8_t max_file_senders_index;
|
uint8_t max_file_senders_index;
|
||||||
|
uint8_t num_active_file_senders;
|
||||||
extern ToxicFriend friends[MAX_FRIENDS_NUM];
|
extern ToxicFriend friends[MAX_FRIENDS_NUM];
|
||||||
|
|
||||||
#define KiB 1024
|
#define KiB 1024
|
||||||
#define MiB 1048576 /* 1024 ^ 2 */
|
#define MiB 1048576 /* 1024 ^ 2 */
|
||||||
#define GiB 1073741824 /* 1024 ^ 3 */
|
#define GiB 1073741824 /* 1024 ^ 3 */
|
||||||
|
|
||||||
/* creates initial progress line that will be updated during file transfer. */
|
/* creates initial progress line that will be updated during file transfer.
|
||||||
|
Assumes progline is of size MAX_STR_SIZE */
|
||||||
void prep_prog_line(char *progline)
|
void prep_prog_line(char *progline)
|
||||||
{
|
{
|
||||||
strcpy(progline, "0.0 B/s [");
|
strcpy(progline, "0.0 B/s [");
|
||||||
@ -127,6 +129,7 @@ static void close_file_sender(ToxWindow *self, Tox *m, int i, char *msg, int CTR
|
|||||||
fclose(file_senders[i].file);
|
fclose(file_senders[i].file);
|
||||||
memset(&file_senders[i], 0, sizeof(FileSender));
|
memset(&file_senders[i], 0, sizeof(FileSender));
|
||||||
set_max_file_senders_index();
|
set_max_file_senders_index();
|
||||||
|
--num_active_file_senders;
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_all_file_senders(Tox *m)
|
void close_all_file_senders(Tox *m)
|
||||||
@ -145,33 +148,15 @@ void close_all_file_senders(Tox *m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void do_file_senders(Tox *m)
|
static void send_file_data(ToxWindow *self, Tox *m, int i, int32_t friendnum, int filenum, const char *pathname)
|
||||||
{
|
{
|
||||||
char msg[MAX_STR_SIZE];
|
char msg[MAX_STR_SIZE];
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < max_file_senders_index; ++i) {
|
|
||||||
if (!file_senders[i].active)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ToxWindow *self = file_senders[i].toxwin;
|
|
||||||
char *pathname = file_senders[i].pathname;
|
|
||||||
int filenum = file_senders[i].filenum;
|
|
||||||
int32_t friendnum = file_senders[i].friendnum;
|
|
||||||
FILE *fp = file_senders[i].file;
|
FILE *fp = file_senders[i].file;
|
||||||
|
|
||||||
/* If file transfer has timed out kill transfer and send kill control */
|
|
||||||
if (timed_out(file_senders[i].timestamp, get_unix_time(), TIMEOUT_FILESENDER)) {
|
|
||||||
snprintf(msg, sizeof(msg), "File transfer for '%s' timed out.", pathname);
|
|
||||||
close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, friendnum);
|
|
||||||
notify(self, error, NT_NOFOCUS | NT_WNDALERT_2);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (tox_file_send_data(m, friendnum, filenum, (uint8_t *) file_senders[i].nextpiece,
|
if (tox_file_send_data(m, friendnum, filenum, (uint8_t *) file_senders[i].nextpiece,
|
||||||
file_senders[i].piecelen) == -1)
|
file_senders[i].piecelen) == -1)
|
||||||
break;
|
return;
|
||||||
|
|
||||||
uint64_t curtime = get_unix_time();
|
uint64_t curtime = get_unix_time();
|
||||||
file_senders[i].timestamp = curtime;
|
file_senders[i].timestamp = curtime;
|
||||||
@ -184,7 +169,7 @@ void do_file_senders(Tox *m)
|
|||||||
/* refresh line with percentage complete and transfer speed (must be called once per second) */
|
/* refresh line with percentage complete and transfer speed (must be called once per second) */
|
||||||
if ((self->chatwin != NULL && timed_out(file_senders[i].last_progress, curtime, 1)) || !remain) {
|
if ((self->chatwin != NULL && timed_out(file_senders[i].last_progress, curtime, 1)) || !remain) {
|
||||||
file_senders[i].last_progress = curtime;
|
file_senders[i].last_progress = curtime;
|
||||||
double pct_remain = remain ? (1 - (remain / file_senders[i].size)) * 100 : 100;
|
double pct_remain = remain > 0 ? (1 - (remain / file_senders[i].size)) * 100 : 100;
|
||||||
print_progress_bar(self, i, -1, pct_remain);
|
print_progress_bar(self, i, -1, pct_remain);
|
||||||
file_senders[i].bps = 0;
|
file_senders[i].bps = 0;
|
||||||
}
|
}
|
||||||
@ -193,8 +178,39 @@ void do_file_senders(Tox *m)
|
|||||||
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);
|
notify(self, transfer_completed, NT_NOFOCUS | NT_WNDALERT_2);
|
||||||
break;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void do_file_senders(Tox *m)
|
||||||
|
{
|
||||||
|
char msg[MAX_STR_SIZE];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < max_file_senders_index; ++i) {
|
||||||
|
if (!file_senders[i].active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (file_senders[i].queue_pos > 0) {
|
||||||
|
--file_senders[i].queue_pos;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToxWindow *self = file_senders[i].toxwin;
|
||||||
|
char *pathname = file_senders[i].pathname;
|
||||||
|
int filenum = file_senders[i].filenum;
|
||||||
|
int32_t friendnum = file_senders[i].friendnum;
|
||||||
|
|
||||||
|
/* If file transfer has timed out kill transfer and send kill control */
|
||||||
|
if (timed_out(file_senders[i].timestamp, get_unix_time(), TIMEOUT_FILESENDER)) {
|
||||||
|
snprintf(msg, sizeof(msg), "File transfer for '%s' timed out.", pathname);
|
||||||
|
close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, friendnum);
|
||||||
|
notify(self, error, NT_NOFOCUS | NT_WNDALERT_2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_senders[i].queue_pos = num_active_file_senders - 1;
|
||||||
|
send_file_data(self, m, i, friendnum, filenum, pathname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -45,9 +45,11 @@ typedef struct {
|
|||||||
double bps;
|
double bps;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint32_t line_id;
|
uint32_t line_id;
|
||||||
|
uint8_t queue_pos;
|
||||||
} FileSender;
|
} FileSender;
|
||||||
|
|
||||||
/* creates progress line that will be updated during file transfer. */
|
/* creates initial progress line that will be updated during file transfer.
|
||||||
|
Assumes progline is of size MAX_STR_SIZE */
|
||||||
void prep_prog_line(char *progline);
|
void prep_prog_line(char *progline);
|
||||||
|
|
||||||
/* prints a progress bar for file transfers.
|
/* prints a progress bar for file transfers.
|
||||||
|
@ -363,10 +363,10 @@ static void groupchat_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 {
|
} else {
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
}
|
}
|
||||||
} else if (key == user_settings_->key_peer_list_down) { /* Scroll peerlist up and down one position */
|
} else if (key == user_settings_->key_peer_list_down) { /* Scroll peerlist up and down one position */
|
||||||
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
|
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
|
||||||
|
15
src/input.c
15
src/input.c
@ -31,6 +31,7 @@
|
|||||||
#include "misc_tools.h"
|
#include "misc_tools.h"
|
||||||
#include "toxic_strings.h"
|
#include "toxic_strings.h"
|
||||||
#include "line_info.h"
|
#include "line_info.h"
|
||||||
|
#include "notify.h"
|
||||||
|
|
||||||
/* add a char to input field and buffer */
|
/* add a char to input field and buffer */
|
||||||
void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
|
void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
|
||||||
@ -41,12 +42,12 @@ void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_
|
|||||||
|
|
||||||
/* this is the only place we need to do this check */
|
/* this is the only place we need to do this check */
|
||||||
if (cur_len == -1) {
|
if (cur_len == -1) {
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_char_to_buf(ctx, key) == -1) {
|
if (add_char_to_buf(ctx, key) == -1) {
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ static void input_backspace(ToxWindow *self, int x, int mx_x)
|
|||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
if (del_char_buf_bck(ctx) == -1) {
|
if (del_char_buf_bck(ctx) == -1) {
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,21 +80,21 @@ static void input_backspace(ToxWindow *self, int x, int mx_x)
|
|||||||
static void input_delete(ToxWindow *self)
|
static void input_delete(ToxWindow *self)
|
||||||
{
|
{
|
||||||
if (del_char_buf_frnt(self->chatwin) == -1)
|
if (del_char_buf_frnt(self->chatwin) == -1)
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* deletes entire line before cursor from input field and buffer */
|
/* deletes entire line before cursor from input field and buffer */
|
||||||
static void input_discard(ToxWindow *self)
|
static void input_discard(ToxWindow *self)
|
||||||
{
|
{
|
||||||
if (discard_buf(self->chatwin) == -1)
|
if (discard_buf(self->chatwin) == -1)
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* deletes entire line after cursor from input field and buffer */
|
/* deletes entire line after cursor from input field and buffer */
|
||||||
static void input_kill(ChatContext *ctx)
|
static void input_kill(ChatContext *ctx)
|
||||||
{
|
{
|
||||||
if (kill_buf(ctx) == -1)
|
if (kill_buf(ctx) == -1)
|
||||||
beep();
|
notify(NULL, error, NT_ALWAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void input_yank(ToxWindow *self, int x, int mx_x)
|
static void input_yank(ToxWindow *self, int x, int mx_x)
|
||||||
@ -101,7 +102,7 @@ static void input_yank(ToxWindow *self, int x, int mx_x)
|
|||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
if (yank_buf(ctx) == -1) {
|
if (yank_buf(ctx) == -1) {
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "line_info.h"
|
#include "line_info.h"
|
||||||
#include "groupchat.h"
|
#include "groupchat.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "notify.h"
|
||||||
|
|
||||||
extern struct user_settings *user_settings_;
|
extern struct user_settings *user_settings_;
|
||||||
|
|
||||||
@ -420,14 +421,14 @@ static void line_info_scroll_up(struct history *hst)
|
|||||||
{
|
{
|
||||||
if (hst->line_start->prev)
|
if (hst->line_start->prev)
|
||||||
hst->line_start = hst->line_start->prev;
|
hst->line_start = hst->line_start->prev;
|
||||||
else beep();
|
else notify(NULL, error, NT_ALWAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void line_info_scroll_down(struct history *hst)
|
static void line_info_scroll_down(struct history *hst)
|
||||||
{
|
{
|
||||||
if (hst->line_start->next)
|
if (hst->line_start->next)
|
||||||
hst->line_start = hst->line_start->next;
|
hst->line_start = hst->line_start->next;
|
||||||
else beep();
|
else notify(NULL, error, NT_ALWAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void line_info_page_up(ToxWindow *self, struct history *hst)
|
static void line_info_page_up(ToxWindow *self, struct history *hst)
|
||||||
|
186
src/notify.c
186
src/notify.c
@ -28,34 +28,43 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef _AUDIO
|
||||||
|
#ifdef __APPLE__
|
||||||
#include <OpenAL/al.h>
|
#include <OpenAL/al.h>
|
||||||
#include <OpenAL/alc.h>
|
#include <OpenAL/alc.h>
|
||||||
#ifdef _SOUND_NOTIFY
|
#ifdef _SOUND_NOTIFY
|
||||||
#include <OpenAL/alut.h> /* Is this good? */
|
#include <OpenAL/alut.h> /* Is this good? */
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
#ifdef _SOUND_NOTIFY
|
#ifdef _SOUND_NOTIFY
|
||||||
#include <AL/alut.h> /* freealut packet */
|
#include <AL/alut.h> /* freealut packet */
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* _AUDIO */
|
||||||
|
|
||||||
#ifdef _X11
|
#ifdef _X11
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#endif /* _X11 */
|
#endif /* _X11 */
|
||||||
|
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
#include <libnotify/notify.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SOUNDS_SIZE 10
|
#define SOUNDS_SIZE 10
|
||||||
#define ACTIVE_SOUNDS_MAX 50
|
#define ACTIVE_NOTIFS_MAX 50
|
||||||
|
|
||||||
extern struct user_settings *user_settings_;
|
extern struct user_settings *user_settings_;
|
||||||
|
|
||||||
struct _Control {
|
struct _Control {
|
||||||
time_t cooldown;
|
time_t cooldown;
|
||||||
|
time_t notif_timeout;
|
||||||
unsigned long this_window;
|
unsigned long this_window;
|
||||||
#ifdef _X11
|
#ifdef _X11
|
||||||
Display *display;
|
Display *display;
|
||||||
@ -69,14 +78,22 @@ struct _Control {
|
|||||||
#endif /* _SOUND_NOTIFY */
|
#endif /* _SOUND_NOTIFY */
|
||||||
} Control = {0};
|
} Control = {0};
|
||||||
|
|
||||||
|
struct _ActiveNotifications {
|
||||||
#ifdef _SOUND_NOTIFY
|
#ifdef _SOUND_NOTIFY
|
||||||
struct _ActiveSounds {
|
|
||||||
uint32_t source;
|
uint32_t source;
|
||||||
uint32_t buffer;
|
uint32_t buffer;
|
||||||
_Bool active;
|
_Bool active;
|
||||||
_Bool looping;
|
_Bool looping;
|
||||||
} actives[ACTIVE_SOUNDS_MAX] = {{0}};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
NotifyNotification* box;
|
||||||
|
char messages[128][128];
|
||||||
|
char title[24];
|
||||||
|
size_t size;
|
||||||
|
time_t timeout;
|
||||||
|
#endif
|
||||||
|
} actives[ACTIVE_NOTIFS_MAX] = {{0}};
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
/**********************************************************************************/
|
/**********************************************************************************/
|
||||||
@ -112,20 +129,27 @@ void graceful_clear()
|
|||||||
int i;
|
int i;
|
||||||
pthread_mutex_lock(Control.poll_mutex);
|
pthread_mutex_lock(Control.poll_mutex);
|
||||||
while (1) {
|
while (1) {
|
||||||
for (i = 0; i < ACTIVE_SOUNDS_MAX; i ++) {
|
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
|
||||||
if (actives[i].active) {
|
if (actives[i].active) {
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
if (actives[i].box) {
|
||||||
|
notify_notification_close(actives[i].box, NULL);
|
||||||
|
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( actives[i].looping ) {
|
if ( actives[i].looping ) {
|
||||||
stop_sound(i);
|
stop_sound(i);
|
||||||
} else {
|
} else {
|
||||||
if (!is_playing(actives[i].source))
|
if (!is_playing(actives[i].source))
|
||||||
memset(&actives[i], 0, sizeof(struct _ActiveSounds));
|
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == ACTIVE_SOUNDS_MAX) {
|
if (i == ACTIVE_NOTIFS_MAX) {
|
||||||
pthread_mutex_unlock(Control.poll_mutex);
|
pthread_mutex_unlock(Control.poll_mutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -140,17 +164,36 @@ void* do_playing(void* _p)
|
|||||||
int i;
|
int i;
|
||||||
while(Control.poll_active) {
|
while(Control.poll_active) {
|
||||||
pthread_mutex_lock(Control.poll_mutex);
|
pthread_mutex_lock(Control.poll_mutex);
|
||||||
for (i = 0; i < ACTIVE_SOUNDS_MAX; i ++) {
|
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
|
||||||
if (actives[i].active && !actives[i].looping) {
|
if (actives[i].active && !actives[i].looping
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
&& !actives[i].box
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
if (!is_playing(actives[i].source)) {
|
if (!is_playing(actives[i].source)) {
|
||||||
/* Close */
|
/* Close */
|
||||||
|
|
||||||
alSourceStop(actives[i].source);
|
alSourceStop(actives[i].source);
|
||||||
alDeleteSources(1, &actives[i].source);
|
alDeleteSources(1, &actives[i].source);
|
||||||
alDeleteBuffers(1,&actives[i].buffer);
|
alDeleteBuffers(1,&actives[i].buffer);
|
||||||
memset(&actives[i], 0, sizeof(struct _ActiveSounds));
|
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
else if (actives[i].box && !actives[i].looping &&
|
||||||
|
time(NULL) >= actives[i].timeout && !is_playing(actives[i].source))
|
||||||
|
{
|
||||||
|
alSourceStop(actives[i].source);
|
||||||
|
alDeleteSources(1, &actives[i].source);
|
||||||
|
alDeleteBuffers(1,&actives[i].buffer);
|
||||||
|
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
|
||||||
|
|
||||||
|
GError* ignore;
|
||||||
|
notify_notification_close(actives[i].box, &ignore);
|
||||||
|
memset(&actives[i], 0, sizeof(struct _ActiveNotifications));
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(Control.poll_mutex);
|
pthread_mutex_unlock(Control.poll_mutex);
|
||||||
usleep(10000);
|
usleep(10000);
|
||||||
@ -163,8 +206,8 @@ int play_source(uint32_t source, uint32_t buffer, _Bool looping)
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock(Control.poll_mutex);
|
pthread_mutex_lock(Control.poll_mutex);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < ACTIVE_SOUNDS_MAX && actives[i].active; i ++);
|
for (; i < ACTIVE_NOTIFS_MAX && actives[i].active; i ++);
|
||||||
if ( i == ACTIVE_SOUNDS_MAX ) {
|
if ( i == ACTIVE_NOTIFS_MAX ) {
|
||||||
pthread_mutex_unlock(Control.poll_mutex);
|
pthread_mutex_unlock(Control.poll_mutex);
|
||||||
return -1; /* Full */
|
return -1; /* Full */
|
||||||
}
|
}
|
||||||
@ -189,11 +232,11 @@ int play_source(uint32_t source, uint32_t buffer, _Bool looping)
|
|||||||
|
|
||||||
|
|
||||||
/* Opens primary device */
|
/* Opens primary device */
|
||||||
int init_notify(int login_cooldown)
|
int init_notify(int login_cooldown, int notification_timeout)
|
||||||
{
|
{
|
||||||
#ifdef _SOUND_NOTIFY
|
#ifdef _SOUND_NOTIFY
|
||||||
alutInitWithoutContext(NULL, NULL);
|
alutInitWithoutContext(NULL, NULL);
|
||||||
if (open_primary_device(output, &Control.device_idx, 48000, 20) != de_None)
|
if (open_primary_device(output, &Control.device_idx, 48000, 20, 1) != de_None)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
pthread_mutex_init(Control.poll_mutex, NULL);
|
pthread_mutex_init(Control.poll_mutex, NULL);
|
||||||
@ -214,6 +257,10 @@ int init_notify(int login_cooldown)
|
|||||||
#endif /* _X11 */
|
#endif /* _X11 */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
notify_init("toxic");
|
||||||
|
#endif
|
||||||
|
Control.notif_timeout = notification_timeout;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +277,11 @@ void terminate_notify()
|
|||||||
close_device(output, Control.device_idx);
|
close_device(output, Control.device_idx);
|
||||||
alutExit();
|
alutExit();
|
||||||
#endif /* _SOUND_NOTIFY */
|
#endif /* _SOUND_NOTIFY */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
notify_uninit();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _SOUND_NOTIFY
|
#ifdef _SOUND_NOTIFY
|
||||||
@ -271,7 +323,7 @@ int play_sound_internal(Notification what, _Bool loop)
|
|||||||
|
|
||||||
int play_notify_sound(Notification notif, uint64_t flags)
|
int play_notify_sound(Notification notif, uint64_t flags)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = -1;
|
||||||
|
|
||||||
if (flags & NT_BEEP) beep();
|
if (flags & NT_BEEP) beep();
|
||||||
else if (notif != silent) {
|
else if (notif != silent) {
|
||||||
@ -287,12 +339,12 @@ int play_notify_sound(Notification notif, uint64_t flags)
|
|||||||
|
|
||||||
void stop_sound(int sound)
|
void stop_sound(int sound)
|
||||||
{
|
{
|
||||||
if (sound >= 0 && sound < ACTIVE_SOUNDS_MAX && actives[sound].looping && actives[sound].active) {
|
if (sound >= 0 && sound < ACTIVE_NOTIFS_MAX && actives[sound].looping && actives[sound].active ) {
|
||||||
alSourcei(actives[sound].source, AL_LOOPING, false);
|
alSourcei(actives[sound].source, AL_LOOPING, false);
|
||||||
alSourceStop(actives[sound].source);
|
alSourceStop(actives[sound].source);
|
||||||
alDeleteSources(1, &actives[sound].source);
|
alDeleteSources(1, &actives[sound].source);
|
||||||
alDeleteBuffers(1,&actives[sound].buffer);
|
alDeleteBuffers(1,&actives[sound].buffer);
|
||||||
memset(&actives[sound], 0, sizeof(struct _ActiveSounds));
|
memset(&actives[sound], 0, sizeof(struct _ActiveNotifications));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -330,9 +382,97 @@ int notify(ToxWindow* self, Notification notif, uint64_t flags)
|
|||||||
else if (flags & NT_ALWAYS)
|
else if (flags & NT_ALWAYS)
|
||||||
rc = m_play_sound(notif, flags);
|
rc = m_play_sound(notif, flags);
|
||||||
|
|
||||||
if (flags & NT_NOTIFWND) {
|
|
||||||
/* TODO: pop notify window */
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int box_notify(ToxWindow* self, Notification notif, uint64_t flags, char* title, char* format, ...)
|
||||||
|
{
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
int id = notify(self, notif, flags);
|
||||||
|
|
||||||
|
pthread_mutex_lock(Control.poll_mutex);
|
||||||
|
|
||||||
|
if (id == -1 && !(flags & NT_NOFOCUS && Control.this_window == get_focused_window_id())) { /* Could not play */
|
||||||
|
|
||||||
|
for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].active; id ++);
|
||||||
|
if ( id == ACTIVE_NOTIFS_MAX ) {
|
||||||
|
pthread_mutex_unlock(Control.poll_mutex);
|
||||||
|
return -1; /* Full */
|
||||||
|
}
|
||||||
|
|
||||||
|
actives[id].active = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(actives[id].title, title, 24);
|
||||||
|
if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");
|
||||||
|
|
||||||
|
va_list __ARGS__; va_start (__ARGS__, format);
|
||||||
|
snprintf (actives[id].messages[0], 127, format, __ARGS__);
|
||||||
|
va_end (__ARGS__);
|
||||||
|
|
||||||
|
if (strlen(actives[id].messages[0]) > 124)
|
||||||
|
strcpy(actives[id].messages[0] + 124, "...");
|
||||||
|
|
||||||
|
actives[id].box = notify_notification_new(actives[id].title, actives[id].messages[0], NULL);
|
||||||
|
actives[id].size ++;
|
||||||
|
actives[id].timeout = time(NULL) + Control.notif_timeout;
|
||||||
|
|
||||||
|
notify_notification_set_timeout(actives[id].box, Control.notif_timeout);
|
||||||
|
notify_notification_show(actives[id].box, NULL);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(Control.poll_mutex);
|
||||||
|
return id;
|
||||||
|
#else
|
||||||
|
return notify(self, notif, flags);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int box_notify_append(ToxWindow* self, Notification notif, uint64_t flags, int id, char* format, ...)
|
||||||
|
{
|
||||||
|
#ifdef _BOX_NOTIFY
|
||||||
|
if (id < 0 || id >= ACTIVE_NOTIFS_MAX || !actives[id].box || actives[id].size >= 128 ) return -1;
|
||||||
|
|
||||||
|
/* Consider colored notify as primary */
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
if (flags & NT_NOFOCUS && Control.this_window == get_focused_window_id())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pthread_mutex_lock(Control.poll_mutex);
|
||||||
|
|
||||||
|
/* Play the sound again */
|
||||||
|
alSourcePlay(actives[id].source);
|
||||||
|
|
||||||
|
va_list __ARGS__; va_start (__ARGS__, format);
|
||||||
|
snprintf (actives[id].messages[actives[id].size], 127, format, __ARGS__);
|
||||||
|
va_end (__ARGS__);
|
||||||
|
|
||||||
|
if (strlen(actives[id].messages[actives[id].size]) > 124)
|
||||||
|
strcpy(actives[id].messages[actives[id].size] + 124, "...");
|
||||||
|
|
||||||
|
actives[id].size ++;
|
||||||
|
actives[id].timeout = time(NULL) + Control.notif_timeout;
|
||||||
|
|
||||||
|
char formated[128 * 129] = {'\0'};
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (; i <actives[id].size; i ++) {
|
||||||
|
strcat(formated, actives[id].messages[i]);
|
||||||
|
strcat(formated, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
formated[strlen(formated) - 1] = '\0';
|
||||||
|
|
||||||
|
notify_notification_update(actives[id].box, actives[id].title, formated, NULL);
|
||||||
|
notify_notification_show(actives[id].box, NULL);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(Control.poll_mutex);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
#else
|
||||||
|
return notify(self, notif, flags);
|
||||||
|
#endif
|
||||||
|
}
|
@ -60,11 +60,14 @@ typedef enum _Flags {
|
|||||||
NT_ALWAYS = 1 << 8, /* Force sound to play */
|
NT_ALWAYS = 1 << 8, /* Force sound to play */
|
||||||
} Flags;
|
} Flags;
|
||||||
|
|
||||||
int init_notify(int login_cooldown);
|
int init_notify(int login_cooldown, int notification_timeout);
|
||||||
void terminate_notify();
|
void terminate_notify();
|
||||||
|
|
||||||
int notify(ToxWindow* self, Notification notif, uint64_t flags);
|
int notify(ToxWindow* self, Notification notif, uint64_t flags);
|
||||||
|
|
||||||
|
int box_notify(ToxWindow* self, Notification notif, uint64_t flags, char* title, char* format, ...);
|
||||||
|
int box_notify_append(ToxWindow* self, Notification notif, uint64_t flags, int id, char* format, ...);
|
||||||
|
|
||||||
#ifdef _SOUND_NOTIFY
|
#ifdef _SOUND_NOTIFY
|
||||||
int set_sound(Notification sound, const char* value);
|
int set_sound(Notification sound, const char* value);
|
||||||
void stop_sound(int sound);
|
void stop_sound(int sound);
|
||||||
|
12
src/prompt.c
12
src/prompt.c
@ -185,10 +185,10 @@ static void prompt_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 {
|
} else {
|
||||||
beep();
|
notify(self, error, 0);
|
||||||
}
|
}
|
||||||
} else if (key == '\n') {
|
} else if (key == '\n') {
|
||||||
rm_trailing_spaces_buf(ctx);
|
rm_trailing_spaces_buf(ctx);
|
||||||
@ -309,21 +309,13 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum
|
|||||||
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg);
|
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg);
|
||||||
write_to_log(msg, nick, ctx->log, true);
|
write_to_log(msg, nick, ctx->log, true);
|
||||||
|
|
||||||
#ifdef _SOUND_NOTIFY
|
|
||||||
notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
|
notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
|
||||||
#else
|
|
||||||
notify(self, silent, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
|
|
||||||
#endif /* _SOUND_NOTIFY */
|
|
||||||
} else {
|
} else {
|
||||||
msg = "has gone offline";
|
msg = "has gone offline";
|
||||||
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, RED, msg);
|
line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, RED, msg);
|
||||||
write_to_log(msg, nick, ctx->log, true);
|
write_to_log(msg, nick, ctx->log, true);
|
||||||
|
|
||||||
#ifdef _SOUND_NOTIFY
|
|
||||||
notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
|
notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
|
||||||
#else
|
|
||||||
notify(self, silent, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL);
|
|
||||||
#endif /* _SOUND_NOTIFY */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,7 +635,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#endif /* _AUDIO */
|
#endif /* _AUDIO */
|
||||||
|
|
||||||
init_notify(60);
|
init_notify(60, 3000);
|
||||||
|
|
||||||
#ifdef _SOUND_NOTIFY
|
#ifdef _SOUND_NOTIFY
|
||||||
notify(prompt, self_log_in, 0);
|
notify(prompt, self_log_in, 0);
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "misc_tools.h"
|
#include "misc_tools.h"
|
||||||
#include "toxic_strings.h"
|
#include "toxic_strings.h"
|
||||||
|
#include "notify.h"
|
||||||
|
|
||||||
/* Adds char to line at pos. Return 0 on success, -1 if line buffer is full */
|
/* Adds char to line at pos. Return 0 on success, -1 if line buffer is full */
|
||||||
int add_char_to_buf(ChatContext *ctx, wint_t ch)
|
int add_char_to_buf(ChatContext *ctx, wint_t ch)
|
||||||
@ -191,7 +192,7 @@ void fetch_hist_item(ChatContext *ctx, int key_dir)
|
|||||||
if (key_dir == KEY_UP) {
|
if (key_dir == KEY_UP) {
|
||||||
if (--ctx->hst_pos < 0) {
|
if (--ctx->hst_pos < 0) {
|
||||||
ctx->hst_pos = 0;
|
ctx->hst_pos = 0;
|
||||||
beep();
|
notify(NULL, error, NT_ALWAYS);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (++ctx->hst_pos >= ctx->hst_tot) {
|
if (++ctx->hst_pos >= ctx->hst_tot) {
|
||||||
|
Loading…
Reference in New Issue
Block a user