1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-30 07:53:27 +01:00
This commit is contained in:
Jfreegman 2014-04-20 16:43:14 -04:00
commit 3a9056745f
23 changed files with 805 additions and 723 deletions

View File

@ -27,9 +27,9 @@
typedef struct _DeviceIx { typedef struct _DeviceIx {
ALCdevice* dhndl; /* Handle of device selected/opened */ ALCdevice *dhndl; /* Handle of device selected/opened */
ALCcontext* ctx; /* Device context */ ALCcontext *ctx; /* Device context */
const char* devices[MAX_DEVICES]; /* Container of available devices */ const char *devices[MAX_DEVICES]; /* Container of available devices */
int size; /* Size of above container */ int size; /* Size of above container */
int dix; /* Index of default device */ int dix; /* Index of default device */
int index; /* Current index */ int index; /* Current index */
@ -41,7 +41,7 @@ struct _ASettings {
AudioError errors; AudioError errors;
ToxAv* av; ToxAv *av;
pthread_t ttid; /* Transmission thread id */ pthread_t ttid; /* Transmission thread id */
int ttas; /* Transmission thread active status (0 - stopped, 1- running) */ int ttas; /* Transmission thread active status (0 - stopped, 1- running) */
@ -57,7 +57,7 @@ void callback_call_canceled ( void *arg );
void callback_call_rejected ( void *arg ); void callback_call_rejected ( void *arg );
void callback_call_ended ( void *arg ); void callback_call_ended ( void *arg );
void callback_requ_timeout ( void *arg ); void callback_requ_timeout ( void *arg );
void callback_peer_timeout ( void* arg ); void callback_peer_timeout ( void *arg );
static void print_err (ToxWindow *self, uint8_t *error_str) static void print_err (ToxWindow *self, uint8_t *error_str)
@ -89,17 +89,17 @@ int device_open (ToxWindow *self, _Devices type)
/* Do not error if no device */ /* Do not error if no device */
if ( !ASettins.device[type].size ) return 0; if ( !ASettins.device[type].size ) return 0;
ALCdevice* prev_device = ASettins.device[type].dhndl; ALCdevice *prev_device = ASettins.device[type].dhndl;
uint8_t msg[MAX_STR_SIZE]; uint8_t msg[MAX_STR_SIZE];
uint8_t* error = NULL; uint8_t *error = NULL;
if ( type == input ) { if ( type == input ) {
ASettins.device[type].dhndl = alcCaptureOpenDevice( ASettins.device[type].dhndl = alcCaptureOpenDevice(
ASettins.device[type].devices[ASettins.device[type].index], ASettins.device[type].devices[ASettins.device[type].index],
av_DefaultSettings.audio_sample_rate, av_DefaultSettings.audio_sample_rate,
AL_FORMAT_MONO16, AL_FORMAT_MONO16,
AUDIO_FRAME_SIZE * 4); AUDIO_FRAME_SIZE * 4);
if (alcGetError(ASettins.device[type].dhndl) != AL_NO_ERROR) { if (alcGetError(ASettins.device[type].dhndl) != AL_NO_ERROR) {
@ -108,16 +108,13 @@ int device_open (ToxWindow *self, _Devices type)
error = "Error starting input device!"; error = "Error starting input device!";
ASettins.errors |= ErrorStartingCaptureDevice; ASettins.errors |= ErrorStartingCaptureDevice;
} } else {
else {
error = "Could not start input device, falling back to previous"; error = "Could not start input device, falling back to previous";
/* NOTE: What if device is opened? */ /* NOTE: What if device is opened? */
ASettins.device[type].dhndl = prev_device; ASettins.device[type].dhndl = prev_device;
} }
} } else {
else
{
/* Close previous */ /* Close previous */
if ( prev_device ) if ( prev_device )
alcCaptureCloseDevice(prev_device); alcCaptureCloseDevice(prev_device);
@ -129,8 +126,7 @@ int device_open (ToxWindow *self, _Devices type)
} }
ASettins.device[type].ctx = NULL; ASettins.device[type].ctx = NULL;
} } else {
else {
ASettins.device[type].dhndl = alcOpenDevice(ASettins.device[type].devices[ASettins.device[type].index]); ASettins.device[type].dhndl = alcOpenDevice(ASettins.device[type].devices[ASettins.device[type].index]);
if (alcGetError(ASettins.device[type].dhndl) != AL_NO_ERROR) { if (alcGetError(ASettins.device[type].dhndl) != AL_NO_ERROR) {
@ -141,15 +137,13 @@ int device_open (ToxWindow *self, _Devices type)
ASettins.errors |= ErrorStartingOutputDevice; ASettins.errors |= ErrorStartingOutputDevice;
ASettins.device[type].ctx = NULL; ASettins.device[type].ctx = NULL;
} } else {
else {
error = "Could not start output device, falling back to previous"; error = "Could not start output device, falling back to previous";
/* NOTE: What if device is opened? */ /* NOTE: What if device is opened? */
ASettins.device[type].dhndl = prev_device; ASettins.device[type].dhndl = prev_device;
} }
} } else {
else {
/* Close previous */ /* Close previous */
if ( prev_device ) { if ( prev_device ) {
@ -174,20 +168,18 @@ int device_open (ToxWindow *self, _Devices type)
} }
return -1; return -1;
} } else return 0;
else return 0;
} }
int device_close (ToxWindow *self, _Devices type) int device_close (ToxWindow *self, _Devices type)
{ {
uint8_t* device = NULL; uint8_t *device = NULL;
if ( ASettins.device[type].dhndl ) { if ( ASettins.device[type].dhndl ) {
if (type == input) { if (type == input) {
alcCaptureCloseDevice(ASettins.device[type].dhndl); alcCaptureCloseDevice(ASettins.device[type].dhndl);
device = "input"; device = "input";
} } else {
else {
alcCloseDevice(ASettins.device[type].dhndl); alcCloseDevice(ASettins.device[type].dhndl);
alcMakeContextCurrent(NULL); alcMakeContextCurrent(NULL);
@ -207,17 +199,17 @@ int device_close (ToxWindow *self, _Devices type)
} }
} }
ToxAv* init_audio(ToxWindow* self, Tox* tox) ToxAv *init_audio(ToxWindow *self, Tox *tox)
{ {
ASettins.errors = NoError; ASettins.errors = NoError;
ASettins.ttas = 0; /* Not running */ ASettins.ttas = 0; /* Not running */
/* Capture devices */ /* Capture devices */
const char* stringed_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER); const char *stringed_device_list = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
ASettins.device[input].size = 0; ASettins.device[input].size = 0;
if ( stringed_device_list ) { if ( stringed_device_list ) {
const char* default_device = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER); const char *default_device = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
for ( ; *stringed_device_list; ++ASettins.device[input].size ) { for ( ; *stringed_device_list; ++ASettins.device[input].size ) {
ASettins.device[input].devices[ASettins.device[input].size] = stringed_device_list; ASettins.device[input].devices[ASettins.device[input].size] = stringed_device_list;
@ -235,7 +227,7 @@ ToxAv* init_audio(ToxWindow* self, Tox* tox)
ASettins.device[output].size = 0; ASettins.device[output].size = 0;
if ( stringed_device_list ) { if ( stringed_device_list ) {
const char* default_device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); const char *default_device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
for ( ; *stringed_device_list; ++ASettins.device[output].size ) { for ( ; *stringed_device_list; ++ASettins.device[output].size ) {
ASettins.device[output].devices[ASettins.device[output].size] = stringed_device_list; ASettins.device[output].devices[ASettins.device[output].size] = stringed_device_list;
@ -251,8 +243,7 @@ ToxAv* init_audio(ToxWindow* self, Tox* tox)
uint8_t *msg = "No devices: disabling audio!"; uint8_t *msg = "No devices: disabling audio!";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
ASettins.av = NULL; ASettins.av = NULL;
} } else {
else {
/* Streaming stuff from core */ /* Streaming stuff from core */
ToxAvCodecSettings cs = av_DefaultSettings; ToxAvCodecSettings cs = av_DefaultSettings;
@ -302,7 +293,7 @@ int errors()
* Transmission * Transmission
*/ */
void* transmission(void* arg) void *transmission(void *arg)
{ {
(void)arg; /* Avoid warning */ (void)arg; /* Avoid warning */
@ -335,6 +326,7 @@ void* transmission(void* arg)
int16_t PCM[AUDIO_FRAME_SIZE]; int16_t PCM[AUDIO_FRAME_SIZE];
int32_t i = 0; int32_t i = 0;
for (; i < openal_buffers; ++i) { for (; i < openal_buffers; ++i) {
alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, AUDIO_FRAME_SIZE, 48000); alBufferData(buffers[i], AL_FORMAT_MONO16, zeros, AUDIO_FRAME_SIZE, 48000);
} }
@ -415,12 +407,13 @@ int start_transmission(ToxWindow *self)
if ( !ASettins.av ) return -1; if ( !ASettins.av ) return -1;
if ( !toxav_capability_supported(ASettins.av, AudioDecoding) || if ( !toxav_capability_supported(ASettins.av, AudioDecoding) ||
!toxav_capability_supported(ASettins.av, AudioEncoding) ) !toxav_capability_supported(ASettins.av, AudioEncoding) )
return -1; return -1;
/* Now open our devices */ /* Now open our devices */
if ( -1 == device_open(self, input) ) if ( -1 == device_open(self, input) )
return -1; return -1;
if ( -1 == device_open(self, output)) if ( -1 == device_open(self, output))
return -1; return -1;
@ -428,7 +421,7 @@ int start_transmission(ToxWindow *self)
toxav_prepare_transmission(ASettins.av, 0); toxav_prepare_transmission(ASettins.av, 0);
if ( 0 != pthread_create(&ASettins.ttid, NULL, transmission, NULL ) && if ( 0 != pthread_create(&ASettins.ttid, NULL, transmission, NULL ) &&
0 != pthread_detach(ASettins.ttid) ) { 0 != pthread_detach(ASettins.ttid) ) {
return -1; return -1;
} }
} }
@ -452,53 +445,53 @@ int stop_transmission()
#define CB_BODY(Arg, onFunc) do { ToxWindow* windows = (Arg); int i;\ #define CB_BODY(Arg, onFunc) do { ToxWindow* windows = (Arg); int i;\
for (i = 0; i < MAX_WINDOWS_NUM; ++i) if (windows[i].onFunc != NULL) windows[i].onFunc(&windows[i], ASettins.av); } while (0) for (i = 0; i < MAX_WINDOWS_NUM; ++i) if (windows[i].onFunc != NULL) windows[i].onFunc(&windows[i], ASettins.av); } while (0)
void callback_recv_invite ( void* arg ) void callback_recv_invite ( void *arg )
{ {
CB_BODY(arg, onInvite); CB_BODY(arg, onInvite);
} }
void callback_recv_ringing ( void* arg ) void callback_recv_ringing ( void *arg )
{ {
CB_BODY(arg, onRinging); CB_BODY(arg, onRinging);
} }
void callback_recv_starting ( void* arg ) void callback_recv_starting ( void *arg )
{ {
CB_BODY(arg, onStarting); CB_BODY(arg, onStarting);
} }
void callback_recv_ending ( void* arg ) void callback_recv_ending ( void *arg )
{ {
CB_BODY(arg, onEnding); CB_BODY(arg, onEnding);
stop_transmission(); stop_transmission();
} }
void callback_recv_error ( void* arg ) void callback_recv_error ( void *arg )
{ {
CB_BODY(arg, onError); CB_BODY(arg, onError);
} }
void callback_call_started ( void* arg ) void callback_call_started ( void *arg )
{ {
CB_BODY(arg, onStart); CB_BODY(arg, onStart);
} }
void callback_call_canceled ( void* arg ) void callback_call_canceled ( void *arg )
{ {
CB_BODY(arg, onCancel); CB_BODY(arg, onCancel);
/* In case call is active */ /* In case call is active */
stop_transmission(); stop_transmission();
} }
void callback_call_rejected ( void* arg ) void callback_call_rejected ( void *arg )
{ {
CB_BODY(arg, onReject); CB_BODY(arg, onReject);
} }
void callback_call_ended ( void* arg ) void callback_call_ended ( void *arg )
{ {
CB_BODY(arg, onEnd); CB_BODY(arg, onEnd);
stop_transmission(); stop_transmission();
} }
void callback_requ_timeout ( void* arg ) void callback_requ_timeout ( void *arg )
{ {
CB_BODY(arg, onRequestTimeout); CB_BODY(arg, onRequestTimeout);
} }
void callback_peer_timeout ( void* arg ) void callback_peer_timeout ( void *arg )
{ {
CB_BODY(arg, onPeerTimeout); CB_BODY(arg, onPeerTimeout);
stop_transmission(); stop_transmission();
@ -518,11 +511,17 @@ void callback_peer_timeout ( void* arg )
void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_call(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
uint8_t msg[MAX_STR_SIZE]; uint8_t msg[MAX_STR_SIZE];
uint8_t* error_str; uint8_t *error_str;
if (argc != 0) { error_str = "Invalid syntax!"; goto on_error; } if (argc != 0) {
error_str = "Invalid syntax!";
goto on_error;
}
if ( !ASettins.av ) { error_str = "Audio not supported!"; goto on_error; } if ( !ASettins.av ) {
error_str = "Audio not supported!";
goto on_error;
}
ToxAvError error = toxav_call(ASettins.av, self->num, TypeAudio, 30); ToxAvError error = toxav_call(ASettins.av, self->num, TypeAudio, 30);
@ -544,11 +543,17 @@ on_error:
void cmd_answer(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_answer(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
uint8_t* error_str; uint8_t *error_str;
if (argc != 0) { error_str = "Invalid syntax!"; goto on_error; } if (argc != 0) {
error_str = "Invalid syntax!";
goto on_error;
}
if ( !ASettins.av ) { error_str = "Audio not supported!"; goto on_error; } if ( !ASettins.av ) {
error_str = "Audio not supported!";
goto on_error;
}
ToxAvError error = toxav_answer(ASettins.av, TypeAudio); ToxAvError error = toxav_answer(ASettins.av, TypeAudio);
@ -569,11 +574,17 @@ on_error:
void cmd_reject(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_reject(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
uint8_t* error_str; uint8_t *error_str;
if (argc != 0) { error_str = "Invalid syntax!"; goto on_error; } if (argc != 0) {
error_str = "Invalid syntax!";
goto on_error;
}
if ( !ASettins.av ) { error_str = "Audio not supported!"; goto on_error; } if ( !ASettins.av ) {
error_str = "Audio not supported!";
goto on_error;
}
ToxAvError error = toxav_reject(ASettins.av, "Why not?"); ToxAvError error = toxav_reject(ASettins.av, "Why not?");
@ -594,11 +605,17 @@ on_error:
void cmd_hangup(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_hangup(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
uint8_t* error_str; uint8_t *error_str;
if (argc != 0) { error_str = "Invalid syntax!"; goto on_error; } if (argc != 0) {
error_str = "Invalid syntax!";
goto on_error;
}
if ( !ASettins.av ) { error_str = "Audio not supported!"; goto on_error; } if ( !ASettins.av ) {
error_str = "Audio not supported!";
goto on_error;
}
ToxAvError error = toxav_hangup(ASettins.av); ToxAvError error = toxav_hangup(ASettins.av);
@ -617,13 +634,20 @@ on_error:
void cmd_cancel(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_cancel(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
uint8_t* error_str; uint8_t *error_str;
if (argc != 0) { error_str = "Invalid syntax!"; goto on_error; } if (argc != 0) {
error_str = "Invalid syntax!";
goto on_error;
}
if ( !ASettins.av ) { error_str = "Audio not supported!"; goto on_error; } if ( !ASettins.av ) {
error_str = "Audio not supported!";
goto on_error;
}
ToxAvError error = toxav_cancel(ASettins.av, self->num, "Only those who appreciate small things know the beauty of life"); ToxAvError error = toxav_cancel(ASettins.av, self->num,
"Only those who appreciate small things know the beauty of life");
if ( error != ErrorNone ) { if ( error != ErrorNone ) {
if ( error == ErrorNoCall ) error_str = "No call!"; if ( error == ErrorNoCall ) error_str = "No call!";
@ -643,7 +667,7 @@ on_error:
void cmd_list_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_list_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
uint8_t msg[MAX_STR_SIZE]; uint8_t msg[MAX_STR_SIZE];
uint8_t* error_str; uint8_t *error_str;
if ( argc != 1 ) { if ( argc != 1 ) {
if ( argc < 1 ) error_str = "Type must be specified!"; if ( argc < 1 ) error_str = "Type must be specified!";
@ -667,6 +691,7 @@ void cmd_list_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*
} }
int i = 0; int i = 0;
for ( ; i < ASettins.device[type].size; i ++) { for ( ; i < ASettins.device[type].size; i ++) {
snprintf(msg, sizeof(msg), "%d: %s", i, ASettins.device[type].devices[i]); snprintf(msg, sizeof(msg), "%d: %s", i, ASettins.device[type].devices[i]);
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
@ -680,7 +705,7 @@ on_error:
void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) void cmd_change_device(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{ {
uint8_t msg[MAX_STR_SIZE]; uint8_t msg[MAX_STR_SIZE];
uint8_t* error_str; uint8_t *error_str;
if ( argc != 2 ) { if ( argc != 2 ) {
if ( argc < 1 ) error_str = "Type must be specified!"; if ( argc < 1 ) error_str = "Type must be specified!";

View File

@ -9,16 +9,14 @@
#define MAX_DEVICES 32 #define MAX_DEVICES 32
typedef enum _AudioError typedef enum _AudioError {
{
NoError = 0, NoError = 0,
ErrorStartingCaptureDevice = 1 << 0, ErrorStartingCaptureDevice = 1 << 0,
ErrorStartingOutputDevice = 1 << 1, ErrorStartingOutputDevice = 1 << 1,
ErrorStartingCoreAudio = 1 << 2 ErrorStartingCoreAudio = 1 << 2
} AudioError; } AudioError;
typedef enum _Devices typedef enum _Devices {
{
input, input,
output, output,
} _Devices; } _Devices;
@ -26,7 +24,7 @@ typedef enum _Devices
/* You will have to pass pointer to first member of 'windows' /* You will have to pass pointer to first member of 'windows'
* declared in windows.c otherwise undefined behaviour will * declared in windows.c otherwise undefined behaviour will
*/ */
ToxAv* init_audio(ToxWindow* self, Tox* tox); ToxAv *init_audio(ToxWindow *self, Tox *tox);
void terminate_audio(); void terminate_audio();
int errors(); int errors();

View File

@ -38,7 +38,7 @@
#include "settings.h" #include "settings.h"
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#include "audio_call.h" #include "audio_call.h"
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
extern char *DATA_FILE; extern char *DATA_FILE;
@ -51,9 +51,9 @@ extern struct _Winthread Winthread;
extern struct user_settings *user_settings; extern struct user_settings *user_settings;
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#define AC_NUM_CHAT_COMMANDS 23 #define AC_NUM_CHAT_COMMANDS 23
#else #else
#define AC_NUM_CHAT_COMMANDS 18 #define AC_NUM_CHAT_COMMANDS 18
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
/* Array of chat command names used for tab completion. */ /* Array of chat command names used for tab completion. */
@ -129,7 +129,7 @@ static void chat_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *msg, u
uint8_t nick[TOX_MAX_NAME_LENGTH]; uint8_t nick[TOX_MAX_NAME_LENGTH];
int n_len = tox_get_name(m, num, nick); int n_len = tox_get_name(m, num, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
nick[n_len] = '\0'; nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE]; uint8_t timefrmt[TIME_STR_SIZE];
@ -178,7 +178,7 @@ static void chat_onAction(ToxWindow *self, Tox *m, int32_t num, uint8_t *action,
uint8_t nick[TOX_MAX_NAME_LENGTH]; uint8_t nick[TOX_MAX_NAME_LENGTH];
int n_len = tox_get_name(m, num, nick); int n_len = tox_get_name(m, num, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1);; n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);;
nick[n_len] = '\0'; nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE]; uint8_t timefrmt[TIME_STR_SIZE];
@ -194,7 +194,7 @@ static void chat_onNickChange(ToxWindow *self, Tox *m, int32_t num, uint8_t *nic
if (self->num != num) if (self->num != num)
return; return;
len = MIN(len, TOXIC_MAX_NAME_LENGTH-1); len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
nick[len] = '\0'; nick[len] = '\0';
strcpy(self->name, nick); strcpy(self->name, nick);
} }
@ -232,7 +232,7 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
get_file_name(pathname, filename); get_file_name(pathname, filename);
snprintf(msg, sizeof(msg), "File transfer request for '%s' (%llu bytes).", filename, snprintf(msg, sizeof(msg), "File transfer request for '%s' (%llu bytes).", filename,
(long long unsigned int)filesize); (long long unsigned int)filesize);
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
if (filenum >= MAX_FILES) { if (filenum >= MAX_FILES) {
@ -249,7 +249,7 @@ static void chat_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t
while ((filecheck = fopen(filename, "r"))) { while ((filecheck = fopen(filename, "r"))) {
filename[len] = '\0'; filename[len] = '\0';
char d[9]; char d[9];
sprintf(d,"(%d)", count++); sprintf(d, "(%d)", count++);
strcat(filename, d); strcat(filename, d);
filename[len + strlen(d)] = '\0'; filename[len + strlen(d)] = '\0';
@ -295,22 +295,26 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, int32_t num, uint8_t rec
filename = file_senders[filenum].pathname; filename = file_senders[filenum].pathname;
switch (control_type) { switch (control_type) {
case TOX_FILECONTROL_ACCEPT: case TOX_FILECONTROL_ACCEPT:
snprintf(msg, sizeof(msg), "File transfer for '%s' accepted (%.1f%%)", filename, 0.0); snprintf(msg, sizeof(msg), "File transfer for '%s' accepted (%.1f%%)", filename, 0.0);
file_senders[filenum].line_id = self->chatwin->hst->line_end->id + 1; file_senders[filenum].line_id = self->chatwin->hst->line_end->id + 1;
break; break;
/*case TOX_FILECONTROL_PAUSE:
wprintw(ctx->history, "File transfer for '%s' paused.\n", filename); /*case TOX_FILECONTROL_PAUSE:
break; */ wprintw(ctx->history, "File transfer for '%s' paused.\n", filename);
case TOX_FILECONTROL_KILL: break; */
snprintf(msg, sizeof(msg), "File transfer for '%s' failed.", filename); case TOX_FILECONTROL_KILL:
if (receive_send == 0) snprintf(msg, sizeof(msg), "File transfer for '%s' failed.", filename);
if (receive_send == 0)
chat_close_file_receiver(num, filenum);
break;
case TOX_FILECONTROL_FINISHED:
snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename);
chat_close_file_receiver(num, filenum); chat_close_file_receiver(num, filenum);
break; break;
case TOX_FILECONTROL_FINISHED:
snprintf(msg, sizeof(msg), "File transfer for '%s' complete.", filename);
chat_close_file_receiver(num, filenum);
break;
} }
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
@ -355,11 +359,11 @@ static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, ui
uint8_t msg[MAX_STR_SIZE + TOX_MAX_NAME_LENGTH]; uint8_t msg[MAX_STR_SIZE + TOX_MAX_NAME_LENGTH];
int n_len = tox_get_name(m, friendnumber, name); int n_len = tox_get_name(m, friendnumber, name);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
name[n_len] = '\0'; name[n_len] = '\0';
snprintf(msg, sizeof(msg), "%s has invited you to a group chat.\n" snprintf(msg, sizeof(msg), "%s has invited you to a group chat.\n"
"Type \"/join\" to join the chat.", name); "Type \"/join\" to join the chat.", name);
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
memcpy(friends[friendnumber].pending_groupchat, group_pub_key, TOX_CLIENT_ID_SIZE); memcpy(friends[friendnumber].pending_groupchat, group_pub_key, TOX_CLIENT_ID_SIZE);
@ -492,7 +496,8 @@ void chat_onPeerTimeout (ToxWindow *self, ToxAv *av)
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *action) { static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *action)
{
if (action == NULL) if (action == NULL)
return; return;
@ -536,11 +541,11 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (ltr) { if (ltr) {
/* prevents buffer overflows and strange behaviour when cursor goes past the window */ /* prevents buffer overflows and strange behaviour when cursor goes past the window */
if ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) { if ( (ctx->len < MAX_STR_SIZE - 1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1) - 1)) ) {
add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key); add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);
if (x == x2-1) if (x == x2 - 1)
wmove(self->window, y+1, 0); wmove(self->window, y + 1, 0);
else else
wmove(self->window, y, x + MAX(1, wcwidth(key))); wmove(self->window, y, x + MAX(1, wcwidth(key)));
} }
@ -556,7 +561,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len); del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);
if (x == 0) if (x == 0)
wmove(self->window, y-1, x2 - cur_len); wmove(self->window, y - 1, x2 - cur_len);
else else
wmove(self->window, y, x - cur_len); wmove(self->window, y, x - cur_len);
} else { } else {
@ -597,7 +602,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
else if (key == KEY_END || key == T_KEY_C_E) { /* END/C-e key: move cursor to end of line */ else if (key == KEY_END || key == T_KEY_C_E) { /* END/C-e key: move cursor to end of line */
if (ctx->pos != ctx->len) { if (ctx->pos != ctx->len) {
ctx->pos = ctx->len; ctx->pos = ctx->len;
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT-1)*x2)), y2, x2); mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT - 1)*x2)), y2, x2);
} }
} }
@ -607,7 +612,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));
if (x == 0) if (x == 0)
wmove(self->window, y-1, x2 - cur_len); wmove(self->window, y - 1, x2 - cur_len);
else else
wmove(self->window, y, x - cur_len); wmove(self->window, y, x - cur_len);
} else { } else {
@ -620,8 +625,8 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));
++ctx->pos; ++ctx->pos;
if (x == x2-1) if (x == x2 - 1)
wmove(self->window, y+1, 0); wmove(self->window, y + 1, 0);
else else
wmove(self->window, y, x + cur_len); wmove(self->window, y, x + cur_len);
} else { } else {
@ -649,9 +654,9 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) { if (x + diff > x2 - 1) {
int ofst = (x + diff - 1) - (x2 - 1); int ofst = (x + diff - 1) - (x2 - 1);
wmove(self->window, y+1, ofst); wmove(self->window, y + 1, ofst);
} else { } else {
wmove(self->window, y, x+diff); wmove(self->window, y, x + diff);
} }
} else { } else {
beep(); beep();
@ -753,22 +758,25 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
uint8_t status = statusbar->status; uint8_t status = statusbar->status;
switch (status) { switch (status) {
case TOX_USERSTATUS_NONE: case TOX_USERSTATUS_NONE:
status_text = "Online"; status_text = "Online";
colour = GREEN; colour = GREEN;
break; break;
case TOX_USERSTATUS_AWAY:
status_text = "Away"; case TOX_USERSTATUS_AWAY:
colour = YELLOW; status_text = "Away";
break; colour = YELLOW;
case TOX_USERSTATUS_BUSY: break;
status_text = "Busy";
colour = RED; case TOX_USERSTATUS_BUSY:
break; status_text = "Busy";
case TOX_USERSTATUS_INVALID: colour = RED;
status_text = "ERROR"; break;
colour = MAGENTA;
break; case TOX_USERSTATUS_INVALID:
status_text = "ERROR";
colour = MAGENTA;
break;
} }
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
@ -808,6 +816,7 @@ static void chat_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) - (KEY_IDENT_DIGITS * 2) - 7; uint16_t maxlen = x2 - getcurx(statusbar->topline) - (KEY_IDENT_DIGITS * 2) - 7;
if (statusbar->statusmsg_len > maxlen) { if (statusbar->statusmsg_len > maxlen) {
statusbar->statusmsg[maxlen] = '\0'; statusbar->statusmsg[maxlen] = '\0';
statusbar->statusmsg_len = maxlen; statusbar->statusmsg_len = maxlen;
@ -852,9 +861,9 @@ static void chat_onInit(ToxWindow *self, Tox *m)
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
statusbar->topline = subwin(self->window, 2, x2, 0, 0); statusbar->topline = subwin(self->window, 2, x2, 0, 0);
ctx->history = subwin(self->window, y2-CHATBOX_HEIGHT+1, x2, 0, 0); ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
scrollok(ctx->history, 1); scrollok(ctx->history, 1);
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2-CHATBOX_HEIGHT, 0); ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
ctx->hst = malloc(sizeof(struct history)); ctx->hst = malloc(sizeof(struct history));
ctx->log = malloc(sizeof(struct chatlog)); ctx->log = malloc(sizeof(struct chatlog));
@ -919,7 +928,7 @@ ToxWindow new_chat(Tox *m, int32_t friendnum)
uint8_t name[TOX_MAX_NAME_LENGTH] = {'\0'}; uint8_t name[TOX_MAX_NAME_LENGTH] = {'\0'};
int len = tox_get_name(m, friendnum, name); int len = tox_get_name(m, friendnum, name);
len = MIN(len, TOXIC_MAX_NAME_LENGTH-1); len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
name[len] = '\0'; name[len] = '\0';
strcpy(ret.name, name); strcpy(ret.name, name);

View File

@ -57,29 +57,29 @@ void cmd_chat_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN);
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#define NUMLINES 13 #define NUMLINES 13
#else #else
#define NUMLINES 9 #define NUMLINES 9
#endif #endif
uint8_t lines[NUMLINES][MAX_STR_SIZE] = { uint8_t lines[NUMLINES][MAX_STR_SIZE] = {
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
{ " /call : Audio call" }, { " /call : Audio call" },
{ " /cancel : Cancel call" }, { " /cancel : Cancel call" },
{ " /answer : Answer incomming call" }, { " /answer : Answer incomming call" },
{ " /reject : Reject incoming call" }, { " /reject : Reject incoming call" },
{ " /hangup : Hangup active call" }, { " /hangup : Hangup active call" },
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
{ " /invite <n> : Invite friend to a group chat" }, { " /invite <n> : Invite friend to a group chat" },
{ " /join : Join a pending group chat" }, { " /join : Join a pending group chat" },
{ " /log <on> or <off> : Enable/disable logging" }, { " /log <on> or <off> : Enable/disable logging" },
{ " /sendfile <filepath> : Send a file" }, { " /sendfile <filepath> : Send a file" },
{ " /savefile <n> : Receive a file" }, { " /savefile <n> : Receive a file" },
{ " /close : Close the current chat window" }, { " /close : Close the current chat window" },
{ " /help : Print this message again" }, { " /help : Print this message again" },
{ " /help global : Show a list of global commands" }, { " /help global : Show a list of global commands" },
}; };
int i; int i;
@ -160,9 +160,9 @@ void cmd_savefile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
uint8_t *errmsg; uint8_t *errmsg;
if (argc != 1) { if (argc != 1) {
errmsg = "Invalid syntax."; errmsg = "Invalid syntax.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return; return;
} }
uint8_t filenum = atoi(argv[1]); uint8_t filenum = atoi(argv[1]);
@ -204,16 +204,16 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
{ {
uint8_t *errmsg; uint8_t *errmsg;
if (max_file_senders_index >= (MAX_FILES-1)) { if (max_file_senders_index >= (MAX_FILES - 1)) {
errmsg = "Please wait for some of your outgoing file transfers to complete."; errmsg = "Please wait for some of your outgoing file transfers to complete.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return; return;
} }
if (argc < 1) { if (argc < 1) {
errmsg = "Invalid syntax."; errmsg = "Invalid syntax.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return; return;
} }
uint8_t *path = argv[1]; uint8_t *path = argv[1];
@ -224,7 +224,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv
return; return;
} }
path[strlen(++path)-1] = L'\0'; path[strlen(++path) - 1] = L'\0';
int path_len = strlen(path); int path_len = strlen(path);
if (path_len > MAX_STR_SIZE) { if (path_len > MAX_STR_SIZE) {

View File

@ -110,6 +110,7 @@ char *get_user_config_dir(void)
# else /* __APPLE__ */ # else /* __APPLE__ */
const char *tmp; const char *tmp;
if (!(tmp = getenv("XDG_CONFIG_HOME"))) { if (!(tmp = getenv("XDG_CONFIG_HOME"))) {
len = strlen(home) + strlen("/.config") + 1; len = strlen(home) + strlen("/.config") + 1;
user_config_dir = malloc(len); user_config_dir = malloc(len);

View File

@ -87,7 +87,7 @@ static int parse_command(WINDOW *w, ToxWindow *self, char *cmd, char (*args)[MAX
/* characters wrapped in double quotes count as one arg */ /* characters wrapped in double quotes count as one arg */
while (!cmd_end && num_args < MAX_NUM_ARGS) { while (!cmd_end && num_args < MAX_NUM_ARGS) {
if (*cmd == '\"') { if (*cmd == '\"') {
end = strchr(cmd+1, '\"'); end = strchr(cmd + 1, '\"');
if (end++ == NULL) { /* Increment past the end quote */ if (end++ == NULL) { /* Increment past the end quote */
uint8_t *errmsg = "Invalid argument. Did you forget a closing \"?"; uint8_t *errmsg = "Invalid argument. Did you forget a closing \"?";
@ -120,7 +120,7 @@ static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, int num_
for (i = 0; i < num_cmds; ++i) { for (i = 0; i < num_cmds; ++i) {
if (strcmp(args[0], commands[i].name) == 0) { if (strcmp(args[0], commands[i].name) == 0) {
(commands[i].func)(w, self, m, num_args-1, args); (commands[i].func)(w, self, m, num_args - 1, args);
return 0; return 0;
} }
} }
@ -128,7 +128,7 @@ static int do_command(WINDOW *w, ToxWindow *self, Tox *m, int num_args, int num_
return 1; return 1;
} }
void execute(WINDOW* w, ToxWindow *self, Tox *m, char *cmd, int mode) void execute(WINDOW *w, ToxWindow *self, Tox *m, char *cmd, int mode)
{ {
if (string_is_empty(cmd)) if (string_is_empty(cmd))
return; return;
@ -144,13 +144,14 @@ void execute(WINDOW* w, ToxWindow *self, Tox *m, char *cmd, int mode)
Note: Global commands must come last in case of duplicate command names */ Note: Global commands must come last in case of duplicate command names */
switch (mode) { switch (mode) {
case CHAT_COMMAND_MODE: case CHAT_COMMAND_MODE:
if (do_command(w, self, m, num_args, CHAT_NUM_COMMANDS, chat_commands, args) == 0) if (do_command(w, self, m, num_args, CHAT_NUM_COMMANDS, chat_commands, args) == 0)
return; return;
break;
case GROUPCHAT_COMMAND_MODE: break;
break;
case GROUPCHAT_COMMAND_MODE:
break;
} }
if (do_command(w, self, m, num_args, GLOBAL_NUM_COMMANDS, global_commands, args) == 0) if (do_command(w, self, m, num_args, GLOBAL_NUM_COMMANDS, global_commands, args) == 0)

View File

@ -23,11 +23,11 @@
#define MAX_NUM_ARGS 4 /* Includes command */ #define MAX_NUM_ARGS 4 /* Includes command */
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#define GLOBAL_NUM_COMMANDS 16 #define GLOBAL_NUM_COMMANDS 16
#define CHAT_NUM_COMMANDS 10 #define CHAT_NUM_COMMANDS 10
#else #else
#define GLOBAL_NUM_COMMANDS 14 #define GLOBAL_NUM_COMMANDS 14
#define CHAT_NUM_COMMANDS 5 #define CHAT_NUM_COMMANDS 5
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
enum { enum {

View File

@ -42,7 +42,7 @@ static void close_file_sender(int i)
int j; int j;
for (j = max_file_senders_index; j > 0; --j) { for (j = max_file_senders_index; j > 0; --j) {
if (file_senders[j-1].active) if (file_senders[j - 1].active)
break; break;
} }

View File

@ -94,7 +94,7 @@ static void update_friend_last_online(int32_t num, uint64_t timestamp)
/* if the format changes make sure TIME_STR_SIZE is the correct size */ /* if the format changes make sure TIME_STR_SIZE is the correct size */
const char *t = user_settings->time == TIME_12 ? "%I:%M %p" : "%H:%M"; const char *t = user_settings->time == TIME_12 ? "%I:%M %p" : "%H:%M";
strftime(friends[num].last_online.hour_min_str, TIME_STR_SIZE, t, strftime(friends[num].last_online.hour_min_str, TIME_STR_SIZE, t,
&friends[num].last_online.tm); &friends[num].last_online.tm);
} }
static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *str, uint16_t len) static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *str, uint16_t len)
@ -110,7 +110,7 @@ static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *
uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'};
int n_len = tox_get_name(m, num, nick); int n_len = tox_get_name(m, num, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
nick[n_len] = '\0'; nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE]; uint8_t timefrmt[TIME_STR_SIZE];
@ -141,7 +141,7 @@ static void friendlist_onNickChange(ToxWindow *self, Tox *m, int32_t num, uint8_
if (len > TOX_MAX_NAME_LENGTH || num >= max_friends_index) if (len > TOX_MAX_NAME_LENGTH || num >= max_friends_index)
return; return;
len = MIN(len, TOXIC_MAX_NAME_LENGTH-1); len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
str[len] = '\0'; str[len] = '\0';
strcpy(friends[num].name, str); strcpy(friends[num].name, str);
@ -208,7 +208,7 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort)
} }
static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum,
uint64_t filesize, uint8_t *filename, uint16_t filename_len) uint64_t filesize, uint8_t *filename, uint16_t filename_len)
{ {
if (num >= max_friends_index) if (num >= max_friends_index)
return; return;
@ -221,7 +221,7 @@ static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, u
uint8_t nick[TOX_MAX_NAME_LENGTH]; uint8_t nick[TOX_MAX_NAME_LENGTH];
int n_len = tox_get_name(m, num, nick); int n_len = tox_get_name(m, num, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
nick[n_len] = '\0'; nick[n_len] = '\0';
uint8_t msg[MAX_STR_SIZE]; uint8_t msg[MAX_STR_SIZE];
@ -244,7 +244,7 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, uint8
} else { } else {
uint8_t nick[TOX_MAX_NAME_LENGTH]; uint8_t nick[TOX_MAX_NAME_LENGTH];
int n_len = tox_get_name(m, num, nick); int n_len = tox_get_name(m, num, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
nick[n_len] = '\0'; nick[n_len] = '\0';
uint8_t msg[MAX_STR_SIZE]; uint8_t msg[MAX_STR_SIZE];
@ -274,7 +274,7 @@ static void delete_friend(Tox *m, int32_t f_num)
int i; int i;
for (i = max_friends_index; i > 0; --i) { for (i = max_friends_index; i > 0; --i) {
if (friends[i-1].active) if (friends[i - 1].active)
break; break;
} }
@ -433,18 +433,21 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
int colour = WHITE; int colour = WHITE;
switch (status) { switch (status) {
case TOX_USERSTATUS_NONE: case TOX_USERSTATUS_NONE:
colour = GREEN; colour = GREEN;
break; break;
case TOX_USERSTATUS_AWAY:
colour = YELLOW; case TOX_USERSTATUS_AWAY:
break; colour = YELLOW;
case TOX_USERSTATUS_BUSY: break;
colour = RED;
break; case TOX_USERSTATUS_BUSY:
case TOX_USERSTATUS_INVALID: colour = RED;
colour = MAGENTA; break;
break;
case TOX_USERSTATUS_INVALID:
colour = MAGENTA;
break;
} }
wattron(self->window, COLOR_PAIR(colour) | A_BOLD); wattron(self->window, COLOR_PAIR(colour) | A_BOLD);
@ -467,7 +470,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
pthread_mutex_lock(&Winthread.lock); pthread_mutex_lock(&Winthread.lock);
uint16_t s_len = tox_get_status_message(m, friends[f].num, statusmsg, uint16_t s_len = tox_get_status_message(m, friends[f].num, statusmsg,
TOX_MAX_STATUSMESSAGE_LENGTH); TOX_MAX_STATUSMESSAGE_LENGTH);
pthread_mutex_unlock(&Winthread.lock); pthread_mutex_unlock(&Winthread.lock);
friends[f].statusmsg_len = s_len; friends[f].statusmsg_len = s_len;
@ -477,8 +480,9 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
/* Truncate note if it doesn't fit on one line */ /* Truncate note if it doesn't fit on one line */
uint16_t maxlen = x2 - getcurx(self->window) - 2; uint16_t maxlen = x2 - getcurx(self->window) - 2;
if (friends[f].statusmsg_len > maxlen) { if (friends[f].statusmsg_len > maxlen) {
friends[f].statusmsg[maxlen-3] = '\0'; friends[f].statusmsg[maxlen - 3] = '\0';
strcat(friends[f].statusmsg, "..."); strcat(friends[f].statusmsg, "...");
friends[f].statusmsg[maxlen] = '\0'; friends[f].statusmsg[maxlen] = '\0';
friends[f].statusmsg_len = maxlen; friends[f].statusmsg_len = maxlen;
@ -508,15 +512,17 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m)
const uint8_t *hourmin = friends[f].last_online.hour_min_str; const uint8_t *hourmin = friends[f].last_online.hour_min_str;
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);
break; break;
case 1:
wprintw(self->window, " Last seen: Yesterday %s\n", hourmin); case 1:
break; wprintw(self->window, " Last seen: Yesterday %s\n", hourmin);
default: break;
wprintw(self->window, " Last seen: %d days ago\n", day_dist);
break; default:
wprintw(self->window, " Last seen: %d days ago\n", day_dist);
break;
} }
} else { } else {
wprintw(self->window, " Last seen: Never\n"); wprintw(self->window, " Last seen: Never\n");
@ -539,11 +545,12 @@ void disable_chatwin(int32_t f_num)
static void friendlist_onAv(ToxWindow *self, ToxAv *av) static void friendlist_onAv(ToxWindow *self, ToxAv *av)
{ {
int id = toxav_get_peer_id(av, 0); int id = toxav_get_peer_id(av, 0);
/*id++;*/ /*id++;*/
if ( id != ErrorInternal && id >= max_friends_index) if ( id != ErrorInternal && id >= max_friends_index)
return; return;
Tox* m = toxav_get_tox(av); Tox *m = toxav_get_tox(av);
if (friends[id].chatwin == -1) { if (friends[id].chatwin == -1) {
if (get_num_active_windows() < MAX_WINDOWS_NUM) { if (get_num_active_windows() < MAX_WINDOWS_NUM) {
@ -552,7 +559,7 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av)
uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'};
int n_len = tox_get_name(m, id, nick); int n_len = tox_get_name(m, id, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
nick[n_len] = '\0'; nick[n_len] = '\0';
uint8_t msg[MAX_STR_SIZE]; uint8_t msg[MAX_STR_SIZE];

View File

@ -54,7 +54,7 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
int req = atoi(argv[1]); int req = atoi(argv[1]);
if ((req == 0 && strcmp(argv[1], "0"))|| req >= MAX_FRIENDS_NUM) { if ((req == 0 && strcmp(argv[1], "0")) || req >= MAX_FRIENDS_NUM) {
msg = "No pending friend request with that number."; msg = "No pending friend request with that number.";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
return; return;
@ -80,7 +80,7 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
int i; int i;
for (i = num_frnd_requests; i > 0; --i) { for (i = num_frnd_requests; i > 0; --i) {
if (!strlen(pending_frnd_requests[i-1])) if (!strlen(pending_frnd_requests[i - 1]))
break; break;
} }
@ -110,7 +110,7 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
return; return;
} }
temp[strlen(++temp)-1] = L'\0'; temp[strlen(++temp) - 1] = L'\0';
snprintf(msg, sizeof(msg), "%s", temp); snprintf(msg, sizeof(msg), "%s", temp);
} else { } else {
uint8_t selfname[TOX_MAX_NAME_LENGTH]; uint8_t selfname[TOX_MAX_NAME_LENGTH];
@ -151,31 +151,38 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
int32_t f_num = tox_add_friend(m, id_bin, msg, strlen(msg)); int32_t f_num = tox_add_friend(m, id_bin, msg, strlen(msg));
switch (f_num) { switch (f_num) {
case TOX_FAERR_TOOLONG: case TOX_FAERR_TOOLONG:
errmsg = "Message is too long."; errmsg = "Message is too long.";
break; break;
case TOX_FAERR_NOMESSAGE:
errmsg = "Please add a message to your request."; case TOX_FAERR_NOMESSAGE:
break; errmsg = "Please add a message to your request.";
case TOX_FAERR_OWNKEY: break;
errmsg = "That appears to be your own ID.";
break; case TOX_FAERR_OWNKEY:
case TOX_FAERR_ALREADYSENT: errmsg = "That appears to be your own ID.";
errmsg = "Friend request has already been sent."; break;
break;
case TOX_FAERR_UNKNOWN: case TOX_FAERR_ALREADYSENT:
errmsg = "Undefined error when adding friend."; errmsg = "Friend request has already been sent.";
break; break;
case TOX_FAERR_BADCHECKSUM:
errmsg = "Bad checksum in address."; case TOX_FAERR_UNKNOWN:
break; errmsg = "Undefined error when adding friend.";
case TOX_FAERR_SETNEWNOSPAM: break;
errmsg = "Nospam was different (is this contact already added?";
break; case TOX_FAERR_BADCHECKSUM:
default: errmsg = "Bad checksum in address.";
errmsg = "Friend request sent."; break;
on_friendadded(m, f_num, true);
break; case TOX_FAERR_SETNEWNOSPAM:
errmsg = "Nospam was different (is this contact already added?";
break;
default:
errmsg = "Friend request sent.";
on_friendadded(m, f_num, true);
break;
} }
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
@ -192,12 +199,11 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
/* check arguments */ /* check arguments */
if (argc != 3) { if (argc != 3) {
errmsg = "Invalid syntax."; errmsg = "Invalid syntax.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return; return;
} }
tox_IP_Port dht;
char *ip = argv[1]; char *ip = argv[1];
char *port = argv[2]; char *port = argv[2];
char *key = argv[3]; char *key = argv[3];
@ -315,9 +321,9 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
/* check arguments */ /* check arguments */
if (argc < 1) { if (argc < 1) {
errmsg = "Invalid name."; errmsg = "Invalid name.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0); line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return; return;
} }
uint8_t *nick = argv[1]; uint8_t *nick = argv[1];
@ -335,7 +341,7 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
return; return;
} }
len = MIN(len, TOXIC_MAX_NAME_LENGTH-1); len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1);
nick[len] = L'\0'; nick[len] = L'\0';
@ -363,7 +369,7 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
return; return;
} }
msg[strlen(++msg)-1] = L'\0'; msg[strlen(++msg) - 1] = L'\0';
uint16_t len = strlen(msg); uint16_t len = strlen(msg);
tox_set_status_message(m, msg, len); tox_set_status_message(m, msg, len);
prompt_update_statusmessage(prompt, msg, len); prompt_update_statusmessage(prompt, msg, len);
@ -379,31 +385,31 @@ void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*a
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN);
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#define NUMLINES 14 #define NUMLINES 14
#else #else
#define NUMLINES 12 #define NUMLINES 12
#endif #endif
uint8_t lines[NUMLINES][MAX_STR_SIZE] = { uint8_t lines[NUMLINES][MAX_STR_SIZE] = {
{ " /add <id> <msg> : Add friend with optional message" }, { " /add <id> <msg> : Add friend with optional message" },
{ " /accept <n> : Accept friend request" }, { " /accept <n> : Accept friend request" },
{ " /connect <ip> <port> <key> : Manually connect to a DHT node" }, { " /connect <ip> <port> <key> : Manually connect to a DHT node" },
{ " /status <type> <msg> : Set status with optional note" }, { " /status <type> <msg> : Set status with optional note" },
{ " /note <msg> : Set a personal note" }, { " /note <msg> : Set a personal note" },
{ " /nick <nick> : Set your nickname" }, { " /nick <nick> : Set your nickname" },
{ " /log <on> or <off> : Enable/disable logging" }, { " /log <on> or <off> : Enable/disable logging" },
{ " /groupchat : Create a group chat" }, { " /groupchat : Create a group chat" },
{ " /myid : Print your ID" }, { " /myid : Print your ID" },
{ " /help : Print this message again" }, { " /help : Print this message again" },
{ " /clear : Clear window history" }, { " /clear : Clear window history" },
{ " /quit or /exit : Exit Toxic" }, { " /quit or /exit : Exit Toxic" },
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
{ " /lsdev <type> : List devices where type: in|out" }, { " /lsdev <type> : List devices where type: in|out" },
{ " /sdev <type> <id> : Set active device" }, { " /sdev <type> <id> : Set active device" },
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
}; };
int i; int i;
for (i = 0; i < NUMLINES; ++i) for (i = 0; i < NUMLINES; ++i)
@ -442,7 +448,7 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
char *status = argv[1]; char *status = argv[1];
int len = strlen(status); int len = strlen(status);
char l_status[len+1]; char l_status[len + 1];
int i; int i;
for (i = 0; i <= len; ++i) for (i = 0; i <= len; ++i)
@ -466,7 +472,7 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
prompt_update_status(prompt, status_kind); prompt_update_status(prompt, status_kind);
if (msg != NULL) { if (msg != NULL) {
msg[strlen(++msg)-1] = L'\0'; /* remove opening and closing quotes */ msg[strlen(++msg) - 1] = L'\0'; /* remove opening and closing quotes */
uint16_t len = strlen(msg); uint16_t len = strlen(msg);
tox_set_status_message(m, msg, len); tox_set_status_message(m, msg, len);
prompt_update_statusmessage(prompt, msg, len); prompt_update_statusmessage(prompt, msg, len);

View File

@ -108,7 +108,7 @@ static void close_groupchat(ToxWindow *self, Tox *m, int groupnum)
int i; int i;
for (i = max_groupchat_index; i > 0; --i) { for (i = max_groupchat_index; i > 0; --i) {
if (groupchats[i-1].active) if (groupchats[i - 1].active)
break; break;
} }
@ -125,21 +125,21 @@ static void print_groupchat_help(ToxWindow *self)
uint8_t *msg = "Group chat commands:"; uint8_t *msg = "Group chat commands:";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN); line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN);
#define NUMLINES 9 #define NUMLINES 9
uint8_t lines[NUMLINES][MAX_STR_SIZE] = { uint8_t lines[NUMLINES][MAX_STR_SIZE] = {
{ " /add <id> <msg> : Add friend with optional message" }, { " /add <id> <msg> : Add friend with optional message" },
{ " /status <type> <msg>: Set your status with optional note" }, { " /status <type> <msg>: Set your status with optional note" },
{ " /note <msg> : Set a personal note" }, { " /note <msg> : Set a personal note" },
{ " /nick <nick> : Set your nickname" }, { " /nick <nick> : Set your nickname" },
{ " /groupchat : Create a group chat" }, { " /groupchat : Create a group chat" },
{ " /log <on> or <off> : Enable/disable logging" }, { " /log <on> or <off> : Enable/disable logging" },
{ " /close : Close the current group chat" }, { " /close : Close the current group chat" },
{ " /help : Print this message again" }, { " /help : Print this message again" },
{ " /help global : Show a list of global commands" }, { " /help global : Show a list of global commands" },
}; };
int i; int i;
@ -169,7 +169,7 @@ static void groupchat_onGroupMessage(ToxWindow *self, Tox *m, int groupnum, int
uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'};
int n_len = tox_group_peername(m, groupnum, peernum, nick); int n_len = tox_group_peername(m, groupnum, peernum, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); /* enforce client max name length */ n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); /* enforce client max name length */
nick[n_len] = '\0'; nick[n_len] = '\0';
/* check if message contains own name and alert appropriately */ /* check if message contains own name and alert appropriately */
@ -229,7 +229,7 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p
uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'}; uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'};
n_len = tox_group_peername(m, groupnum, peernum, nick); n_len = tox_group_peername(m, groupnum, peernum, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
nick[n_len] = '\0'; nick[n_len] = '\0';
uint8_t timefrmt[TIME_STR_SIZE]; uint8_t timefrmt[TIME_STR_SIZE];
@ -259,7 +259,7 @@ static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], ui
memset(groupchats[gnum].peer_name_lengths, 0, sizeof(uint16_t) * npeers); memset(groupchats[gnum].peer_name_lengths, 0, sizeof(uint16_t) * npeers);
if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL if (groupchats[gnum].peer_names == NULL || groupchats[gnum].oldpeer_names == NULL
|| groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) { || groupchats[gnum].peer_name_lengths == NULL || groupchats[gnum].oldpeer_name_lengths == NULL) {
endwin(); endwin();
fprintf(stderr, "malloc() failed. Aborting...\n"); fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -270,26 +270,26 @@ static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], ui
for (i = 0; i < npeers; ++i) { for (i = 0; i < npeers; ++i) {
if (string_is_empty(peerlist[i])) { if (string_is_empty(peerlist[i])) {
memcpy(&groupchats[gnum].peer_names[i*N], UNKNOWN_NAME, sizeof(UNKNOWN_NAME)); memcpy(&groupchats[gnum].peer_names[i * N], UNKNOWN_NAME, sizeof(UNKNOWN_NAME));
groupchats[gnum].peer_name_lengths[i] = unknown_len; groupchats[gnum].peer_name_lengths[i] = unknown_len;
} else { } else {
memcpy(&groupchats[gnum].peer_names[i*N], peerlist[i], N); memcpy(&groupchats[gnum].peer_names[i * N], peerlist[i], N);
uint16_t n_len = lengths[i]; uint16_t n_len = lengths[i];
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
groupchats[gnum].peer_names[i*N+n_len] = '\0'; groupchats[gnum].peer_names[i * N + n_len] = '\0';
groupchats[gnum].peer_name_lengths[i] = n_len; groupchats[gnum].peer_name_lengths[i] = n_len;
} }
} }
memcpy(groupchats[gnum].oldpeer_names, groupchats[gnum].peer_names, N*npeers); memcpy(groupchats[gnum].oldpeer_names, groupchats[gnum].peer_names, N * npeers);
memcpy(groupchats[gnum].oldpeer_name_lengths, groupchats[gnum].peer_name_lengths, memcpy(groupchats[gnum].oldpeer_name_lengths, groupchats[gnum].peer_name_lengths,
sizeof(uint16_t) * npeers); sizeof(uint16_t) * npeers);
} }
static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnum, int peernum, static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnum, int peernum,
uint8_t change) uint8_t change)
{ {
if (self->num != groupnum) if (self->num != groupnum)
return; return;
@ -301,7 +301,7 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
uint8_t oldpeername[TOX_MAX_NAME_LENGTH]; uint8_t oldpeername[TOX_MAX_NAME_LENGTH];
if (change != TOX_CHAT_CHANGE_PEER_ADD) { if (change != TOX_CHAT_CHANGE_PEER_ADD) {
memcpy(oldpeername, &groupchats[groupnum].oldpeer_names[peernum*TOX_MAX_NAME_LENGTH], memcpy(oldpeername, &groupchats[groupnum].oldpeer_names[peernum * TOX_MAX_NAME_LENGTH],
sizeof(oldpeername)); sizeof(oldpeername));
uint16_t old_n_len = groupchats[groupnum].oldpeer_name_lengths[peernum]; uint16_t old_n_len = groupchats[groupnum].oldpeer_name_lengths[peernum];
oldpeername[old_n_len] = '\0'; oldpeername[old_n_len] = '\0';
@ -318,7 +318,7 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
if (change != TOX_CHAT_CHANGE_PEER_DEL) { if (change != TOX_CHAT_CHANGE_PEER_DEL) {
uint16_t n_len = groupchats[groupnum].peer_name_lengths[peernum]; uint16_t n_len = groupchats[groupnum].peer_name_lengths[peernum];
memcpy(peername, &groupchats[groupnum].peer_names[peernum*TOX_MAX_NAME_LENGTH], sizeof(peername)); memcpy(peername, &groupchats[groupnum].peer_names[peernum * TOX_MAX_NAME_LENGTH], sizeof(peername));
peername[n_len] = '\0'; peername[n_len] = '\0';
} }
@ -331,36 +331,37 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu
get_time_str(timefrmt); get_time_str(timefrmt);
switch (change) { switch (change) {
case TOX_CHAT_CHANGE_PEER_ADD: case TOX_CHAT_CHANGE_PEER_ADD:
event = "has joined the room"; event = "has joined the room";
line_info_add(self, timefrmt, peername, NULL, event, CONNECTION, 0, GREEN); line_info_add(self, timefrmt, peername, NULL, event, CONNECTION, 0, GREEN);
write_to_log(event, peername, ctx->log, true); write_to_log(event, peername, ctx->log, true);
break; break;
case TOX_CHAT_CHANGE_PEER_DEL: case TOX_CHAT_CHANGE_PEER_DEL:
event = "has left the room"; event = "has left the room";
line_info_add(self, timefrmt, oldpeername, NULL, event, CONNECTION, 0, 0); line_info_add(self, timefrmt, oldpeername, NULL, event, CONNECTION, 0, 0);
if (groupchats[self->num].side_pos > 0) if (groupchats[self->num].side_pos > 0)
--groupchats[self->num].side_pos; --groupchats[self->num].side_pos;
write_to_log(event, oldpeername, ctx->log, true); write_to_log(event, oldpeername, ctx->log, true);
break; break;
case TOX_CHAT_CHANGE_PEER_NAME: case TOX_CHAT_CHANGE_PEER_NAME:
event = " is now known as "; event = " is now known as ";
line_info_add(self, timefrmt, oldpeername, peername, event, NAME_CHANGE, 0, 0); line_info_add(self, timefrmt, oldpeername, peername, event, NAME_CHANGE, 0, 0);
uint8_t tmp_event[TOXIC_MAX_NAME_LENGTH * 2 + 32]; uint8_t tmp_event[TOXIC_MAX_NAME_LENGTH * 2 + 32];
snprintf(tmp_event, sizeof(tmp_event), "is now known as %s", peername); snprintf(tmp_event, sizeof(tmp_event), "is now known as %s", peername);
write_to_log(tmp_event, oldpeername, ctx->log, true); write_to_log(tmp_event, oldpeername, ctx->log, true);
break; break;
} }
alert_window(self, WINDOW_ALERT_2, false); alert_window(self, WINDOW_ALERT_2, false);
} }
static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *action) { static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *action)
{
if (action == NULL) { if (action == NULL) {
wprintw(ctx->history, "Invalid syntax.\n"); wprintw(ctx->history, "Invalid syntax.\n");
return; return;
@ -393,11 +394,11 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} }
if (ltr) { if (ltr) {
if ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) { if ( (ctx->len < MAX_STR_SIZE - 1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1) - 1)) ) {
add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key); add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);
if (x == x2-1) if (x == x2 - 1)
wmove(self->window, y+1, 0); wmove(self->window, y + 1, 0);
else else
wmove(self->window, y, x + MAX(1, wcwidth(key))); wmove(self->window, y, x + MAX(1, wcwidth(key)));
} }
@ -410,7 +411,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len); del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);
if (x == 0) if (x == 0)
wmove(self->window, y-1, x2 - cur_len); wmove(self->window, y - 1, x2 - cur_len);
else else
wmove(self->window, y, x - cur_len); wmove(self->window, y, x - cur_len);
} else { } else {
@ -451,7 +452,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
else if (key == KEY_END || key == T_KEY_C_E) { /* END/C-e key: move cursor to end of line */ else if (key == KEY_END || key == T_KEY_C_E) { /* END/C-e key: move cursor to end of line */
if (ctx->pos != ctx->len) { if (ctx->pos != ctx->len) {
ctx->pos = ctx->len; ctx->pos = ctx->len;
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT-1)*x2)), y2, x2); mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT - 1)*x2)), y2, x2);
} }
} }
@ -461,7 +462,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));
if (x == 0) if (x == 0)
wmove(self->window, y-1, x2 - cur_len); wmove(self->window, y - 1, x2 - cur_len);
else else
wmove(self->window, y, x - cur_len); wmove(self->window, y, x - cur_len);
} else { } else {
@ -474,8 +475,8 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos])); cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));
++ctx->pos; ++ctx->pos;
if (x == x2-1) if (x == x2 - 1)
wmove(self->window, y+1, 0); wmove(self->window, y + 1, 0);
else else
wmove(self->window, y, x + cur_len); wmove(self->window, y, x + cur_len);
} else { } else {
@ -509,9 +510,9 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (diff != -1) { if (diff != -1) {
if (x + diff > x2 - 1) { if (x + diff > x2 - 1) {
int ofst = (x + diff - 1) - (x2 - 1); int ofst = (x + diff - 1) - (x2 - 1);
wmove(self->window, y+1, ofst); wmove(self->window, y + 1, ofst);
} else { } else {
wmove(self->window, y, x+diff); wmove(self->window, y, x + diff);
} }
} else { } else {
beep(); beep();
@ -606,8 +607,8 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
wclear(ctx->sidebar); wclear(ctx->sidebar);
mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x2); mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x2);
mvwvline(ctx->sidebar, 0, 0, ACS_VLINE, y2-CHATBOX_HEIGHT); mvwvline(ctx->sidebar, 0, 0, ACS_VLINE, y2 - CHATBOX_HEIGHT);
mvwaddch(ctx->sidebar, y2-CHATBOX_HEIGHT, 0, ACS_BTEE); mvwaddch(ctx->sidebar, y2 - CHATBOX_HEIGHT, 0, ACS_BTEE);
int num_peers = groupchats[self->num].num_peers; int num_peers = groupchats[self->num].num_peers;
@ -617,20 +618,20 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
wattroff(ctx->sidebar, A_BOLD); wattroff(ctx->sidebar, A_BOLD);
mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE); mvwaddch(ctx->sidebar, 1, 0, ACS_LTEE);
mvwhline(ctx->sidebar, 1, 1, ACS_HLINE, SIDEBAR_WIDTH-1); mvwhline(ctx->sidebar, 1, 1, ACS_HLINE, SIDEBAR_WIDTH - 1);
int N = TOX_MAX_NAME_LENGTH; int N = TOX_MAX_NAME_LENGTH;
int maxlines = y2 - SDBAR_OFST - CHATBOX_HEIGHT; int maxlines = y2 - SDBAR_OFST - CHATBOX_HEIGHT;
int i; int i;
for (i = 0; i < num_peers && i < maxlines; ++i) { for (i = 0; i < num_peers && i < maxlines; ++i) {
wmove(ctx->sidebar, i+2, 1); wmove(ctx->sidebar, i + 2, 1);
int peer = i + groupchats[self->num].side_pos; int peer = i + groupchats[self->num].side_pos;
/* truncate nick to fit in side panel without modifying list */ /* truncate nick to fit in side panel without modifying list */
uint8_t tmpnck[TOX_MAX_NAME_LENGTH]; uint8_t tmpnck[TOX_MAX_NAME_LENGTH];
memcpy(tmpnck, &groupchats[self->num].peer_names[peer*N], SIDEBAR_WIDTH-2); memcpy(tmpnck, &groupchats[self->num].peer_names[peer * N], SIDEBAR_WIDTH - 2);
tmpnck[SIDEBAR_WIDTH-2] = '\0'; tmpnck[SIDEBAR_WIDTH - 2] = '\0';
wprintw(ctx->sidebar, "%s\n", tmpnck); wprintw(ctx->sidebar, "%s\n", tmpnck);
} }
@ -643,9 +644,9 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
ChatContext *ctx = self->chatwin; ChatContext *ctx = self->chatwin;
ctx->history = subwin(self->window, y-CHATBOX_HEIGHT+1, x-SIDEBAR_WIDTH-1, 0, 0); ctx->history = subwin(self->window, y - CHATBOX_HEIGHT + 1, x - SIDEBAR_WIDTH - 1, 0, 0);
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x, y-CHATBOX_HEIGHT, 0); ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x, y - CHATBOX_HEIGHT, 0);
ctx->sidebar = subwin(self->window, y-CHATBOX_HEIGHT+1, SIDEBAR_WIDTH, 0, x-SIDEBAR_WIDTH); ctx->sidebar = subwin(self->window, y - CHATBOX_HEIGHT + 1, SIDEBAR_WIDTH, 0, x - SIDEBAR_WIDTH);
ctx->hst = malloc(sizeof(struct history)); ctx->hst = malloc(sizeof(struct history));
ctx->log = malloc(sizeof(struct chatlog)); ctx->log = malloc(sizeof(struct chatlog));
@ -667,7 +668,7 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE);
wmove(self->window, y-CURS_Y_OFFSET, 0); wmove(self->window, y - CURS_Y_OFFSET, 0);
} }
ToxWindow new_group_chat(Tox *m, int groupnum) ToxWindow new_group_chat(Tox *m, int groupnum)

