mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-22 21:03:02 +01:00
Fix more threading issues
This commit is contained in:
parent
28dd43608d
commit
b4464eda4d
162
src/device.c
162
src/device.c
@ -58,14 +58,14 @@ typedef struct Device {
|
|||||||
DataHandleCallback cb; /* Use this to handle data from input device usually */
|
DataHandleCallback cb; /* Use this to handle data from input device usually */
|
||||||
void* cb_data; /* Data to be passed to callback */
|
void* cb_data; /* Data to be passed to callback */
|
||||||
int32_t call_idx; /* ToxAv call index */
|
int32_t call_idx; /* ToxAv call index */
|
||||||
|
|
||||||
uint32_t source, buffers[OPENAL_BUFS]; /* Playback source/buffers */
|
uint32_t source, buffers[OPENAL_BUFS]; /* Playback source/buffers */
|
||||||
uint32_t ref_count;
|
uint32_t ref_count;
|
||||||
int32_t selection;
|
int32_t selection;
|
||||||
bool enable_VAD;
|
bool enable_VAD;
|
||||||
bool muted;
|
bool muted;
|
||||||
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;
|
int32_t sound_mode;
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
@ -89,7 +89,7 @@ static ToxAv* av = NULL;
|
|||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
||||||
|
|
||||||
bool thread_running = true,
|
bool thread_running = true,
|
||||||
thread_paused = true; /* Thread control */
|
thread_paused = true; /* Thread control */
|
||||||
|
|
||||||
void* thread_poll(void*);
|
void* thread_poll(void*);
|
||||||
@ -105,19 +105,19 @@ DeviceError init_devices()
|
|||||||
size[input] = 0;
|
size[input] = 0;
|
||||||
if ( (stringed_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER)) ) {
|
if ( (stringed_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER)) ) {
|
||||||
ddevice_names[input] = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
ddevice_names[input] = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
||||||
|
|
||||||
for ( ; *stringed_device_list && size[input] < MAX_DEVICES; ++size[input] ) {
|
for ( ; *stringed_device_list && size[input] < MAX_DEVICES; ++size[input] ) {
|
||||||
devices_names[input][size[input]] = stringed_device_list;
|
devices_names[input][size[input]] = stringed_device_list;
|
||||||
stringed_device_list += strlen( stringed_device_list ) + 1;
|
stringed_device_list += strlen( stringed_device_list ) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size[output] = 0;
|
size[output] = 0;
|
||||||
if ( (stringed_device_list = alcGetString(NULL, ALC_DEVICE_SPECIFIER)) ) {
|
if ( (stringed_device_list = alcGetString(NULL, ALC_DEVICE_SPECIFIER)) ) {
|
||||||
ddevice_names[output] = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
ddevice_names[output] = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||||
|
|
||||||
for ( ; *stringed_device_list && size[output] < MAX_DEVICES; ++size[output] ) {
|
for ( ; *stringed_device_list && size[output] < MAX_DEVICES; ++size[output] ) {
|
||||||
devices_names[output][size[output]] = stringed_device_list;
|
devices_names[output][size[output]] = stringed_device_list;
|
||||||
stringed_device_list += strlen( stringed_device_list ) + 1;
|
stringed_device_list += strlen( stringed_device_list ) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -125,27 +125,30 @@ DeviceError init_devices()
|
|||||||
// Start poll thread
|
// Start poll thread
|
||||||
if (pthread_mutex_init(&mutex, NULL) != 0)
|
if (pthread_mutex_init(&mutex, NULL) != 0)
|
||||||
return de_InternalError;
|
return de_InternalError;
|
||||||
|
|
||||||
pthread_t thread_id;
|
pthread_t thread_id;
|
||||||
if ( pthread_create(&thread_id, NULL, thread_poll, NULL) != 0 || pthread_detach(thread_id) != 0)
|
if ( pthread_create(&thread_id, NULL, thread_poll, NULL) != 0 || pthread_detach(thread_id) != 0)
|
||||||
return de_InternalError;
|
return de_InternalError;
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
av = av_;
|
av = av_;
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
return (DeviceError) de_None;
|
return (DeviceError) de_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceError terminate_devices()
|
DeviceError terminate_devices()
|
||||||
{
|
{
|
||||||
/* Cleanup if needed */
|
/* Cleanup if needed */
|
||||||
|
lock;
|
||||||
thread_running = false;
|
thread_running = false;
|
||||||
|
unlock;
|
||||||
|
|
||||||
usleep(20000);
|
usleep(20000);
|
||||||
|
|
||||||
if (pthread_mutex_destroy(&mutex) != 0)
|
if (pthread_mutex_destroy(&mutex) != 0)
|
||||||
return (DeviceError) de_InternalError;
|
return (DeviceError) de_InternalError;
|
||||||
|
|
||||||
return (DeviceError) de_None;
|
return (DeviceError) de_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,16 +156,16 @@ DeviceError device_mute(DeviceType type, uint32_t device_idx)
|
|||||||
{
|
{
|
||||||
if (device_idx >= MAX_DEVICES) return de_InvalidSelection;
|
if (device_idx >= MAX_DEVICES) return de_InvalidSelection;
|
||||||
lock;
|
lock;
|
||||||
|
|
||||||
Device* device = running[type][device_idx];
|
Device* device = running[type][device_idx];
|
||||||
|
|
||||||
if (!device) {
|
if (!device) {
|
||||||
unlock;
|
unlock;
|
||||||
return de_DeviceNotActive;
|
return de_DeviceNotActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->muted = !device->muted;
|
device->muted = !device->muted;
|
||||||
|
|
||||||
unlock;
|
unlock;
|
||||||
return de_None;
|
return de_None;
|
||||||
}
|
}
|
||||||
@ -175,7 +178,7 @@ DeviceError device_set_VAD_treshold(uint32_t device_idx, float value)
|
|||||||
|
|
||||||
Device* device = running[input][device_idx];
|
Device* device = running[input][device_idx];
|
||||||
|
|
||||||
if (!device) {
|
if (!device) {
|
||||||
unlock;
|
unlock;
|
||||||
return de_DeviceNotActive;
|
return de_DeviceNotActive;
|
||||||
}
|
}
|
||||||
@ -192,7 +195,7 @@ DeviceError set_primary_device(DeviceType type, int32_t selection)
|
|||||||
{
|
{
|
||||||
if (size[type] <= selection || selection < 0) return de_InvalidSelection;
|
if (size[type] <= selection || selection < 0) return de_InvalidSelection;
|
||||||
primary_device[type] = selection;
|
primary_device[type] = selection;
|
||||||
|
|
||||||
return de_None;
|
return de_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,88 +215,88 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
|||||||
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;
|
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);
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; ++i);
|
for (i = 0; i < MAX_DEVICES && running[type][i] != NULL; ++i);
|
||||||
|
|
||||||
if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; }
|
if (i == MAX_DEVICES) { unlock; return de_AllDevicesBusy; }
|
||||||
else *device_idx = i;
|
else *device_idx = i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_DEVICES; i ++) { /* Check if any device has the same selection */
|
for (i = 0; i < MAX_DEVICES; i ++) { /* Check if any device has the same selection */
|
||||||
if ( running[type][i] && running[type][i]->selection == selection ) {
|
if ( running[type][i] && running[type][i]->selection == selection ) {
|
||||||
// printf("a%d-%d:%p ", selection, i, running[type][i]->dhndl);
|
// printf("a%d-%d:%p ", selection, i, running[type][i]->dhndl);
|
||||||
|
|
||||||
running[type][*device_idx] = running[type][i];
|
running[type][*device_idx] = running[type][i];
|
||||||
running[type][i]->ref_count ++;
|
running[type][i]->ref_count ++;
|
||||||
|
|
||||||
unlock;
|
unlock;
|
||||||
return de_None;
|
return de_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));
|
Device* device = running[type][*device_idx] = calloc(1, sizeof(Device));
|
||||||
device->selection = selection;
|
device->selection = selection;
|
||||||
|
|
||||||
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;
|
device->sound_mode = channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
||||||
|
|
||||||
if (pthread_mutex_init(device->mutex, NULL) != 0) {
|
if (pthread_mutex_init(device->mutex, NULL) != 0) {
|
||||||
free(device);
|
free(device);
|
||||||
unlock;
|
unlock;
|
||||||
return de_InternalError;
|
return de_InternalError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == input) {
|
if (type == input) {
|
||||||
device->dhndl = alcCaptureOpenDevice(devices_names[type][selection],
|
device->dhndl = alcCaptureOpenDevice(devices_names[type][selection],
|
||||||
sample_rate, device->sound_mode, 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
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
device->dhndl = alcOpenDevice(devices_names[type][selection]);
|
device->dhndl = alcOpenDevice(devices_names[type][selection]);
|
||||||
if ( !device->dhndl ) {
|
if ( !device->dhndl ) {
|
||||||
free(device);
|
free(device);
|
||||||
running[type][*device_idx] = NULL;
|
running[type][*device_idx] = NULL;
|
||||||
unlock;
|
unlock;
|
||||||
return de_FailedStart;
|
return de_FailedStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->ctx = alcCreateContext(device->dhndl, NULL);
|
device->ctx = alcCreateContext(device->dhndl, NULL);
|
||||||
alcMakeContextCurrent(device->ctx);
|
alcMakeContextCurrent(device->ctx);
|
||||||
|
|
||||||
alGenBuffers(OPENAL_BUFS, device->buffers);
|
alGenBuffers(OPENAL_BUFS, device->buffers);
|
||||||
alGenSources((uint32_t)1, &device->source);
|
alGenSources((uint32_t)1, &device->source);
|
||||||
alSourcei(device->source, AL_LOOPING, AL_FALSE);
|
alSourcei(device->source, AL_LOOPING, AL_FALSE);
|
||||||
|
|
||||||
uint16_t zeros[frame_size];
|
uint16_t zeros[frame_size];
|
||||||
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], device->sound_mode, 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);
|
||||||
alSourcePlay(device->source);
|
alSourcePlay(device->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alcGetError(device->dhndl) != AL_NO_ERROR) {
|
if (alcGetError(device->dhndl) != AL_NO_ERROR) {
|
||||||
free(device);
|
free(device);
|
||||||
running[type][*device_idx] = NULL;
|
running[type][*device_idx] = NULL;
|
||||||
unlock;
|
unlock;
|
||||||
return de_FailedStart;
|
return de_FailedStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == input) {
|
if (type == input) {
|
||||||
alcCaptureStart(device->dhndl);
|
alcCaptureStart(device->dhndl);
|
||||||
thread_paused = false;
|
thread_paused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock;
|
unlock;
|
||||||
return de_None;
|
return de_None;
|
||||||
}
|
}
|
||||||
@ -301,47 +304,47 @@ DeviceError open_device(DeviceType type, int32_t selection, uint32_t* device_idx
|
|||||||
DeviceError close_device(DeviceType type, uint32_t device_idx)
|
DeviceError close_device(DeviceType type, uint32_t device_idx)
|
||||||
{
|
{
|
||||||
if (device_idx >= MAX_DEVICES) return de_InvalidSelection;
|
if (device_idx >= MAX_DEVICES) return de_InvalidSelection;
|
||||||
|
|
||||||
lock;
|
lock;
|
||||||
Device* device = running[type][device_idx];
|
Device* device = running[type][device_idx];
|
||||||
DeviceError rc = de_None;
|
DeviceError rc = de_None;
|
||||||
|
|
||||||
if (!device) {
|
if (!device) {
|
||||||
unlock;
|
unlock;
|
||||||
return de_DeviceNotActive;
|
return de_DeviceNotActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
running[type][device_idx] = NULL;
|
running[type][device_idx] = NULL;
|
||||||
|
|
||||||
if ( !device->ref_count ) {
|
if ( !device->ref_count ) {
|
||||||
|
|
||||||
// printf("Closed device ");
|
// printf("Closed device ");
|
||||||
|
|
||||||
if (type == input) {
|
if (type == input) {
|
||||||
if ( !alcCaptureCloseDevice(device->dhndl) ) rc = de_AlError;
|
if ( !alcCaptureCloseDevice(device->dhndl) ) rc = de_AlError;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (alcGetCurrentContext() != device->ctx) alcMakeContextCurrent(device->ctx);
|
if (alcGetCurrentContext() != device->ctx) alcMakeContextCurrent(device->ctx);
|
||||||
|
|
||||||
alDeleteSources(1, &device->source);
|
alDeleteSources(1, &device->source);
|
||||||
alDeleteBuffers(OPENAL_BUFS, device->buffers);
|
alDeleteBuffers(OPENAL_BUFS, device->buffers);
|
||||||
|
|
||||||
alcMakeContextCurrent(NULL);
|
alcMakeContextCurrent(NULL);
|
||||||
if ( device->ctx ) alcDestroyContext(device->ctx);
|
if ( device->ctx ) alcDestroyContext(device->ctx);
|
||||||
if ( !alcCloseDevice(device->dhndl) ) rc = de_AlError;
|
if ( !alcCloseDevice(device->dhndl) ) rc = de_AlError;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(device);
|
free(device);
|
||||||
}
|
}
|
||||||
else device->ref_count--;
|
else device->ref_count--;
|
||||||
|
|
||||||
unlock;
|
unlock;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceError register_device_callback( int32_t call_idx, uint32_t device_idx, DataHandleCallback callback, void* data, bool enable_VAD)
|
DeviceError register_device_callback( int32_t call_idx, uint32_t device_idx, DataHandleCallback callback, void* data, bool enable_VAD)
|
||||||
{
|
{
|
||||||
if (size[input] <= device_idx || !running[input][device_idx] || running[input][device_idx]->dhndl == NULL)
|
if (size[input] <= device_idx || !running[input][device_idx] || running[input][device_idx]->dhndl == NULL)
|
||||||
return de_InvalidSelection;
|
return de_InvalidSelection;
|
||||||
|
|
||||||
lock;
|
lock;
|
||||||
@ -375,9 +378,9 @@ inline__ DeviceError write_out(uint32_t device_idx, const int16_t* data, uint32_
|
|||||||
alSourceUnqueueBuffers(device->source, processed, bufids);
|
alSourceUnqueueBuffers(device->source, processed, bufids);
|
||||||
alDeleteBuffers(processed - 1, bufids + 1);
|
alDeleteBuffers(processed - 1, bufids + 1);
|
||||||
bufid = bufids[0];
|
bufid = bufids[0];
|
||||||
}
|
}
|
||||||
else if(queued < 16) alGenBuffers(1, &bufid);
|
else if(queued < 16) alGenBuffers(1, &bufid);
|
||||||
else {
|
else {
|
||||||
pthread_mutex_unlock(device->mutex);
|
pthread_mutex_unlock(device->mutex);
|
||||||
return de_Busy;
|
return de_Busy;
|
||||||
}
|
}
|
||||||
@ -404,44 +407,51 @@ void* thread_poll (void* arg) // TODO: maybe use thread for every input source
|
|||||||
(void)arg;
|
(void)arg;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int32_t sample = 0;
|
int32_t sample = 0;
|
||||||
|
|
||||||
|
|
||||||
while (thread_running)
|
while (true)
|
||||||
{
|
{
|
||||||
|
lock;
|
||||||
|
if (!thread_running) {
|
||||||
|
unlock;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
unlock;
|
||||||
|
|
||||||
if (thread_paused) usleep(10000); /* Wait for unpause. */
|
if (thread_paused) usleep(10000); /* Wait for unpause. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < size[input]; ++i)
|
for (i = 0; i < size[input]; ++i)
|
||||||
{
|
{
|
||||||
lock;
|
lock;
|
||||||
if (running[input][i] != NULL)
|
if (running[input][i] != NULL)
|
||||||
{
|
{
|
||||||
alcGetIntegerv(running[input][i]->dhndl, ALC_CAPTURE_SAMPLES, sizeof(int32_t), &sample);
|
alcGetIntegerv(running[input][i]->dhndl, ALC_CAPTURE_SAMPLES, sizeof(int32_t), &sample);
|
||||||
|
|
||||||
int f_size = (running[input][i]->sample_rate * running[input][i]->frame_duration / 1000);
|
int f_size = (running[input][i]->sample_rate * running[input][i]->frame_duration / 1000);
|
||||||
|
|
||||||
if (sample < f_size) {
|
if (sample < f_size) {
|
||||||
unlock;
|
unlock;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Device* device = running[input][i];
|
Device* device = running[input][i];
|
||||||
|
|
||||||
int16_t frame[16000];
|
int16_t frame[16000];
|
||||||
alcCaptureSamples(device->dhndl, frame, f_size);
|
alcCaptureSamples(device->dhndl, frame, f_size);
|
||||||
|
|
||||||
if (device->muted) {
|
if (device->muted) {
|
||||||
unlock;
|
unlock;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( device->cb ) device->cb(frame, f_size, device->cb_data);
|
if ( device->cb ) device->cb(frame, f_size, device->cb_data);
|
||||||
}
|
}
|
||||||
unlock;
|
unlock;
|
||||||
}
|
}
|
||||||
usleep(5000);
|
usleep(5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,8 +472,8 @@ DeviceError selection_valid(DeviceType type, int32_t selection)
|
|||||||
|
|
||||||
void* get_device_callback_data(uint32_t device_idx)
|
void* get_device_callback_data(uint32_t device_idx)
|
||||||
{
|
{
|
||||||
if (size[input] <= device_idx || !running[input][device_idx] || running[input][device_idx]->dhndl == NULL)
|
if (size[input] <= device_idx || !running[input][device_idx] || running[input][device_idx]->dhndl == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return running[input][device_idx]->cb_data;
|
return running[input][device_idx]->cb_data;
|
||||||
}
|
}
|
||||||
|
@ -624,10 +624,12 @@ static void draw_del_popup(void)
|
|||||||
wprintw(PendingDelete.popup, "Delete contact ");
|
wprintw(PendingDelete.popup, "Delete contact ");
|
||||||
wattron(PendingDelete.popup, A_BOLD);
|
wattron(PendingDelete.popup, A_BOLD);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
if (blocklist_view == 0)
|
if (blocklist_view == 0)
|
||||||
wprintw(PendingDelete.popup, "%s", Friends.list[PendingDelete.num].name);
|
wprintw(PendingDelete.popup, "%s", Friends.list[PendingDelete.num].name);
|
||||||
else
|
else
|
||||||
wprintw(PendingDelete.popup, "%s", Blocked.list[PendingDelete.num].name);
|
wprintw(PendingDelete.popup, "%s", Blocked.list[PendingDelete.num].name);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
wattroff(PendingDelete.popup, A_BOLD);
|
wattroff(PendingDelete.popup, A_BOLD);
|
||||||
wprintw(PendingDelete.popup, "? y/n");
|
wprintw(PendingDelete.popup, "? y/n");
|
||||||
@ -888,12 +890,13 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t cur_time = get_unix_time();
|
uint64_t cur_time = time(NULL);
|
||||||
struct tm cur_loc_tm = *localtime((const time_t *) &cur_time);
|
struct tm cur_loc_tm = *localtime((const time_t *) &cur_time);
|
||||||
|
|
||||||
wattron(self->window, A_BOLD);
|
wattron(self->window, A_BOLD);
|
||||||
wprintw(self->window, " Online: ");
|
wprintw(self->window, " Online: ");
|
||||||
wattroff(self->window, A_BOLD);
|
wattroff(self->window, A_BOLD);
|
||||||
|
|
||||||
wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends);
|
wprintw(self->window, "%d/%d \n\n", Friends.num_online, Friends.num_friends);
|
||||||
|
|
||||||
if ((y2 - FLIST_OFST) <= 0)
|
if ((y2 - FLIST_OFST) <= 0)
|
||||||
@ -902,18 +905,30 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
uint32_t selected_num = 0;
|
uint32_t selected_num = 0;
|
||||||
|
|
||||||
/* Determine which portion of friendlist to draw based on current position */
|
/* Determine which portion of friendlist to draw based on current position */
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
int page = Friends.num_selected / (y2 - FLIST_OFST);
|
int page = Friends.num_selected / (y2 - FLIST_OFST);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
int start = (y2 - FLIST_OFST) * page;
|
int start = (y2 - FLIST_OFST) * page;
|
||||||
int end = y2 - FLIST_OFST + start;
|
int end = y2 - FLIST_OFST + start;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
|
size_t num_friends = Friends.num_friends;
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = start; i < Friends.num_friends && i < end; ++i) {
|
for (i = start; i < num_friends && i < end; ++i) {
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
uint32_t f = Friends.index[i];
|
uint32_t f = Friends.index[i];
|
||||||
|
bool is_active = Friends.list[f].active;
|
||||||
|
int num_selected = Friends.num_selected;
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
bool f_selected = false;
|
bool f_selected = false;
|
||||||
|
|
||||||
if (Friends.list[f].active) {
|
if (is_active) {
|
||||||
if (i == Friends.num_selected) {
|
if (i == num_selected) {
|
||||||
wattron(self->window, A_BOLD);
|
wattron(self->window, A_BOLD);
|
||||||
wprintw(self->window, " > ");
|
wprintw(self->window, " > ");
|
||||||
wattroff(self->window, A_BOLD);
|
wattroff(self->window, A_BOLD);
|
||||||
@ -923,8 +938,12 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
wprintw(self->window, " ");
|
wprintw(self->window, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Friends.list[f].connection_status != TOX_CONNECTION_NONE) {
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
TOX_USER_STATUS status = Friends.list[f].status;
|
TOX_CONNECTION connection_status = Friends.list[f].connection_status;
|
||||||
|
TOX_USER_STATUS status = Friends.list[f].status;
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
|
if (connection_status != TOX_CONNECTION_NONE) {
|
||||||
int colour = MAGENTA;
|
int colour = MAGENTA;
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@ -947,7 +966,9 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
wattron(self->window, COLOR_PAIR(BLUE));
|
wattron(self->window, COLOR_PAIR(BLUE));
|
||||||
|
|
||||||
wattron(self->window, A_BOLD);
|
wattron(self->window, A_BOLD);
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
wprintw(self->window, "%s", Friends.list[f].name);
|
wprintw(self->window, "%s", Friends.list[f].name);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
wattroff(self->window, A_BOLD);
|
wattroff(self->window, A_BOLD);
|
||||||
|
|
||||||
if (f_selected)
|
if (f_selected)
|
||||||
@ -960,17 +981,23 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
pthread_mutex_lock(&Winthread.lock);
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
tox_friend_get_status_message(m, Friends.list[f].num, (uint8_t *) statusmsg, NULL);
|
tox_friend_get_status_message(m, Friends.list[f].num, (uint8_t *) statusmsg, NULL);
|
||||||
size_t s_len = tox_friend_get_status_message_size(m, Friends.list[f].num, NULL);
|
size_t s_len = tox_friend_get_status_message_size(m, Friends.list[f].num, NULL);
|
||||||
statusmsg[s_len] = '\0';
|
|
||||||
pthread_mutex_unlock(&Winthread.lock);
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
|
statusmsg[s_len] = '\0';
|
||||||
|
|
||||||
filter_str(statusmsg, s_len);
|
filter_str(statusmsg, s_len);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
snprintf(Friends.list[f].statusmsg, sizeof(Friends.list[f].statusmsg), "%s", statusmsg);
|
snprintf(Friends.list[f].statusmsg, sizeof(Friends.list[f].statusmsg), "%s", statusmsg);
|
||||||
Friends.list[f].statusmsg_len = strlen(Friends.list[f].statusmsg);
|
Friends.list[f].statusmsg_len = strlen(Friends.list[f].statusmsg);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Truncate note if it doesn't fit on one line */
|
/* Truncate note if it doesn't fit on one line */
|
||||||
size_t maxlen = x2 - getcurx(self->window) - 2;
|
size_t maxlen = x2 - getcurx(self->window) - 2;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
|
|
||||||
if (Friends.list[f].statusmsg_len > maxlen) {
|
if (Friends.list[f].statusmsg_len > maxlen) {
|
||||||
Friends.list[f].statusmsg[maxlen - 3] = '\0';
|
Friends.list[f].statusmsg[maxlen - 3] = '\0';
|
||||||
strcat(Friends.list[f].statusmsg, "...");
|
strcat(Friends.list[f].statusmsg, "...");
|
||||||
@ -981,6 +1008,8 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
if (Friends.list[f].statusmsg_len > 0)
|
if (Friends.list[f].statusmsg_len > 0)
|
||||||
wprintw(self->window, " %s", Friends.list[f].statusmsg);
|
wprintw(self->window, " %s", Friends.list[f].statusmsg);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
wprintw(self->window, "\n");
|
wprintw(self->window, "\n");
|
||||||
} else {
|
} else {
|
||||||
wprintw(self->window, "%s ", OFFLINE_CHAR);
|
wprintw(self->window, "%s ", OFFLINE_CHAR);
|
||||||
@ -989,21 +1018,29 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
wattron(self->window, COLOR_PAIR(BLUE));
|
wattron(self->window, COLOR_PAIR(BLUE));
|
||||||
|
|
||||||
wattron(self->window, A_BOLD);
|
wattron(self->window, A_BOLD);
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
wprintw(self->window, "%s", Friends.list[f].name);
|
wprintw(self->window, "%s", Friends.list[f].name);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
wattroff(self->window, A_BOLD);
|
wattroff(self->window, A_BOLD);
|
||||||
|
|
||||||
if (f_selected)
|
if (f_selected)
|
||||||
wattroff(self->window, COLOR_PAIR(BLUE));
|
wattroff(self->window, COLOR_PAIR(BLUE));
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
uint64_t last_seen = Friends.list[f].last_online.last_on;
|
uint64_t last_seen = Friends.list[f].last_online.last_on;
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
if (last_seen != 0) {
|
if (last_seen != 0) {
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
|
|
||||||
int day_dist = (
|
int day_dist = (
|
||||||
cur_loc_tm.tm_yday - Friends.list[f].last_online.tm.tm_yday
|
cur_loc_tm.tm_yday - Friends.list[f].last_online.tm.tm_yday
|
||||||
+ ((cur_loc_tm.tm_year - Friends.list[f].last_online.tm.tm_year) * 365)
|
+ ((cur_loc_tm.tm_year - Friends.list[f].last_online.tm.tm_year) * 365)
|
||||||
);
|
);
|
||||||
const char *hourmin = Friends.list[f].last_online.hour_min_str;
|
const char *hourmin = Friends.list[f].last_online.hour_min_str;
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
switch (day_dist) {
|
switch (day_dist) {
|
||||||
case 0:
|
case 0:
|
||||||
wprintw(self->window, " Last seen: Today %s\n", hourmin);
|
wprintw(self->window, " Last seen: Today %s\n", hourmin);
|
||||||
@ -1026,7 +1063,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
|
|||||||
|
|
||||||
self->x = x2;
|
self->x = x2;
|
||||||
|
|
||||||
if (Friends.num_friends) {
|
if (num_friends) {
|
||||||
wmove(self->window, y2 - 1, 1);
|
wmove(self->window, y2 - 1, 1);
|
||||||
|
|
||||||
wattron(self->window, A_BOLD);
|
wattron(self->window, A_BOLD);
|
||||||
|
@ -54,6 +54,7 @@ void hst_to_net(uint8_t *num, uint16_t numbytes)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: The time functions are not thread safe */
|
||||||
void update_unix_time(void)
|
void update_unix_time(void)
|
||||||
{
|
{
|
||||||
current_unix_time = (uint64_t) time(NULL);
|
current_unix_time = (uint64_t) time(NULL);
|
||||||
|
@ -53,16 +53,16 @@ int hex_string_to_bin(const char *hex_string, size_t hex_len, char *output, size
|
|||||||
/* convert a hex string to bytes. returns 0 on success, -1 on failure */
|
/* convert a hex string to bytes. returns 0 on success, -1 on failure */
|
||||||
int hex_string_to_bytes(char *buf, int size, const char *keystr);
|
int hex_string_to_bytes(char *buf, int size, const char *keystr);
|
||||||
|
|
||||||
/* get the current unix time */
|
/* get the current unix time (not thread safe) */
|
||||||
uint64_t get_unix_time(void);
|
uint64_t get_unix_time(void);
|
||||||
|
|
||||||
/* Puts the current time in buf in the format of [HH:mm:ss] */
|
/* Puts the current time in buf in the format of [HH:mm:ss] (not thread safe) */
|
||||||
void get_time_str(char *buf, int bufsize);
|
void get_time_str(char *buf, int bufsize);
|
||||||
|
|
||||||
/* Converts seconds to string in format HH:mm:ss; truncates hours and minutes when necessary */
|
/* Converts seconds to string in format HH:mm:ss; truncates hours and minutes when necessary */
|
||||||
void get_elapsed_time_str(char *buf, int bufsize, uint64_t secs);
|
void get_elapsed_time_str(char *buf, int bufsize, uint64_t secs);
|
||||||
|
|
||||||
/* get the current local time */
|
/* get the current local time (not thread safe) */
|
||||||
struct tm *get_time(void);
|
struct tm *get_time(void);
|
||||||
|
|
||||||
/* updates current unix time (should be run once per do_toxic loop) */
|
/* updates current unix time (should be run once per do_toxic loop) */
|
||||||
|
@ -257,7 +257,7 @@ void* do_playing(void* _p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef BOX_NOTIFY
|
#ifdef BOX_NOTIFY
|
||||||
else if (actives[i].box && get_unix_time() >= actives[i].n_timeout)
|
else if (actives[i].box && time(NULL) >= actives[i].n_timeout)
|
||||||
{
|
{
|
||||||
GError* ignore;
|
GError* ignore;
|
||||||
notify_notification_close(actives[i].box, &ignore);
|
notify_notification_close(actives[i].box, &ignore);
|
||||||
@ -278,7 +278,7 @@ void* do_playing(void* _p)
|
|||||||
|
|
||||||
/* device is opened and no activity in under DEVICE_COOLDOWN time, close device*/
|
/* device is opened and no activity in under DEVICE_COOLDOWN time, close device*/
|
||||||
if (device_opened && !has_looping &&
|
if (device_opened && !has_looping &&
|
||||||
(get_unix_time() - last_opened_update) > DEVICE_COOLDOWN) {
|
(time(NULL) - last_opened_update) > DEVICE_COOLDOWN) {
|
||||||
m_close_device();
|
m_close_device();
|
||||||
}
|
}
|
||||||
has_looping = false;
|
has_looping = false;
|
||||||
@ -323,7 +323,7 @@ void* do_playing(void* _p)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
|
for (i = 0; i < ACTIVE_NOTIFS_MAX; i ++) {
|
||||||
if (actives[i].box && get_unix_time() >= actives[i].n_timeout)
|
if (actives[i].box && time(NULL) >= actives[i].n_timeout)
|
||||||
{
|
{
|
||||||
GError* ignore;
|
GError* ignore;
|
||||||
notify_notification_close(actives[i].box, &ignore);
|
notify_notification_close(actives[i].box, &ignore);
|
||||||
@ -391,7 +391,7 @@ int init_notify(int login_cooldown, int notification_timeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Control.cooldown = get_unix_time() + login_cooldown;
|
Control.cooldown = time(NULL) + login_cooldown;
|
||||||
|
|
||||||
|
|
||||||
#ifdef BOX_NOTIFY
|
#ifdef BOX_NOTIFY
|
||||||
|
24
src/prompt.c
24
src/prompt.c
@ -260,14 +260,23 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
|||||||
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
|
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
|
||||||
|
|
||||||
StatusBar *statusbar = self->stb;
|
StatusBar *statusbar = self->stb;
|
||||||
|
|
||||||
mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2);
|
mvwhline(statusbar->topline, 1, 0, ACS_HLINE, x2);
|
||||||
wmove(statusbar->topline, 0, 0);
|
wmove(statusbar->topline, 0, 0);
|
||||||
|
|
||||||
if (statusbar->connection != TOX_CONNECTION_NONE) {
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
|
TOX_CONNECTION connection = statusbar->connection;
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
|
if (connection != TOX_CONNECTION_NONE) {
|
||||||
int colour = MAGENTA;
|
int colour = MAGENTA;
|
||||||
const char *status_text = "ERROR";
|
const char *status_text = "ERROR";
|
||||||
|
|
||||||
switch (statusbar->status) {
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
|
TOX_USER_STATUS status = statusbar->status;
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
case TOX_USER_STATUS_NONE:
|
case TOX_USER_STATUS_NONE:
|
||||||
status_text = "Online";
|
status_text = "Online";
|
||||||
colour = GREEN;
|
colour = GREEN;
|
||||||
@ -287,12 +296,16 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
|||||||
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
|
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
|
||||||
|
|
||||||
wattron(statusbar->topline, A_BOLD);
|
wattron(statusbar->topline, A_BOLD);
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
wprintw(statusbar->topline, " %s", statusbar->nick);
|
wprintw(statusbar->topline, " %s", statusbar->nick);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
wattroff(statusbar->topline, A_BOLD);
|
wattroff(statusbar->topline, A_BOLD);
|
||||||
} else {
|
} else {
|
||||||
wprintw(statusbar->topline, " [Offline]");
|
wprintw(statusbar->topline, " [Offline]");
|
||||||
wattron(statusbar->topline, A_BOLD);
|
wattron(statusbar->topline, A_BOLD);
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
wprintw(statusbar->topline, " %s", statusbar->nick);
|
wprintw(statusbar->topline, " %s", statusbar->nick);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
wattroff(statusbar->topline, A_BOLD);
|
wattroff(statusbar->topline, A_BOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,10 +317,9 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
|||||||
size_t slen = tox_self_get_status_message_size(m);
|
size_t slen = tox_self_get_status_message_size(m);
|
||||||
tox_self_get_status_message (m, (uint8_t*) statusmsg);
|
tox_self_get_status_message (m, (uint8_t*) statusmsg);
|
||||||
statusmsg[slen] = '\0';
|
statusmsg[slen] = '\0';
|
||||||
pthread_mutex_unlock(&Winthread.lock);
|
|
||||||
|
|
||||||
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
|
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
|
||||||
statusbar->statusmsg_len = strlen(statusbar->statusmsg);
|
statusbar->statusmsg_len = strlen(statusbar->statusmsg);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->x = x2;
|
self->x = x2;
|
||||||
@ -315,6 +327,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
|||||||
/* Truncate note if it doesn't fit in statusbar */
|
/* Truncate note if it doesn't fit in statusbar */
|
||||||
uint16_t maxlen = x2 - getcurx(statusbar->topline) - 3;
|
uint16_t maxlen = x2 - getcurx(statusbar->topline) - 3;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
|
|
||||||
if (statusbar->statusmsg_len > maxlen) {
|
if (statusbar->statusmsg_len > maxlen) {
|
||||||
statusbar->statusmsg[maxlen - 3] = '\0';
|
statusbar->statusmsg[maxlen - 3] = '\0';
|
||||||
strcat(statusbar->statusmsg, "...");
|
strcat(statusbar->statusmsg, "...");
|
||||||
@ -324,6 +338,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
|||||||
if (statusbar->statusmsg[0])
|
if (statusbar->statusmsg[0])
|
||||||
wprintw(statusbar->topline, " : %s", statusbar->statusmsg);
|
wprintw(statusbar->topline, " : %s", statusbar->statusmsg);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);
|
mvwhline(self->window, y2 - CHATBOX_HEIGHT, 0, ACS_HLINE, x2);
|
||||||
|
|
||||||
int y, x;
|
int y, x;
|
||||||
|
26
src/toxic.c
26
src/toxic.c
@ -807,10 +807,14 @@ static void do_bootstrap(Tox *m)
|
|||||||
|
|
||||||
static void do_toxic(Tox *m, ToxWindow *prompt)
|
static void do_toxic(Tox *m, ToxWindow *prompt)
|
||||||
{
|
{
|
||||||
if (arg_opts.no_connect)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&Winthread.lock);
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
|
update_unix_time();
|
||||||
|
|
||||||
|
if (arg_opts.no_connect) {
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tox_iterate(m);
|
tox_iterate(m);
|
||||||
do_bootstrap(m);
|
do_bootstrap(m);
|
||||||
check_file_transfer_timeouts(m);
|
check_file_transfer_timeouts(m);
|
||||||
@ -822,6 +826,7 @@ static void do_toxic(Tox *m, ToxWindow *prompt)
|
|||||||
void *thread_winref(void *data)
|
void *thread_winref(void *data)
|
||||||
{
|
{
|
||||||
Tox *m = (Tox *) data;
|
Tox *m = (Tox *) data;
|
||||||
|
|
||||||
uint8_t draw_count = 0;
|
uint8_t draw_count = 0;
|
||||||
init_signal_catchers();
|
init_signal_catchers();
|
||||||
|
|
||||||
@ -1105,14 +1110,16 @@ static useconds_t optimal_msleepval(uint64_t *looptimer, uint64_t *loopcount, ui
|
|||||||
return new_sleep;
|
return new_sleep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this doesn't do anything (yet)
|
||||||
#ifdef X11
|
#ifdef X11
|
||||||
// FIXME
|
|
||||||
void DnD_callback(const char* asdv, DropType dt)
|
void DnD_callback(const char* asdv, DropType dt)
|
||||||
{
|
{
|
||||||
if (dt != DT_plain)
|
// if (dt != DT_plain)
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, asdv);
|
// pthread_mutex_lock(&Winthread.lock);
|
||||||
|
// line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, asdv);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
}
|
}
|
||||||
#endif /* X11 */
|
#endif /* X11 */
|
||||||
|
|
||||||
@ -1181,6 +1188,7 @@ int main(int argc, char *argv[])
|
|||||||
if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
|
if (pthread_create(&cqueue_thread.tid, NULL, thread_cqueue, (void *) m) != 0)
|
||||||
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
|
exit_toxic_err("failed in main", FATALERR_THREAD_CREATE);
|
||||||
|
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
|
|
||||||
av = init_audio(prompt, m);
|
av = init_audio(prompt, m);
|
||||||
@ -1214,7 +1222,10 @@ int main(int argc, char *argv[])
|
|||||||
if (init_mplex_away_timer(m) == -1)
|
if (init_mplex_away_timer(m) == -1)
|
||||||
queue_init_message("Failed to init mplex auto-away.");
|
queue_init_message("Failed to init mplex auto-away.");
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
print_init_messages(prompt);
|
print_init_messages(prompt);
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
cleanup_init_messages();
|
cleanup_init_messages();
|
||||||
|
|
||||||
/* set user avatar from config file. if no path is supplied tox_unset_avatar is called */
|
/* set user avatar from config file. if no path is supplied tox_unset_avatar is called */
|
||||||
@ -1228,7 +1239,6 @@ int main(int argc, char *argv[])
|
|||||||
uint64_t loopcount = 0;
|
uint64_t loopcount = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
update_unix_time();
|
|
||||||
do_toxic(m, prompt);
|
do_toxic(m, prompt);
|
||||||
uint64_t cur_time = get_unix_time();
|
uint64_t cur_time = get_unix_time();
|
||||||
|
|
||||||
|
@ -454,10 +454,16 @@ void on_window_resize(void)
|
|||||||
|
|
||||||
static void draw_window_tab(ToxWindow *toxwin)
|
static void draw_window_tab(ToxWindow *toxwin)
|
||||||
{
|
{
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
if (toxwin->alert != WINDOW_ALERT_NONE) attron(COLOR_PAIR(toxwin->alert));
|
if (toxwin->alert != WINDOW_ALERT_NONE) attron(COLOR_PAIR(toxwin->alert));
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
clrtoeol();
|
clrtoeol();
|
||||||
printw(" [%s]", toxwin->name);
|
printw(" [%s]", toxwin->name);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
if (toxwin->alert != WINDOW_ALERT_NONE) attroff(COLOR_PAIR(toxwin->alert));
|
if (toxwin->alert != WINDOW_ALERT_NONE) attroff(COLOR_PAIR(toxwin->alert));
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_bar(void)
|
static void draw_bar(void)
|
||||||
@ -505,7 +511,10 @@ static void draw_bar(void)
|
|||||||
void draw_active_window(Tox *m)
|
void draw_active_window(Tox *m)
|
||||||
{
|
{
|
||||||
ToxWindow *a = active_window;
|
ToxWindow *a = active_window;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
a->alert = WINDOW_ALERT_NONE;
|
a->alert = WINDOW_ALERT_NONE;
|
||||||
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
|
|
||||||
wint_t ch = 0;
|
wint_t ch = 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user