1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-12-23 17:03:25 +01:00

Merge pull request #200 from mannol1/master

Core adjustments
This commit is contained in:
mannol1 2014-07-28 01:35:58 +02:00
commit 02708534c0
12 changed files with 234 additions and 81 deletions

View File

@ -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);
} }

View File

@ -770,7 +770,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') {

View File

@ -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

View File

@ -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);

View File

@ -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 == T_KEY_C_RB) { /* Scroll peerlist up and down one position */ } else if (key == T_KEY_C_RB) { /* Scroll peerlist up and down one position */
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST; int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;

View File

@ -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;
} }

View File

@ -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)

View File

@ -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
#include <OpenAL/al.h> #ifdef __APPLE__
#include <OpenAL/alc.h> #include <OpenAL/al.h>
#ifdef _SOUND_NOTIFY #include <OpenAL/alc.h>
#include <OpenAL/alut.h> /* Is this good? */ #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 #endif
#else #endif /* _AUDIO */
#include <AL/al.h>
#include <AL/alc.h>
#ifdef _SOUND_NOTIFY
#include <AL/alut.h> /* freealut packet */
#endif
#endif
#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
}

View File

@ -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);

View File

@ -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 */
} }
} }

View File

@ -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);

View File

@ -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) {