View File

@ -125,24 +125,31 @@ void line_info_add(ToxWindow *self, uint8_t *tmstmp, uint8_t *name1, uint8_t *na
/* for type-specific formatting in print function */ /* for type-specific formatting in print function */
switch (type) { switch (type) {
case ACTION: case ACTION:
len += 3; len += 3;
break; break;
default:
len += 2; default:
break; len += 2;
break;
} }
if (msg) { if (msg) {
memcpy(new_line->msg, msg, sizeof(new_line->msg)); memcpy(new_line->msg, msg, sizeof(new_line->msg));
len += strlen(msg); len += strlen(msg);
} if (tmstmp) { }
if (tmstmp) {
memcpy(new_line->timestamp, tmstmp, sizeof(new_line->timestamp)); memcpy(new_line->timestamp, tmstmp, sizeof(new_line->timestamp));
len += strlen(tmstmp); len += strlen(tmstmp);
} if (name1) { }
if (name1) {
memcpy(new_line->name1, name1, sizeof(new_line->name1)); memcpy(new_line->name1, name1, sizeof(new_line->name1));
len += strlen(name1); len += strlen(name1);
} if (name2) { }
if (name2) {
memcpy(new_line->name2, name2, sizeof(new_line->name2)); memcpy(new_line->name2, name2, sizeof(new_line->name2));
len += strlen(name2); len += strlen(name2);
} }
@ -223,112 +230,114 @@ void line_info_print(ToxWindow *self)
int offst = self->is_groupchat ? SIDEBAR_WIDTH : 0; int offst = self->is_groupchat ? SIDEBAR_WIDTH : 0;
int numlines = 0; int numlines = 0;
while(line && numlines++ <= y2) { while (line && numlines++ <= y2) {
uint8_t type = line->type; uint8_t type = line->type;
switch (type) { switch (type) {
case OUT_MSG: case OUT_MSG:
case IN_MSG: case IN_MSG:
wattron(win, COLOR_PAIR(BLUE)); wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s", line->timestamp); wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(BLUE)); wattroff(win, COLOR_PAIR(BLUE));
int nameclr = GREEN; int nameclr = GREEN;
if (line->colour) if (line->colour)
nameclr = line->colour; nameclr = line->colour;
else if (type == IN_MSG) else if (type == IN_MSG)
nameclr = CYAN; nameclr = CYAN;
wattron(win, COLOR_PAIR(nameclr)); wattron(win, COLOR_PAIR(nameclr));
wprintw(win, "%s: ", line->name1); wprintw(win, "%s: ", line->name1);
wattroff(win, COLOR_PAIR(nameclr)); wattroff(win, COLOR_PAIR(nameclr));
if (line->msg[0] == '>') if (line->msg[0] == '>')
wattron(win, COLOR_PAIR(GREEN)); wattron(win, COLOR_PAIR(GREEN));
wprintw(win, "%s\n", line->msg); wprintw(win, "%s\n", line->msg);
if (line->msg[0] == '>') if (line->msg[0] == '>')
wattroff(win, COLOR_PAIR(GREEN)); wattroff(win, COLOR_PAIR(GREEN));
break; break;
case ACTION: case ACTION:
wattron(win, COLOR_PAIR(BLUE)); wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s", line->timestamp); wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(BLUE)); wattroff(win, COLOR_PAIR(BLUE));
wattron(win, COLOR_PAIR(YELLOW)); wattron(win, COLOR_PAIR(YELLOW));
wprintw(win, "* %s %s\n", line->name1, line->msg); wprintw(win, "* %s %s\n", line->name1, line->msg);
wattroff(win, COLOR_PAIR(YELLOW)); wattroff(win, COLOR_PAIR(YELLOW));
break; break;
case SYS_MSG: case SYS_MSG:
if (line->timestamp[0]) { if (line->timestamp[0]) {
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(BLUE));
}
if (line->bold)
wattron(win, A_BOLD);
if (line->colour)
wattron(win, COLOR_PAIR(line->colour));
wprintw(win, "%s\n", line->msg);
if (line->bold)
wattroff(win, A_BOLD);
if (line->colour)
wattroff(win, COLOR_PAIR(line->colour));
break;
case PROMPT:
wattron(win, COLOR_PAIR(GREEN));
wprintw(win, "$ ");
wattroff(win, COLOR_PAIR(GREEN));
if (line->msg[0])
wprintw(win, "%s", line->msg);
wprintw(win, "\n");
break;
case CONNECTION:
wattron(win, COLOR_PAIR(BLUE)); wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s", line->timestamp); wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(BLUE)); wattroff(win, COLOR_PAIR(BLUE));
}
if (line->bold)
wattron(win, A_BOLD);
if (line->colour)
wattron(win, COLOR_PAIR(line->colour)); wattron(win, COLOR_PAIR(line->colour));
wattron(win, A_BOLD);
wprintw(win, "%s\n", line->msg); wprintw(win, "* %s ", line->name1);
if (line->bold)
wattroff(win, A_BOLD); wattroff(win, A_BOLD);
if (line->colour) wprintw(win, "%s\n", line->msg);
wattroff(win, COLOR_PAIR(line->colour)); wattroff(win, COLOR_PAIR(line->colour));
break; break;
case PROMPT: case NAME_CHANGE:
wattron(win, COLOR_PAIR(GREEN)); wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "$ "); wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(GREEN)); wattroff(win, COLOR_PAIR(BLUE));
wattron(win, COLOR_PAIR(MAGENTA));
wattron(win, A_BOLD);
wprintw(win, "* %s", line->name1);
wattroff(win, A_BOLD);
if (line->msg[0])
wprintw(win, "%s", line->msg); wprintw(win, "%s", line->msg);
wprintw(win, "\n"); wattron(win, A_BOLD);
break; wprintw(win, "%s\n", line->name2);
wattroff(win, A_BOLD);
wattroff(win, COLOR_PAIR(MAGENTA));
case CONNECTION: break;
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(BLUE));
wattron(win, COLOR_PAIR(line->colour));
wattron(win, A_BOLD);
wprintw(win, "* %s ", line->name1);
wattroff(win, A_BOLD);
wprintw(win, "%s\n", line->msg);
wattroff(win, COLOR_PAIR(line->colour));
break;
case NAME_CHANGE:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(BLUE));
wattron(win, COLOR_PAIR(MAGENTA));
wattron(win, A_BOLD);
wprintw(win, "* %s", line->name1);
wattroff(win, A_BOLD);
wprintw(win, "%s", line->msg);
wattron(win, A_BOLD);
wprintw(win, "%s\n", line->name2);
wattroff(win, A_BOLD);
wattroff(win, COLOR_PAIR(MAGENTA));
break;
} }
line = line->next; line = line->next;
@ -395,24 +404,29 @@ void line_info_onKey(ToxWindow *self, wint_t key)
struct history *hst = self->chatwin->hst; struct history *hst = self->chatwin->hst;
switch (key) { switch (key) {
case KEY_PPAGE: case KEY_PPAGE:
line_info_page_up(self, hst); line_info_page_up(self, hst);
break; break;
case KEY_NPAGE:
line_info_page_down(self, hst); case KEY_NPAGE:
break; line_info_page_down(self, hst);
case KEY_UP: break;
line_info_scroll_up(hst);
break; case KEY_UP:
case KEY_DOWN: line_info_scroll_up(hst);
line_info_scroll_down(hst); break;
break;
case KEY_HOME: case KEY_DOWN:
line_info_goto_root(hst); line_info_scroll_down(hst);
break; break;
case KEY_END:
line_info_reset_start(hst); case KEY_HOME:
break; line_info_goto_root(hst);
break;
case KEY_END:
line_info_reset_start(hst);
break;
} }
} }
@ -424,7 +438,7 @@ void line_info_onDraw(ToxWindow *self)
mvwprintw(ctx->linewin, 1, 0, "Scroll mode:\n"); mvwprintw(ctx->linewin, 1, 0, "Scroll mode:\n");
wattroff(ctx->linewin, A_BOLD | COLOR_PAIR(BLUE)); wattroff(ctx->linewin, A_BOLD | COLOR_PAIR(BLUE));
mvwprintw(ctx->linewin, 1, 13, "Use up/down arrows, page up/page down, and home/end to navigate.\n" mvwprintw(ctx->linewin, 1, 13, "Use up/down arrows, page up/page down, and home/end to navigate.\n"
" ESC to exit.\n"); " ESC to exit.\n");
} }
void line_info_clear(struct history *hst) void line_info_clear(struct history *hst)

