1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-15 10:33:03 +01:00
toxic/src/notify.c

902 lines
22 KiB
C
Raw Normal View History

/* notify.c
2015-03-26 03:56:45 +01:00
*
*
* Copyright (C) 2014 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
* Toxic is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Toxic is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdarg.h>
#include <time.h>
2014-07-28 01:35:40 +02:00
#include <assert.h>
#include <sys/stat.h>
2014-09-26 10:46:14 +02:00
#include "notify.h"
#include "audio_device.h"
2014-09-26 10:46:14 +02:00
#include "settings.h"
#include "line_info.h"
#include "misc_tools.h"
2014-10-01 23:28:34 +02:00
#include "xtra.h"
2014-09-26 10:46:14 +02:00
#if defined(AUDIO) || defined(SOUND_NOTIFY)
#ifdef __APPLE__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
/* compatibility with older versions of OpenAL */
#ifndef ALC_ALL_DEVICES_SPECIFIER
#include <AL/alext.h>
2018-10-08 19:39:04 +02:00
#endif /* ALC_ALL_DEVICES_SPECIFIER */
#endif /* __APPLE__ */
#ifdef SOUND_NOTIFY
#include <AL/alut.h> /* freealut packet */
2018-10-08 19:39:04 +02:00
#endif /* SOUND_NOTIFY */
#endif /* defined(AUDIO) || defined(SOUND_NOTIFY) */
#ifdef BOX_NOTIFY
#include <libnotify/notify.h>
#endif
#define MAX_BOX_MSG_LEN 127
#define SOUNDS_SIZE 10
#define ACTIVE_NOTIFS_MAX 10
extern struct user_settings *user_settings;
static struct Control {
time_t cooldown;
time_t notif_timeout;
2015-03-26 03:56:45 +01:00
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
pthread_mutex_t poll_mutex[1];
bool poll_active;
2014-08-02 00:37:02 +02:00
#endif
2015-03-26 03:56:45 +01:00
#ifdef SOUND_NOTIFY
2014-08-02 00:37:02 +02:00
uint32_t device_idx; /* index of output device */
char *sounds[SOUNDS_SIZE];
#endif /* SOUND_NOTIFY */
} Control = {0};
static struct _ActiveNotifications {
#ifdef SOUND_NOTIFY
uint32_t source;
uint32_t buffer;
bool looping;
2018-10-08 19:39:04 +02:00
#endif /* SOUND_NOTIFY */
bool active;
2014-08-02 00:37:02 +02:00
int *id_indicator;
#ifdef BOX_NOTIFY
NotifyNotification *box;
char messages[MAX_BOX_MSG_LEN + 1][MAX_BOX_MSG_LEN + 1];
char title[64];
2014-07-28 01:35:40 +02:00
size_t size;
2014-08-02 00:37:02 +02:00
time_t n_timeout;
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
2014-10-12 06:28:28 +02:00
} actives[ACTIVE_NOTIFS_MAX];
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
static void clear_actives_index(size_t idx)
{
if (actives[idx].id_indicator) {
*actives[idx].id_indicator = -1;
}
actives[idx] = (struct _ActiveNotifications) {
0
};
}
/* coloured tab notifications: primary notification type */
static void tab_notify(ToxWindow *self, uint64_t flags)
{
if (self == NULL) {
return;
}
if (flags & NT_WNDALERT_0) {
self->alert = WINDOW_ALERT_0;
} else if ((flags & NT_WNDALERT_1) && (!self->alert || self->alert > WINDOW_ALERT_0)) {
self->alert = WINDOW_ALERT_1;
} else if ((flags & NT_WNDALERT_2) && (!self->alert || self->alert > WINDOW_ALERT_1)) {
self->alert = WINDOW_ALERT_2;
}
}
static bool notifications_are_disabled(uint64_t flags)
{
if (user_settings->alerts != ALERTS_ENABLED) {
return true;
}
bool res = (flags & NT_RESTOL) && (Control.cooldown > get_unix_time());
#ifdef X11
return res || ((flags & NT_NOFOCUS) && is_focused());
2014-09-04 00:38:08 +02:00
#else
return res;
2014-09-04 00:38:08 +02:00
#endif
}
static void control_lock(void)
2014-08-02 00:37:02 +02:00
{
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
2014-08-02 00:37:02 +02:00
pthread_mutex_lock(Control.poll_mutex);
#endif
}
static void control_unlock(void)
2014-08-02 00:37:02 +02:00
{
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
2014-08-02 00:37:02 +02:00
pthread_mutex_unlock(Control.poll_mutex);
#endif
}
#ifdef SOUND_NOTIFY
bool is_playing(int source)
{
int ready;
alGetSourcei(source, AL_SOURCE_STATE, &ready);
return ready == AL_PLAYING;
}
/* TODO maybe find better way to do this */
/* cooldown is in seconds */
#define DEVICE_COOLDOWN 5 /* TODO perhaps load this from config? */
static bool device_opened = false;
time_t last_opened_update = 0;
/* Opens primary device. Returns true on succe*/
void m_open_device(void)
2015-03-26 03:56:45 +01:00
{
last_opened_update = get_unix_time();
2015-03-26 03:56:45 +01:00
if (device_opened) {
return;
}
2015-03-26 03:56:45 +01:00
/* Blah error check */
open_primary_device(output, &Control.device_idx, 48000, 20, 1);
2015-03-26 03:56:45 +01:00
device_opened = true;
}
void m_close_device(void)
{
if (!device_opened) {
return;
}
2014-10-12 06:28:28 +02:00
close_device(output, Control.device_idx);
2014-10-12 06:28:28 +02:00
device_opened = false;
}
/* Terminate all sounds but wait for them to finish first */
void graceful_clear(void)
{
2014-08-02 00:37:02 +02:00
control_lock();
while (1) {
int i;
for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
if (actives[i].active) {
#ifdef BOX_NOTIFY
2014-07-28 01:35:40 +02:00
if (actives[i].box) {
GError *ignore;
2014-08-02 00:37:02 +02:00
notify_notification_close(actives[i].box, &ignore);
actives[i].box = NULL;
2014-07-28 01:35:40 +02:00
}
2014-10-12 06:28:28 +02:00
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
if (actives[i].id_indicator) {
2014-10-12 07:49:56 +02:00
*actives[i].id_indicator = -1; /* reset indicator value */
}
2014-10-12 06:28:28 +02:00
if (actives[i].looping) {
2015-03-26 03:56:45 +01:00
stop_sound(i);
} else {
if (!is_playing(actives[i].source)) {
clear_actives_index(i);
} else {
break;
}
}
}
}
2014-10-12 06:28:28 +02:00
if (i == ACTIVE_NOTIFS_MAX) {
m_close_device(); /* In case it's opened */
2014-08-02 00:37:02 +02:00
control_unlock();
return;
}
2014-10-12 06:28:28 +02:00
sleep_thread(1000L);
}
control_unlock();
}
void *do_playing(void *_p)
{
UNUSED_VAR(_p);
2015-03-26 03:56:45 +01:00
while (true) {
2014-08-02 00:37:02 +02:00
control_lock();
2015-03-26 03:56:45 +01:00
if (!Control.poll_active) {
control_unlock();
break;
}
bool has_looping = false;
bool test_active_notify = false;
int i;
2015-03-26 03:56:45 +01:00
for (i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
2015-03-26 03:56:45 +01:00
if (actives[i].looping) {
has_looping = true;
}
test_active_notify = actives[i].active && !actives[i].looping;
#ifdef BOX_NOTIFY
test_active_notify = test_active_notify && !actives[i].box;
#endif
if (test_active_notify) {
if (actives[i].id_indicator) {
2014-10-12 07:49:56 +02:00
*actives[i].id_indicator = -1; /* reset indicator value */
}
2014-10-12 07:49:56 +02:00
if (!is_playing(actives[i].source)) {
/* Close */
alSourceStop(actives[i].source);
alDeleteSources(1, &actives[i].source);
2014-10-12 06:28:28 +02:00
alDeleteBuffers(1, &actives[i].buffer);
clear_actives_index(i);
}
2014-08-02 00:37:02 +02:00
}
#ifdef BOX_NOTIFY
else if (actives[i].box && time(NULL) >= actives[i].n_timeout) {
GError *ignore;
2014-07-28 01:35:40 +02:00
notify_notification_close(actives[i].box, &ignore);
2014-08-02 00:37:02 +02:00
actives[i].box = NULL;
if (actives[i].id_indicator) {
2014-10-12 07:49:56 +02:00
*actives[i].id_indicator = -1; /* reset indicator value */
}
2014-08-02 00:37:02 +02:00
if (!actives[i].looping && !is_playing(actives[i].source)) {
/* stop source if not looping or playing, just terminate box */
2014-08-02 00:37:02 +02:00
alSourceStop(actives[i].source);
alDeleteSources(1, &actives[i].source);
2014-10-12 07:49:56 +02:00
alDeleteBuffers(1, &actives[i].buffer);
clear_actives_index(i);
2014-08-02 00:37:02 +02:00
}
}
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
}
2015-03-26 03:56:45 +01:00
/* device is opened and no activity in under DEVICE_COOLDOWN time, close device*/
2015-03-26 03:56:45 +01:00
if (device_opened && !has_looping &&
(time(NULL) - last_opened_update) > DEVICE_COOLDOWN) {
m_close_device();
}
has_looping = false;
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
control_unlock();
sleep_thread(10000L);
}
2014-07-21 23:48:39 +02:00
pthread_exit(NULL);
}
int play_source(uint32_t source, uint32_t buffer, bool looping)
2015-03-26 03:56:45 +01:00
{
int i = 0;
for (; i < ACTIVE_NOTIFS_MAX && actives[i].active; ++i);
if (i == ACTIVE_NOTIFS_MAX) {
return -1; /* Full */
}
2015-03-26 03:56:45 +01:00
alSourcePlay(source);
2015-03-26 03:56:45 +01:00
actives[i].active = 1;
actives[i].source = source;
actives[i].buffer = buffer;
actives[i].looping = looping;
2015-03-26 03:56:45 +01:00
return i;
}
2014-08-02 00:37:02 +02:00
#elif BOX_NOTIFY
void *do_playing(void *_p)
2014-08-02 00:37:02 +02:00
{
UNUSED_VAR(_p);
while (true) {
2014-08-02 00:37:02 +02:00
control_lock();
if (!Control.poll_active) {
control_unlock();
break;
}
for (size_t i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
if (actives[i].box && time(NULL) >= actives[i].n_timeout) {
GError *ignore;
2014-08-02 00:37:02 +02:00
notify_notification_close(actives[i].box, &ignore);
clear_actives_index(i);
2014-08-02 00:37:02 +02:00
}
}
2014-08-02 00:37:02 +02:00
control_unlock();
sleep_thread(10000L);
2014-08-02 00:37:02 +02:00
}
2014-08-02 00:37:02 +02:00
pthread_exit(NULL);
}
void graceful_clear(void)
2014-08-02 00:37:02 +02:00
{
control_lock();
2015-03-26 03:56:45 +01:00
for (size_t i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
2014-08-02 00:37:02 +02:00
if (actives[i].box) {
GError *ignore;
2014-08-02 00:37:02 +02:00
notify_notification_close(actives[i].box, &ignore);
}
2014-10-12 07:49:56 +02:00
clear_actives_index(i);
2015-03-26 03:56:45 +01:00
}
2014-08-02 00:37:02 +02:00
control_unlock();
}
2018-10-08 19:39:04 +02:00
#endif /* SOUND_NOTIFY */
2014-08-02 00:37:02 +02:00
/* Kills all notifications for `id`. This must be called before freeing a ToxWindow. */
void kill_notifs(int id)
{
control_lock();
for (size_t i = 0; i < ACTIVE_NOTIFS_MAX; ++i) {
if (!actives[i].id_indicator) {
continue;
}
if (*actives[i].id_indicator == id) {
#ifdef BOX_NOTIFY
if (actives[i].box) {
GError *ignore;
notify_notification_close(actives[i].box, &ignore);
}
#endif // BOX_NOTIFY
clear_actives_index(i);
}
}
control_unlock();
}
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/**********************************************************************************/
/* Opens primary device */
int init_notify(int login_cooldown, int notification_timeout)
{
#ifdef SOUND_NOTIFY
2014-07-22 12:30:35 +02:00
alutInitWithoutContext(NULL, NULL);
#endif /* SOUND_NOTIFY */
2015-03-26 03:56:45 +01:00
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
if (pthread_mutex_init(Control.poll_mutex, NULL) != 0) {
2014-09-24 04:51:56 +02:00
return -1;
}
2014-09-24 04:51:56 +02:00
Control.poll_active = 1;
pthread_t thread;
2014-09-24 04:51:56 +02:00
if (pthread_create(&thread, NULL, do_playing, NULL) != 0 || pthread_detach(thread) != 0) {
pthread_mutex_destroy(Control.poll_mutex);
Control.poll_active = 0;
return -1;
}
2014-10-12 07:49:56 +02:00
2018-10-08 19:39:04 +02:00
#endif /* defined(SOUND_NOTIFY) || defined(BOX_NOTIFY) */
2015-08-28 03:29:34 +02:00
Control.cooldown = time(NULL) + login_cooldown;
2015-03-26 03:56:45 +01:00
#ifdef BOX_NOTIFY
2014-10-12 07:49:56 +02:00
notify_init("Toxic");
#endif
Control.notif_timeout = notification_timeout;
return 1;
}
void terminate_notify(void)
2015-03-26 03:56:45 +01:00
{
#if defined(SOUND_NOTIFY) || defined(BOX_NOTIFY)
control_lock();
if (!Control.poll_active) {
control_unlock();
return;
}
Control.poll_active = 0;
control_unlock();
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
graceful_clear();
2018-10-08 19:39:04 +02:00
#endif /* defined(SOUND_NOTIFY) || defined(BOX_NOTIFY) */
2014-08-02 00:37:02 +02:00
#ifdef SOUND_NOTIFY
int i = 0;
for (; i < SOUNDS_SIZE; ++i) {
free(Control.sounds[i]);
}
2014-07-22 12:30:35 +02:00
alutExit();
#endif /* SOUND_NOTIFY */
2015-03-26 03:56:45 +01:00
#ifdef BOX_NOTIFY
notify_uninit();
#endif
}
#ifdef SOUND_NOTIFY
int set_sound(Notification sound, const char *value)
{
if (sound == silent) {
return 0;
}
2015-03-26 03:56:45 +01:00
free(Control.sounds[sound]);
size_t len = strlen(value) + 1;
2014-07-25 02:12:32 +02:00
Control.sounds[sound] = calloc(len, 1);
memcpy(Control.sounds[sound], value, len);
struct stat buf;
return stat(value, &buf) == 0;
}
int play_sound_internal(Notification what, bool loop)
2015-03-26 03:56:45 +01:00
{
uint32_t source;
uint32_t buffer;
2015-03-26 03:56:45 +01:00
m_open_device();
2015-03-26 03:56:45 +01:00
alGenSources(1, &source);
alGenBuffers(1, &buffer);
2014-07-25 02:12:32 +02:00
buffer = alutCreateBufferFromFile(Control.sounds[what]);
alSourcei(source, AL_BUFFER, buffer);
alSourcei(source, AL_LOOPING, loop);
2015-03-26 03:56:45 +01:00
int rc = play_source(source, buffer, loop);
if (rc < 0) {
alSourceStop(source);
alDeleteSources(1, &source);
alDeleteBuffers(1, &buffer);
return -1;
}
2015-03-26 03:56:45 +01:00
return rc;
}
int play_notify_sound(Notification notif, uint64_t flags)
{
int rc = -1;
if (flags & NT_BEEP) {
beep();
}
if (notif != silent) {
if (!Control.poll_active || !Control.sounds[notif]) {
return -1;
}
rc = play_sound_internal(notif, flags & NT_LOOP ? 1 : 0);
}
return rc;
}
2014-08-02 00:37:02 +02:00
void stop_sound(int id)
{
if (id >= 0 && id < ACTIVE_NOTIFS_MAX && actives[id].looping && actives[id].active) {
#ifdef BOX_NOTIFY
2014-08-02 00:37:02 +02:00
if (actives[id].box) {
GError *ignore;
2014-08-02 00:37:02 +02:00
notify_notification_close(actives[id].box, &ignore);
}
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
2018-10-08 19:39:04 +02:00
// alSourcei(actives[id].source, AL_LOOPING, false);
2014-08-02 00:37:02 +02:00
alSourceStop(actives[id].source);
alDeleteSources(1, &actives[id].source);
alDeleteBuffers(1, &actives[id].buffer);
clear_actives_index(id);
}
}
2018-10-08 19:39:04 +02:00
#endif /* SOUND_NOTIFY */
static int m_play_sound(Notification notif, uint64_t flags)
{
#ifdef SOUND_NOTIFY
return play_notify_sound(notif, flags);
2014-07-22 20:38:32 +02:00
#else
if (notif != silent) {
2014-07-22 20:38:32 +02:00
beep();
}
2014-07-22 20:38:32 +02:00
return -1;
2015-03-26 03:56:45 +01:00
#endif /* SOUND_NOTIFY */
}
int sound_notify(ToxWindow *self, Notification notif, uint64_t flags, int *id_indicator)
{
tab_notify(self, flags);
if (notifications_are_disabled(flags)) {
return -1;
}
2014-10-12 06:28:28 +02:00
2014-08-02 00:37:02 +02:00
int id = -1;
control_lock();
2014-10-12 06:28:28 +02:00
if (self && (!self->stb || self->stb->status != TOX_USER_STATUS_BUSY)) {
2014-08-02 00:37:02 +02:00
id = m_play_sound(notif, flags);
} else if (flags & NT_ALWAYS) {
2014-08-02 00:37:02 +02:00
id = m_play_sound(notif, flags);
}
2014-10-12 06:28:28 +02:00
#if defined(BOX_NOTIFY) && !defined(SOUND_NOTIFY)
2014-08-02 00:37:02 +02:00
if (id == -1) {
2014-10-12 06:28:28 +02:00
for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].box; id++);
if (id == ACTIVE_NOTIFS_MAX) {
2014-08-02 00:37:02 +02:00
control_unlock();
return -1; /* Full */
}
}
2014-10-12 06:28:28 +02:00
2018-10-08 19:39:04 +02:00
#endif /* defined(BOX_NOTIFY) && !defined(SOUND_NOTIFY) */
2014-10-12 06:28:28 +02:00
if (id_indicator && id != -1) {
2014-08-02 00:37:02 +02:00
actives[id].id_indicator = id_indicator;
*id_indicator = id;
}
2014-10-12 06:28:28 +02:00
2014-08-02 00:37:02 +02:00
control_unlock();
2014-10-12 06:28:28 +02:00
2014-08-02 00:37:02 +02:00
return id;
}
int sound_notify2(ToxWindow *self, Notification notif, uint64_t flags, int id)
2014-08-02 00:37:02 +02:00
{
tab_notify(self, flags);
2015-03-26 03:56:45 +01:00
if (notifications_are_disabled(flags)) {
2014-08-02 00:37:02 +02:00
return -1;
}
2015-03-26 03:56:45 +01:00
if (id < 0 || id >= ACTIVE_NOTIFS_MAX) {
return -1;
}
2015-03-26 03:56:45 +01:00
#ifdef SOUND_NOTIFY
2014-08-02 00:37:02 +02:00
control_lock();
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
if (!actives[id].active || !Control.sounds[notif]) {
control_unlock();
return -1;
}
2015-03-26 03:56:45 +01:00
m_open_device();
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
alSourceStop(actives[id].source);
alDeleteSources(1, &actives[id].source);
alDeleteBuffers(1, &actives[id].buffer);
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
alGenSources(1, &actives[id].source);
alGenBuffers(1, &actives[id].buffer);
actives[id].buffer = alutCreateBufferFromFile(Control.sounds[notif]);
alSourcei(actives[id].source, AL_BUFFER, actives[id].buffer);
alSourcei(actives[id].source, AL_LOOPING, flags & NT_LOOP);
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
alSourcePlay(actives[id].source);
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
control_unlock();
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
return id;
#else
if (notif != silent) {
2014-08-02 00:37:02 +02:00
beep();
}
2015-03-26 03:56:45 +01:00
2014-08-02 00:37:02 +02:00
return 0;
#endif /* SOUND_NOTIFY */
}
int box_notify(ToxWindow *self, Notification notif, uint64_t flags, int *id_indicator, const char *title,
const char *format, ...)
{
if (notifications_are_disabled(flags)) {
tab_notify(self, flags);
2014-08-02 00:37:02 +02:00
return -1;
}
#ifdef BOX_NOTIFY
2014-08-02 00:37:02 +02:00
int id = sound_notify(self, notif, flags, id_indicator);
2014-08-02 00:37:02 +02:00
control_lock();
#ifdef SOUND_NOTIFY
2014-08-02 00:37:02 +02:00
if (id == -1) { /* Could not play */
for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].active; id ++);
if (id == ACTIVE_NOTIFS_MAX) {
2014-08-02 00:37:02 +02:00
control_unlock();
return -1; /* Full */
}
2015-03-26 03:56:45 +01:00
actives[id].active = 1;
2014-08-02 00:37:02 +02:00
actives[id].id_indicator = id_indicator;
if (id_indicator) {
*id_indicator = id;
}
}
#else
if (id == -1) {
return -1;
}
2018-10-08 19:39:04 +02:00
#endif /* SOUND_NOTIFY */
snprintf(actives[id].title, sizeof(actives[id].title), "%s", title);
if (strlen(title) > 23) {
strcpy(actives[id].title + 20, "...");
}
va_list __ARGS__;
va_start(__ARGS__, format);
vsnprintf(actives[id].messages[0], MAX_BOX_MSG_LEN, format, __ARGS__);
va_end(__ARGS__);
if (strlen(actives[id].messages[0]) > MAX_BOX_MSG_LEN - 3) {
strcpy(actives[id].messages[0] + MAX_BOX_MSG_LEN - 3, "...");
}
2014-07-28 01:35:40 +02:00
actives[id].box = notify_notification_new(actives[id].title, actives[id].messages[0], NULL);
2014-10-12 06:28:28 +02:00
actives[id].size++;
actives[id].n_timeout = get_unix_time() + Control.notif_timeout / 1000;
2015-03-26 03:56:45 +01:00
notify_notification_set_timeout(actives[id].box, Control.notif_timeout);
2014-08-02 00:37:02 +02:00
notify_notification_set_app_name(actives[id].box, "toxic");
/*notify_notification_add_action(actives[id].box, "lel", "default", m_notify_action, self, NULL);*/
notify_notification_show(actives[id].box, NULL);
2014-08-02 00:37:02 +02:00
control_unlock();
return id;
#else
2014-08-02 00:37:02 +02:00
return sound_notify(self, notif, flags, id_indicator);
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
2014-07-22 09:59:44 +02:00
}
int box_notify2(ToxWindow *self, Notification notif, uint64_t flags, int id, const char *format, ...)
{
2014-09-05 00:48:55 +02:00
if (notifications_are_disabled(flags)) {
tab_notify(self, flags);
2014-08-02 00:37:02 +02:00
return -1;
2014-09-05 00:48:55 +02:00
}
#ifdef BOX_NOTIFY
if (sound_notify2(self, notif, flags, id) == -1) {
2014-08-02 00:37:02 +02:00
return -1;
}
2014-08-02 00:37:02 +02:00
control_lock();
if (!actives[id].box || actives[id].size >= MAX_BOX_MSG_LEN + 1) {
2014-08-02 00:37:02 +02:00
control_unlock();
return -1;
}
va_list __ARGS__;
va_start(__ARGS__, format);
vsnprintf(actives[id].messages[actives[id].size], MAX_BOX_MSG_LEN, format, __ARGS__);
va_end(__ARGS__);
if (strlen(actives[id].messages[actives[id].size]) > MAX_BOX_MSG_LEN - 3) {
strcpy(actives[id].messages[actives[id].size] + MAX_BOX_MSG_LEN - 3, "...");
}
2014-10-12 06:28:28 +02:00
actives[id].size++;
actives[id].n_timeout = get_unix_time() + Control.notif_timeout / 1000;
char *formatted = calloc(1, sizeof(char) * ((MAX_BOX_MSG_LEN + 1) * (MAX_BOX_MSG_LEN + 2)));
for (size_t i = 0; i < actives[id].size; ++i) {
strcat(formatted, actives[id].messages[i]);
strcat(formatted, "\n");
2014-08-02 00:37:02 +02:00
}
notify_notification_update(actives[id].box, actives[id].title, formatted, NULL);
2014-08-02 00:37:02 +02:00
notify_notification_show(actives[id].box, NULL);
free(formatted);
2014-08-02 00:37:02 +02:00
control_unlock();
2014-08-02 00:37:02 +02:00
return id;
#else
return sound_notify2(self, notif, flags, id);
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
2014-08-02 00:37:02 +02:00
}
int box_silent_notify(ToxWindow *self, uint64_t flags, int *id_indicator, const char *title, const char *format, ...)
2014-08-02 00:37:02 +02:00
{
tab_notify(self, flags);
if (notifications_are_disabled(flags)) {
2014-07-28 01:35:40 +02:00
return -1;
}
#ifdef BOX_NOTIFY
2014-08-02 00:37:02 +02:00
control_lock();
2015-03-26 03:56:45 +01:00
int id;
2014-08-02 00:37:02 +02:00
for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].active; id ++);
if (id == ACTIVE_NOTIFS_MAX) {
2014-08-02 00:37:02 +02:00
control_unlock();
return -1; /* Full */
}
2014-08-02 00:37:02 +02:00
if (id_indicator) {
actives[id].id_indicator = id_indicator;
*id_indicator = id;
}
snprintf(actives[id].title, sizeof(actives[id].title), "%s", title);
if (strlen(title) > 23) {
strcpy(actives[id].title + 20, "...");
}
va_list __ARGS__;
va_start(__ARGS__, format);
vsnprintf(actives[id].messages[0], MAX_BOX_MSG_LEN, format, __ARGS__);
va_end(__ARGS__);
if (strlen(actives[id].messages[0]) > MAX_BOX_MSG_LEN - 3) {
strcpy(actives[id].messages[0] + MAX_BOX_MSG_LEN - 3, "...");
}
2014-08-02 00:37:02 +02:00
actives[id].active = 1;
actives[id].box = notify_notification_new(actives[id].title, actives[id].messages[0], NULL);
actives[id].size ++;
actives[id].n_timeout = get_unix_time() + Control.notif_timeout / 1000;
2014-08-02 00:37:02 +02:00
notify_notification_set_timeout(actives[id].box, Control.notif_timeout);
notify_notification_set_app_name(actives[id].box, "toxic");
/*notify_notification_add_action(actives[id].box, "lel", "default", m_notify_action, self, NULL);*/
notify_notification_show(actives[id].box, NULL);
2014-08-02 00:37:02 +02:00
control_unlock();
return id;
#else
return -1;
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
2014-08-02 00:37:02 +02:00
}
int box_silent_notify2(ToxWindow *self, uint64_t flags, int id, const char *format, ...)
2014-08-02 00:37:02 +02:00
{
tab_notify(self, flags);
if (notifications_are_disabled(flags)) {
2014-08-02 00:37:02 +02:00
return -1;
}
#ifdef BOX_NOTIFY
2014-08-02 00:37:02 +02:00
control_lock();
if (id < 0 || id >= ACTIVE_NOTIFS_MAX || !actives[id].box || actives[id].size >= MAX_BOX_MSG_LEN + 1) {
2014-08-02 00:37:02 +02:00
control_unlock();
return -1;
}
va_list __ARGS__;
va_start(__ARGS__, format);
vsnprintf(actives[id].messages[actives[id].size], MAX_BOX_MSG_LEN, format, __ARGS__);
va_end(__ARGS__);
if (strlen(actives[id].messages[actives[id].size]) > MAX_BOX_MSG_LEN - 3) {
strcpy(actives[id].messages[actives[id].size] + MAX_BOX_MSG_LEN - 3, "...");
}
2014-07-28 01:35:40 +02:00
actives[id].size ++;
actives[id].n_timeout = get_unix_time() + Control.notif_timeout / 1000;
char *formatted = calloc(1, sizeof(char) * ((MAX_BOX_MSG_LEN + 1) * (MAX_BOX_MSG_LEN + 2)));
for (size_t i = 0; i < actives[id].size; ++i) {
strcat(formatted, actives[id].messages[i]);
strcat(formatted, "\n");
2014-07-28 01:35:40 +02:00
}
notify_notification_update(actives[id].box, actives[id].title, formatted, NULL);
2014-07-28 01:35:40 +02:00
notify_notification_show(actives[id].box, NULL);
free(formatted);
2014-08-02 00:37:02 +02:00
control_unlock();
2014-07-28 01:35:40 +02:00
return id;
#else
2014-08-02 00:37:02 +02:00
return -1;
2018-10-08 19:39:04 +02:00
#endif /* BOX_NOTIFY */
}