View File

@ -56,7 +56,7 @@ void init_logging_session(uint8_t *name, uint8_t *key, struct chatlog *log)
sprintf(&ident[0], "%02X", key[0] & 0xff); sprintf(&ident[0], "%02X", key[0] & 0xff);
sprintf(&ident[2], "%02X", key[1] & 0xff); sprintf(&ident[2], "%02X", key[1] & 0xff);
ident[KEY_IDENT_DIGITS*2+1] = '\0'; ident[KEY_IDENT_DIGITS * 2 + 1] = '\0';
} else { } else {
strftime(ident, sizeof(ident), "%Y-%m-%d[%H:%M:%S]", get_time()); strftime(ident, sizeof(ident), "%Y-%m-%d[%H:%M:%S]", get_time());
path_len += strlen(ident) + 1; path_len += strlen(ident) + 1;
@ -105,7 +105,7 @@ void write_to_log(const uint8_t *msg, uint8_t *name, struct chatlog *log, bool e
const char *t = user_settings->time == TIME_12 ? "%Y/%m/%d [%I:%M:%S %p]" : "%Y/%m/%d [%H:%M:%S]"; const char *t = user_settings->time == TIME_12 ? "%Y/%m/%d [%I:%M:%S %p]" : "%Y/%m/%d [%H:%M:%S]";
uint8_t s[MAX_STR_SIZE]; uint8_t s[MAX_STR_SIZE];
strftime(s, MAX_STR_SIZE, t, get_time()); strftime(s, MAX_STR_SIZE, t, get_time());
fprintf(log->file,"%s %s %s\n", s, name_frmt, msg); fprintf(log->file, "%s %s %s\n", s, name_frmt, msg);
uint64_t curtime = get_unix_time(); uint64_t curtime = get_unix_time();

View File

@ -25,7 +25,7 @@
#endif #endif
#ifndef SIGWINCH #ifndef SIGWINCH
#define SIGWINCH 28 #define SIGWINCH 28
#endif #endif
#include <curses.h> #include <curses.h>
@ -41,9 +41,9 @@
#include <pthread.h> #include <pthread.h>
#ifdef _WIN32 #ifdef _WIN32
#include <direct.h> #include <direct.h>
#include <winsock2.h> #include <winsock2.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#else #else
#include <netdb.h> #include <netdb.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -64,7 +64,7 @@
#include "settings.h" #include "settings.h"
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#include "audio_call.h" #include "audio_call.h"
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
#ifndef PACKAGE_DATADIR #ifndef PACKAGE_DATADIR
@ -72,7 +72,7 @@
#endif #endif
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
ToxAv* av; ToxAv *av;
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
/* Export for use in Callbacks */ /* Export for use in Callbacks */
@ -95,11 +95,13 @@ static void init_term(void)
/* Setup terminal */ /* Setup terminal */
signal(SIGWINCH, on_window_resize); signal(SIGWINCH, on_window_resize);
#if HAVE_WIDECHAR #if HAVE_WIDECHAR
if (setlocale(LC_ALL, "") == NULL) { if (setlocale(LC_ALL, "") == NULL) {
fprintf(stderr, "Could not set your locale, plese check your locale settings or" fprintf(stderr, "Could not set your locale, plese check your locale settings or"
"disable wide char support\n"); "disable wide char support\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#endif #endif
initscr(); initscr();
cbreak(); cbreak();
@ -112,7 +114,7 @@ static void init_term(void)
start_color(); start_color();
if (user_settings->colour_theme == NATIVE_COLS) { if (user_settings->colour_theme == NATIVE_COLS) {
if (assume_default_colors(-1,-1) == OK) if (assume_default_colors(-1, -1) == OK)
bg_color = -1; bg_color = -1;
} }
@ -199,11 +201,13 @@ static int nodelist_load(char *filename)
return 1; return 1;
char line[MAXLINE]; char line[MAXLINE];
while (fgets(line, sizeof(line), fp) && linecnt < MAXNODES) { while (fgets(line, sizeof(line), fp) && linecnt < MAXNODES) {
if (strlen(line) > MINLINE) { if (strlen(line) > MINLINE) {
char *name = strtok(line, " "); char *name = strtok(line, " ");
char *port = strtok(NULL, " "); char *port = strtok(NULL, " ");
char *key_ascii = strtok(NULL, " "); char *key_ascii = strtok(NULL, " ");
/* invalid line */ /* invalid line */
if (name == NULL || port == NULL || key_ascii == NULL) if (name == NULL || port == NULL || key_ascii == NULL)
continue; continue;
@ -232,7 +236,7 @@ static int nodelist_load(char *filename)
int init_connection_helper(Tox *m, int line) int init_connection_helper(Tox *m, int line)
{ {
return tox_bootstrap_from_address(m, nodes[line], TOX_ENABLE_IPV6_DEFAULT, return tox_bootstrap_from_address(m, nodes[line], TOX_ENABLE_IPV6_DEFAULT,
ports[line], keys[line]); ports[line], keys[line]);
} }
/* Connects to a random DHT node listed in the DHTnodes file /* Connects to a random DHT node listed in the DHTnodes file
@ -267,7 +271,7 @@ int init_connection(Tox *m)
int i; int i;
int n = MIN(NUM_INIT_NODES, linecnt); int n = MIN(NUM_INIT_NODES, linecnt);
for(i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
if (init_connection_helper(m, rand() % linecnt)) if (init_connection_helper(m, rand() % linecnt))
res = 0; res = 0;
} }
@ -425,9 +429,9 @@ void exit_toxic(Tox *m)
free(prompt->chatwin); free(prompt->chatwin);
free(user_settings); free(user_settings);
tox_kill(m); tox_kill(m);
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
terminate_audio(); terminate_audio();
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
endwin(); endwin();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
@ -484,11 +488,13 @@ int main(int argc, char *argv[])
} }
config_err = create_user_config_dir(user_config_dir); config_err = create_user_config_dir(user_config_dir);
if (DATA_FILE == NULL ) { if (DATA_FILE == NULL ) {
if (config_err) { if (config_err) {
DATA_FILE = strdup("data"); DATA_FILE = strdup("data");
} else { } else {
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1); DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1);
if (DATA_FILE != NULL) { if (DATA_FILE != NULL) {
strcpy(DATA_FILE, user_config_dir); strcpy(DATA_FILE, user_config_dir);
strcat(DATA_FILE, CONFIGDIR); strcat(DATA_FILE, CONFIGDIR);

View File

@ -98,7 +98,7 @@ int mbs_to_wcs_buf(wchar_t *buf, const uint8_t *string, size_t n)
if (n < len) if (n < len)
return -1; return -1;
if ((len = mbstowcs(buf, string, n)) == (size_t) -1) if ((len = mbstowcs(buf, string, n)) == (size_t) - 1)
return -1; return -1;
return len; return len;
@ -113,7 +113,7 @@ int wcs_to_mbs_buf(uint8_t *buf, const wchar_t *string, size_t n)
if (n < len) if (n < len)
return -1; return -1;
if ((len = wcstombs(buf, string, n)) == (size_t) -1) if ((len = wcstombs(buf, string, n)) == (size_t) - 1)
return -1; return -1;
return len; return len;
@ -125,11 +125,11 @@ uint8_t *wcs_to_mbs(wchar_t *string)
uint8_t *ret = NULL; uint8_t *ret = NULL;
size_t len = wcstombs(NULL, string, 0); size_t len = wcstombs(NULL, string, 0);
if (len != (size_t) -1) { if (len != (size_t) - 1) {
ret = malloc(++len); ret = malloc(++len);
if (ret != NULL) { if (ret != NULL) {
if (wcstombs(ret, string, len) == (size_t) -1) if (wcstombs(ret, string, len) == (size_t) - 1)
return NULL; return NULL;
} }
} else { } else {
@ -176,15 +176,17 @@ int timed_out(uint64_t timestamp, uint64_t curtime, uint64_t timeout)
void alert_window(ToxWindow *self, int type, bool is_beep) void alert_window(ToxWindow *self, int type, bool is_beep)
{ {
switch (type) { switch (type) {
case WINDOW_ALERT_0: case WINDOW_ALERT_0:
self->alert0 = true; self->alert0 = true;
break; break;
case WINDOW_ALERT_1:
self->alert1 = true; case WINDOW_ALERT_1:
break; self->alert1 = true;
case WINDOW_ALERT_2: break;
self->alert2 = true;
break; case WINDOW_ALERT_2:
self->alert2 = true;
break;
} }
StatusBar *stb = prompt->stb; StatusBar *stb = prompt->stb;
@ -212,8 +214,9 @@ int valid_nick(uint8_t *nick)
int i; int i;
for (i = 0; nick[i]; ++i) { for (i = 0; nick[i]; ++i) {
if (nick[i] == ' ' && nick[i+1] == ' ') if (nick[i] == ' ' && nick[i + 1] == ' ')
return 0; return 0;
if (nick[i] == '/') if (nick[i] == '/')
return 0; return 0;
} }
@ -235,7 +238,7 @@ void get_file_name(uint8_t *pathname, uint8_t *namebuf)
int idx = strlen(pathname) - 1; int idx = strlen(pathname) - 1;
while (idx >= 0 && pathname[idx] == '/') while (idx >= 0 && pathname[idx] == '/')
pathname[idx--] = '\0'; pathname[idx--] = '\0';
uint8_t *filename = strrchr(pathname, '/'); /* Try unix style paths */ uint8_t *filename = strrchr(pathname, '/'); /* Try unix style paths */

View File

@ -146,7 +146,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
} }
if (ltr) { if (ltr) {
if (ctx->len < (MAX_STR_SIZE-1)) { if (ctx->len < (MAX_STR_SIZE - 1)) {
add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key); add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);
} }
} else { /* if (!ltr) */ } else { /* if (!ltr) */
@ -155,7 +155,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
if (key == 0x107 || key == 0x8 || key == 0x7f) { if (key == 0x107 || key == 0x8 || key == 0x7f) {
if (ctx->pos > 0) { if (ctx->pos > 0) {
del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len); del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);
wmove(ctx->history, y, x-1); /* not necessary but fixes a display glitch */ wmove(ctx->history, y, x - 1); /* not necessary but fixes a display glitch */
} else { } else {
beep(); beep();
} }
@ -325,23 +325,27 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
const uint8_t *status_text = "Unknown"; const uint8_t *status_text = "Unknown";
switch (statusbar->status) { switch (statusbar->status) {
case TOX_USERSTATUS_NONE: case TOX_USERSTATUS_NONE:
status_text = "Online"; status_text = "Online";
colour = GREEN; colour = GREEN;
break; break;
case TOX_USERSTATUS_AWAY:
status_text = "Away"; case TOX_USERSTATUS_AWAY:
colour = YELLOW; status_text = "Away";
break; colour = YELLOW;
case TOX_USERSTATUS_BUSY: break;
status_text = "Busy";
colour = RED; case TOX_USERSTATUS_BUSY:
break; status_text = "Busy";
case TOX_USERSTATUS_INVALID: colour = RED;
status_text = "ERROR"; break;
colour = MAGENTA;
break; case TOX_USERSTATUS_INVALID:
status_text = "ERROR";
colour = MAGENTA;
break;
} }
wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
wprintw(statusbar->topline, " [%s]", status_text); wprintw(statusbar->topline, " [%s]", status_text);
wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD); wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
@ -374,7 +378,7 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum
uint8_t nick[TOX_MAX_NAME_LENGTH] = {0}; uint8_t nick[TOX_MAX_NAME_LENGTH] = {0};
int n_len = tox_get_name(m, friendnum, nick); int n_len = tox_get_name(m, friendnum, nick);
n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH-1); n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1);
if (!nick[0]) { if (!nick[0]) {
snprintf(nick, sizeof(nick), "%s", UNKNOWN_NAME); snprintf(nick, sizeof(nick), "%s", UNKNOWN_NAME);
@ -500,7 +504,7 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
} }
execute(ctx->history, self, m, "/help", GLOBAL_COMMAND_MODE); execute(ctx->history, self, m, "/help", GLOBAL_COMMAND_MODE);
wmove(ctx->history, y2-1, 2); wmove(ctx->history, y2 - 1, 2);
} }
ToxWindow new_prompt(void) ToxWindow new_prompt(void)

View File

@ -27,9 +27,9 @@
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#define AC_NUM_GLOB_COMMANDS 17 #define AC_NUM_GLOB_COMMANDS 17
#else #else
#define AC_NUM_GLOB_COMMANDS 15 #define AC_NUM_GLOB_COMMANDS 15
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
ToxWindow new_prompt(void); ToxWindow new_prompt(void);

View File

@ -41,7 +41,7 @@ void add_char_to_buf(wchar_t *buf, size_t *pos, size_t *len, wint_t ch)
int i; int i;
for (i = *len; i >= *pos && i >= 0; --i) for (i = *len; i >= *pos && i >= 0; --i)
buf[i+1] = buf[i]; buf[i + 1] = buf[i];
buf[(*pos)++] = ch; buf[(*pos)++] = ch;
++(*len); ++(*len);
@ -56,8 +56,8 @@ void del_char_buf_bck(wchar_t *buf, size_t *pos, size_t *len)
int i; int i;
/* similar to add_char_to_buf but deletes a char */ /* similar to add_char_to_buf but deletes a char */
for (i = *pos-1; i <= *len; ++i) for (i = *pos - 1; i <= *len; ++i)
buf[i] = buf[i+1]; buf[i] = buf[i + 1];
--(*pos); --(*pos);
--(*len); --(*len);
@ -72,7 +72,7 @@ void del_char_buf_frnt(wchar_t *buf, size_t *pos, size_t *len)
int i; int i;
for (i = *pos; i < *len; ++i) for (i = *pos; i < *len; ++i)
buf[i] = buf[i+1]; buf[i] = buf[i + 1];
--(*len); --(*len);
} }
@ -120,7 +120,7 @@ static void shift_hist_back(wchar_t (*hst)[MAX_STR_SIZE], int *hst_tot)
int n = MAX_LINE_HIST - HIST_PURGE; int n = MAX_LINE_HIST - HIST_PURGE;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
wmemcpy(hst[i], hst[i+HIST_PURGE], MAX_STR_SIZE); wmemcpy(hst[i], hst[i + HIST_PURGE], MAX_STR_SIZE);
*hst_tot = n; *hst_tot = n;
} }
@ -138,7 +138,7 @@ void add_line_to_hist(const wchar_t *buf, size_t len, wchar_t (*hst)[MAX_STR_SIZ
++(*hst_tot); ++(*hst_tot);
*hst_pos = *hst_tot; *hst_pos = *hst_tot;
wmemcpy(hst[*hst_tot-1], buf, len + 1); wmemcpy(hst[*hst_tot - 1], buf, len + 1);
} }
/* copies history item at hst_pos to buf. Sets pos and len to the len of the history item. /* copies history item at hst_pos to buf. Sets pos and len to the len of the history item.
@ -186,6 +186,7 @@ int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int
const uint8_t *L = (uint8_t *) list; const uint8_t *L = (uint8_t *) list;
uint8_t ubuf[MAX_STR_SIZE]; uint8_t ubuf[MAX_STR_SIZE];
/* work with multibyte string copy of buf for simplicity */ /* work with multibyte string copy of buf for simplicity */
if (wcs_to_mbs_buf(ubuf, buf, MAX_STR_SIZE) == -1) if (wcs_to_mbs_buf(ubuf, buf, MAX_STR_SIZE) == -1)
return -1; return -1;
@ -199,6 +200,7 @@ int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int
if (!sub++) { if (!sub++) {
sub = tmp; sub = tmp;
if (sub[0] != '/') /* make sure it's not a command */ if (sub[0] != '/') /* make sure it's not a command */
n_endchrs = 2; n_endchrs = 2;
} }
@ -213,7 +215,8 @@ int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int
/* look for a match in list */ /* look for a match in list */
for (i = 0; i < n_items; ++i) { for (i = 0; i < n_items; ++i) {
match = &L[i*size]; match = &L[i * size];
if (is_match = strncasecmp(match, sub, s_len) == 0) if (is_match = strncasecmp(match, sub, s_len) == 0)
break; break;
} }
@ -224,7 +227,7 @@ int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int
/* put match in correct spot in buf and append endchars (space or ": ") */ /* put match in correct spot in buf and append endchars (space or ": ") */
const uint8_t *endchrs = n_endchrs == 1 ? " " : ": "; const uint8_t *endchrs = n_endchrs == 1 ? " " : ": ";
int m_len = strlen(match); int m_len = strlen(match);
int strt = (int) *pos - s_len; int strt = (int) * pos - s_len;
int diff = m_len - s_len + n_endchrs; int diff = m_len - s_len + n_endchrs;
if (*len + diff > MAX_STR_SIZE) if (*len + diff > MAX_STR_SIZE)
@ -233,8 +236,8 @@ int complete_line(wchar_t *buf, size_t *pos, size_t *len, const void *list, int
uint8_t tmpend[MAX_STR_SIZE]; uint8_t tmpend[MAX_STR_SIZE];
strcpy(tmpend, &ubuf[*pos]); strcpy(tmpend, &ubuf[*pos]);
strcpy(&ubuf[strt], match); strcpy(&ubuf[strt], match);
strcpy(&ubuf[strt+m_len], endchrs); strcpy(&ubuf[strt + m_len], endchrs);
strcpy(&ubuf[strt+m_len+n_endchrs], tmpend); strcpy(&ubuf[strt + m_len + n_endchrs], tmpend);
/* convert to widechar and copy back to original buf */ /* convert to widechar and copy back to original buf */
wchar_t newbuf[MAX_STR_SIZE]; wchar_t newbuf[MAX_STR_SIZE];

View File

@ -35,7 +35,7 @@
#include <tox/tox.h> #include <tox/tox.h>
#ifdef _SUPPORT_AUDIO #ifdef _SUPPORT_AUDIO
#include <tox/toxav.h> #include <tox/toxav.h>
#endif /* _SUPPORT_AUDIO */ #endif /* _SUPPORT_AUDIO */
#define UNKNOWN_NAME "Anonymous" #define UNKNOWN_NAME "Anonymous"
@ -112,7 +112,7 @@ struct ToxWindow {
void(*onGroupMessage)(ToxWindow *, Tox *, int, int, uint8_t *, uint16_t); void(*onGroupMessage)(ToxWindow *, Tox *, int, int, uint8_t *, uint16_t);
void(*onGroupAction)(ToxWindow *, Tox *, int, int, uint8_t *, uint16_t); void(*onGroupAction)(ToxWindow *, Tox *, int, int, uint8_t *, uint16_t);
void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, uint8_t *); void(*onGroupInvite)(ToxWindow *, Tox *, int32_t, uint8_t *);
void(*onGroupNamelistChange)(ToxWindow *, Tox*, int, int, uint8_t); void(*onGroupNamelistChange)(ToxWindow *, Tox *, int, int, uint8_t);
void(*onFileSendRequest)(ToxWindow *, Tox *, int32_t, uint8_t, uint64_t, uint8_t *, uint16_t); void(*onFileSendRequest)(ToxWindow *, Tox *, int32_t, uint8_t, uint64_t, uint8_t *, uint16_t);
void(*onFileControl)(ToxWindow *, Tox *, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, uint16_t); void(*onFileControl)(ToxWindow *, Tox *, int32_t, uint8_t, uint8_t, uint8_t, uint8_t *, uint16_t);
void(*onFileData)(ToxWindow *, Tox *, int32_t, uint8_t, uint8_t *, uint16_t); void(*onFileData)(ToxWindow *, Tox *, int32_t, uint8_t, uint8_t *, uint16_t);
@ -239,8 +239,10 @@ void on_groupmessage(Tox *m, int groupnumber, int peernumber, uint8_t *message,
void on_groupaction(Tox *m, int groupnumber, int peernumber, uint8_t *action, uint16_t length, void *userdata); void on_groupaction(Tox *m, int groupnumber, int peernumber, uint8_t *action, uint16_t length, void *userdata);
void on_groupinvite(Tox *m, int32_t friendnumber, uint8_t *group_pub_key, void *userdata); void on_groupinvite(Tox *m, int32_t friendnumber, uint8_t *group_pub_key, void *userdata);
void on_group_namelistchange(Tox *m, int groupnumber, int peernumber, uint8_t change, void *userdata); void on_group_namelistchange(Tox *m, int groupnumber, int peernumber, uint8_t change, void *userdata);
void on_file_sendrequest(Tox *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *pathname, uint16_t pathname_length, void *userdata); void on_file_sendrequest(Tox *m, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *pathname,
void on_file_control(Tox *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata); uint16_t pathname_length, void *userdata);
void on_file_control(Tox *m, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, uint8_t control_type,
uint8_t *data, uint16_t length, void *userdata);
void on_file_data(Tox *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata); void on_file_data(Tox *m, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata);
void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *userdata); void on_typing_change(Tox *m, int32_t friendnumber, uint8_t is_typing, void *userdata);

View File

@ -236,6 +236,7 @@ int add_window(Tox *m, ToxWindow w)
if (w.window == NULL) if (w.window == NULL)
return -1; return -1;
#ifdef URXVT_FIX #ifdef URXVT_FIX
/* Fixes text color problem on some terminals. */ /* Fixes text color problem on some terminals. */
wbkgd(w.window, COLOR_PAIR(6)); wbkgd(w.window, COLOR_PAIR(6));
@ -405,6 +406,7 @@ void draw_active_window(Tox *m)
ltr = iswprint(ch); ltr = iswprint(ch);
else /* if (status == KEY_CODE_YES) */ else /* if (status == KEY_CODE_YES) */
ltr = false; ltr = false;
#else #else
ch = getch(); ch = getch();