mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-22 21:03:02 +01:00
Merge with upstream master
This commit is contained in:
commit
fbd22003a8
@ -16,6 +16,7 @@
|
|||||||
| [LibConfig](http://www.hyperrealm.com/libconfig) | BASE | libconfig-dev |
|
| [LibConfig](http://www.hyperrealm.com/libconfig) | BASE | libconfig-dev |
|
||||||
| [GNUmake](https://www.gnu.org/software/make) | BASE | make |
|
| [GNUmake](https://www.gnu.org/software/make) | BASE | make |
|
||||||
| [libcurl](http://curl.haxx.se/) | BASE | libcurl4-openssl-dev|
|
| [libcurl](http://curl.haxx.se/) | BASE | libcurl4-openssl-dev|
|
||||||
|
| [libqrencode](https://fukuchi.org/works/qrencode/) | BASE | libqrencode-dev |
|
||||||
| [Tox Core AV](https://github.com/irungentoo/toxcore) | AUDIO | *None* |
|
| [Tox Core AV](https://github.com/irungentoo/toxcore) | AUDIO | *None* |
|
||||||
| [OpenAL](http://openal.org) | AUDIO, SOUND NOTIFICATIONS | libopenal-dev |
|
| [OpenAL](http://openal.org) | AUDIO, SOUND NOTIFICATIONS | libopenal-dev |
|
||||||
| [OpenALUT](http://openal.org) | SOUND NOTIFICATIONS | libalut-dev |
|
| [OpenALUT](http://openal.org) | SOUND NOTIFICATIONS | libalut-dev |
|
||||||
|
9
Makefile
9
Makefile
@ -3,9 +3,9 @@ CFG_DIR = $(BASE_DIR)/cfg
|
|||||||
|
|
||||||
-include $(CFG_DIR)/global_vars.mk
|
-include $(CFG_DIR)/global_vars.mk
|
||||||
|
|
||||||
LIBS = libtoxcore ncursesw libconfig
|
LIBS = libtoxcore ncursesw libconfig libqrencode
|
||||||
|
|
||||||
CFLAGS = -std=gnu99 -pthread -Wall -g
|
CFLAGS = -std=gnu99 -pthread -Wall -g -fstack-protector-all
|
||||||
CFLAGS += '-DTOXICVER="$(VERSION)"' -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED -D_FILE_OFFSET_BITS=64
|
CFLAGS += '-DTOXICVER="$(VERSION)"' -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED -D_FILE_OFFSET_BITS=64
|
||||||
CFLAGS += '-DPACKAGE_DATADIR="$(abspath $(DATADIR))"'
|
CFLAGS += '-DPACKAGE_DATADIR="$(abspath $(DATADIR))"'
|
||||||
CFLAGS += $(USER_CFLAGS)
|
CFLAGS += $(USER_CFLAGS)
|
||||||
@ -14,7 +14,7 @@ LDFLAGS = $(USER_LDFLAGS)
|
|||||||
OBJ = chat.o chat_commands.o configdir.o execute.o file_transfers.o notify.o
|
OBJ = chat.o chat_commands.o configdir.o execute.o file_transfers.o notify.o
|
||||||
OBJ += friendlist.o global_commands.o groupchat.o line_info.o input.o help.o autocomplete.o
|
OBJ += friendlist.o global_commands.o groupchat.o line_info.o input.o help.o autocomplete.o
|
||||||
OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o message_queue.o
|
OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o message_queue.o
|
||||||
OBJ += group_commands.o term_mplex.o avatars.o name_lookup.o
|
OBJ += group_commands.o term_mplex.o avatars.o name_lookup.o qr_code.o
|
||||||
|
|
||||||
# Check on wich system we are running
|
# Check on wich system we are running
|
||||||
UNAME_S = $(shell uname -s)
|
UNAME_S = $(shell uname -s)
|
||||||
@ -24,6 +24,9 @@ endif
|
|||||||
ifeq ($(UNAME_S), FreeBSD)
|
ifeq ($(UNAME_S), FreeBSD)
|
||||||
-include $(CFG_DIR)/systems/FreeBSD.mk
|
-include $(CFG_DIR)/systems/FreeBSD.mk
|
||||||
endif
|
endif
|
||||||
|
ifeq ($(UNAME_S), DragonFly)
|
||||||
|
-include $(CFG_DIR)/systems/FreeBSD.mk
|
||||||
|
endif
|
||||||
ifeq ($(UNAME_S), OpenBSD)
|
ifeq ($(UNAME_S), OpenBSD)
|
||||||
-include $(CFG_DIR)/systems/FreeBSD.mk
|
-include $(CFG_DIR)/systems/FreeBSD.mk
|
||||||
endif
|
endif
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
<a href="https://scan.coverity.com/projects/toxic-tox">
|
||||||
|
<img alt="Coverity Scan Build Status"
|
||||||
|
src="https://scan.coverity.com/projects/4975/badge.svg"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
Toxic is a [Tox](https://tox.im)-based instant messenging client which formerly resided in the [Tox core repository](https://github.com/irungentoo/toxcore), and is now available as a standalone application.
|
Toxic is a [Tox](https://tox.im)-based instant messenging client which formerly resided in the [Tox core repository](https://github.com/irungentoo/toxcore), and is now available as a standalone application.
|
||||||
|
|
||||||
[![Toxic Screenshot](https://i.imgur.com/san99Z2.png "Home Screen")](https://i.imgur.com/san99Z2.png)
|
[![Toxic Screenshot](https://i.imgur.com/san99Z2.png "Home Screen")](https://i.imgur.com/san99Z2.png)
|
||||||
|
@ -170,7 +170,8 @@ void read_device_callback(const int16_t* captured, uint32_t size, void* data)
|
|||||||
{
|
{
|
||||||
TOXAV_ERR_SEND_FRAME error;
|
TOXAV_ERR_SEND_FRAME error;
|
||||||
uint32_t friend_number = *((uint32_t *)data); /* TODO: Or pass an array of call_idx's */
|
uint32_t friend_number = *((uint32_t *)data); /* TODO: Or pass an array of call_idx's */
|
||||||
int64_t sample_count = CallControl.audio_sample_rate * CallControl.audio_frame_duration / 1000;
|
int64_t sample_count = ((int64_t) CallControl.audio_sample_rate) * \
|
||||||
|
((int64_t) CallControl.audio_frame_duration) / 1000;
|
||||||
|
|
||||||
if ( sample_count <= 0 || toxav_audio_send_frame(CallControl.av, friend_number,
|
if ( sample_count <= 0 || toxav_audio_send_frame(CallControl.av, friend_number,
|
||||||
captured, sample_count,
|
captured, sample_count,
|
||||||
|
@ -114,7 +114,7 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
tmp[ctx->pos] = '\0';
|
tmp[ctx->pos] = '\0';
|
||||||
|
|
||||||
const char *s = dir_search ? strchr(tmp, '\"') : strrchr(tmp, ' ');
|
const char *s = dir_search ? strchr(tmp, '\"') : strrchr(tmp, ' ');
|
||||||
char *sub = malloc(strlen(ubuf) + 1);
|
char *sub = calloc(1, strlen(ubuf) + 1);
|
||||||
|
|
||||||
if (sub == NULL)
|
if (sub == NULL)
|
||||||
exit_toxic_err("failed in complete_line", FATALERR_MEMORY);
|
exit_toxic_err("failed in complete_line", FATALERR_MEMORY);
|
||||||
@ -142,14 +142,14 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int s_len = strlen(sub);
|
int s_len = strlen(sub);
|
||||||
const char *str;
|
|
||||||
int n_matches = 0;
|
int n_matches = 0;
|
||||||
char matches[n_items][MAX_STR_SIZE];
|
char matches[n_items][MAX_STR_SIZE];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* put all list matches in matches array */
|
/* put all list matches in matches array */
|
||||||
for (i = 0; i < n_items; ++i) {
|
for (i = 0; i < n_items; ++i) {
|
||||||
str = &L[i * size];
|
char str[MAX_CMDNAME_SIZE + 1];
|
||||||
|
snprintf(str, sizeof(str), "%s", &L[i * size]);
|
||||||
|
|
||||||
if (strncasecmp(str, sub, s_len) == 0)
|
if (strncasecmp(str, sub, s_len) == 0)
|
||||||
strcpy(matches[n_matches++], str);
|
strcpy(matches[n_matches++], str);
|
||||||
@ -165,10 +165,11 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
|
|
||||||
char match[MAX_STR_SIZE];
|
char match[MAX_STR_SIZE];
|
||||||
get_str_match(self, match, matches, n_matches);
|
get_str_match(self, match, matches, n_matches);
|
||||||
|
size_t match_len = strlen(match);
|
||||||
|
|
||||||
if (dir_search) {
|
if (dir_search) {
|
||||||
if (n_matches == 1)
|
if (n_matches == 1)
|
||||||
endchrs = char_rfind(match, '.', strlen(match)) ? "\"" : "/";
|
endchrs = char_rfind(match, '.', match_len) ? "\"" : "/";
|
||||||
else
|
else
|
||||||
endchrs = "";
|
endchrs = "";
|
||||||
} else if (n_matches > 1) {
|
} else if (n_matches > 1) {
|
||||||
@ -177,18 +178,21 @@ int complete_line(ToxWindow *self, const void *list, int n_items, int size)
|
|||||||
|
|
||||||
/* put match in correct spot in buf and append endchars */
|
/* put match in correct spot in buf and append endchars */
|
||||||
int n_endchrs = strlen(endchrs);
|
int n_endchrs = strlen(endchrs);
|
||||||
int m_len = strlen(match);
|
|
||||||
int strt = ctx->pos - s_len;
|
int strt = ctx->pos - s_len;
|
||||||
int diff = m_len - s_len + n_endchrs;
|
int diff = match_len - s_len + n_endchrs;
|
||||||
|
|
||||||
if (ctx->len + diff >= MAX_STR_SIZE)
|
if (ctx->len + diff >= MAX_STR_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char tmpend[MAX_STR_SIZE];
|
char tmpend[MAX_STR_SIZE];
|
||||||
snprintf(tmpend, sizeof(tmpend), "%s", &ubuf[ctx->pos]);
|
snprintf(tmpend, sizeof(tmpend), "%s", &ubuf[ctx->pos]);
|
||||||
|
|
||||||
|
if (match_len + n_endchrs + strlen(tmpend) >= sizeof(ubuf))
|
||||||
|
return -1;
|
||||||
|
|
||||||
strcpy(&ubuf[strt], match);
|
strcpy(&ubuf[strt], match);
|
||||||
strcpy(&ubuf[strt + m_len], endchrs);
|
strcpy(&ubuf[strt + match_len], endchrs);
|
||||||
strcpy(&ubuf[strt + m_len + n_endchrs], tmpend);
|
strcpy(&ubuf[strt + match_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];
|
||||||
|
18
src/chat.c
18
src/chat.c
@ -63,9 +63,9 @@ static void kill_infobox(ToxWindow *self);
|
|||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
#define AC_NUM_CHAT_COMMANDS 29
|
#define AC_NUM_CHAT_COMMANDS 30
|
||||||
#else
|
#else
|
||||||
#define AC_NUM_CHAT_COMMANDS 22
|
#define AC_NUM_CHAT_COMMANDS 23
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
/* Array of chat command names used for tab completion. */
|
/* Array of chat command names used for tab completion. */
|
||||||
@ -85,6 +85,7 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
|
|||||||
{ "/join" },
|
{ "/join" },
|
||||||
{ "/log" },
|
{ "/log" },
|
||||||
{ "/myid" },
|
{ "/myid" },
|
||||||
|
{ "/myqr" },
|
||||||
{ "/nick" },
|
{ "/nick" },
|
||||||
{ "/note" },
|
{ "/note" },
|
||||||
{ "/nospam" },
|
{ "/nospam" },
|
||||||
@ -789,6 +790,10 @@ static void init_infobox(ToxWindow *self)
|
|||||||
|
|
||||||
int x2, y2;
|
int x2, y2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
(void) y2;
|
(void) y2;
|
||||||
|
|
||||||
memset(&ctx->infobox, 0, sizeof(struct infobox));
|
memset(&ctx->infobox, 0, sizeof(struct infobox));
|
||||||
@ -895,7 +900,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
getyx(self->window, y, x);
|
getyx(self->window, y, x);
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
if (x2 <= 0)
|
if (y2 <= 0 || x2 <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (self->help->active) {
|
if (self->help->active) {
|
||||||
@ -993,6 +998,9 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
|||||||
int x2, y2;
|
int x2, y2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
pthread_mutex_lock(&Winthread.lock);
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
@ -1117,6 +1125,10 @@ static void chat_onInit(ToxWindow *self, Tox *m)
|
|||||||
curs_set(1);
|
curs_set(1);
|
||||||
int x2, y2;
|
int x2, y2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
exit_toxic_err("failed in chat_onInit", FATALERR_CURSES);
|
||||||
|
|
||||||
self->x = x2;
|
self->x = x2;
|
||||||
|
|
||||||
/* Init statusbar info */
|
/* Init statusbar info */
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
#include "configdir.h"
|
#include "configdir.h"
|
||||||
|
#include "misc_tools.h"
|
||||||
|
|
||||||
/* get the user's home directory */
|
/* get the user's home directory */
|
||||||
void get_home_dir(char *home, int size)
|
void get_home_dir(char *home, int size)
|
||||||
@ -69,8 +70,8 @@ char *get_user_config_dir(void)
|
|||||||
char home[NSS_BUFLEN_PASSWD] = {0};
|
char home[NSS_BUFLEN_PASSWD] = {0};
|
||||||
get_home_dir(home, sizeof(home));
|
get_home_dir(home, sizeof(home));
|
||||||
|
|
||||||
char *user_config_dir;
|
char *user_config_dir = NULL;
|
||||||
size_t len;
|
size_t len = 0;
|
||||||
|
|
||||||
# if defined(__APPLE__)
|
# if defined(__APPLE__)
|
||||||
len = strlen(home) + strlen("/Library/Application Support") + 1;
|
len = strlen(home) + strlen("/Library/Application Support") + 1;
|
||||||
@ -82,9 +83,9 @@ char *get_user_config_dir(void)
|
|||||||
snprintf(user_config_dir, len, "%s/Library/Application Support", home);
|
snprintf(user_config_dir, len, "%s/Library/Application Support", home);
|
||||||
# else /* __APPLE__ */
|
# else /* __APPLE__ */
|
||||||
|
|
||||||
const char *tmp;
|
const char *tmp = getenv("XDG_CONFIG_HOME");
|
||||||
|
|
||||||
if (!(tmp = getenv("XDG_CONFIG_HOME"))) {
|
if (tmp == NULL) {
|
||||||
len = strlen(home) + strlen("/.config") + 1;
|
len = strlen(home) + strlen("/.config") + 1;
|
||||||
user_config_dir = malloc(len);
|
user_config_dir = malloc(len);
|
||||||
|
|
||||||
@ -98,6 +99,11 @@ char *get_user_config_dir(void)
|
|||||||
|
|
||||||
# endif /* __APPLE__ */
|
# endif /* __APPLE__ */
|
||||||
|
|
||||||
|
if (!file_exists(user_config_dir)) {
|
||||||
|
free(user_config_dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return user_config_dir;
|
return user_config_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ static struct cmd_func global_commands[] = {
|
|||||||
{ "/join", cmd_join },
|
{ "/join", cmd_join },
|
||||||
{ "/log", cmd_log },
|
{ "/log", cmd_log },
|
||||||
{ "/myid", cmd_myid },
|
{ "/myid", cmd_myid },
|
||||||
|
{ "/myqr", cmd_myqr },
|
||||||
{ "/nick", cmd_nick },
|
{ "/nick", cmd_nick },
|
||||||
{ "/note", cmd_note },
|
{ "/note", cmd_note },
|
||||||
{ "/nospam", cmd_nospam },
|
{ "/nospam", cmd_nospam },
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <tox/tox.h>
|
#include <tox/tox.h>
|
||||||
|
|
||||||
@ -125,7 +124,13 @@ void kill_friendlist(void)
|
|||||||
realloc_friends(0);
|
realloc_friends(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEMP_BLOCKLIST_SAVE_NAME "toxic_blocklist.tmp"
|
/* Saves the blocklist to path. If there are no items in the blocklist the
|
||||||
|
* empty file will be removed.
|
||||||
|
*
|
||||||
|
* Returns 0 if stored successfully.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
#define TEMP_BLOCKLIST_EXT ".tmp"
|
||||||
static int save_blocklist(char *path)
|
static int save_blocklist(char *path)
|
||||||
{
|
{
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
@ -165,19 +170,23 @@ static int save_blocklist(char *path)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fp = fopen(TEMP_BLOCKLIST_SAVE_NAME, "wb");
|
char temp_path[strlen(path) + strlen(TEMP_BLOCKLIST_EXT) + 1];
|
||||||
|
snprintf(temp_path, sizeof(temp_path), "%s%s", path, TEMP_BLOCKLIST_EXT);
|
||||||
|
|
||||||
|
FILE *fp = fopen(temp_path, "wb");
|
||||||
|
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (fwrite(data, len, 1, fp) != 1) {
|
if (fwrite(data, len, 1, fp) != 1) {
|
||||||
|
fprintf(stderr, "Failed to write blocklist data.\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
if (rename(TEMP_BLOCKLIST_SAVE_NAME, path) != 0)
|
if (rename(temp_path, path) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -228,7 +237,7 @@ int load_blocklist(char *path)
|
|||||||
memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend));
|
memcpy(&tmp, data + i * sizeof(BlockedFriend), sizeof(BlockedFriend));
|
||||||
Blocked.list[i].active = true;
|
Blocked.list[i].active = true;
|
||||||
Blocked.list[i].num = i;
|
Blocked.list[i].num = i;
|
||||||
Blocked.list[i].namelength = ntohs(tmp.namelength);
|
Blocked.list[i].namelength = MIN(TOXIC_MAX_NAME_LENGTH, ntohs(tmp.namelength));
|
||||||
memcpy(Blocked.list[i].name, tmp.name, Blocked.list[i].namelength + 1);
|
memcpy(Blocked.list[i].name, tmp.name, Blocked.list[i].namelength + 1);
|
||||||
memcpy(Blocked.list[i].pub_key, tmp.pub_key, TOX_PUBLIC_KEY_SIZE);
|
memcpy(Blocked.list[i].pub_key, tmp.pub_key, TOX_PUBLIC_KEY_SIZE);
|
||||||
|
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#include "toxic.h"
|
#include "toxic.h"
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
@ -36,6 +35,7 @@
|
|||||||
#include "term_mplex.h"
|
#include "term_mplex.h"
|
||||||
#include "avatars.h"
|
#include "avatars.h"
|
||||||
#include "name_lookup.h"
|
#include "name_lookup.h"
|
||||||
|
#include "qr_code.h"
|
||||||
|
|
||||||
extern char *DATA_FILE;
|
extern char *DATA_FILE;
|
||||||
extern ToxWindow *prompt;
|
extern ToxWindow *prompt;
|
||||||
@ -493,19 +493,57 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
|
|||||||
|
|
||||||
void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
{
|
{
|
||||||
char id[TOX_ADDRESS_SIZE * 2 + 1] = {0};
|
char id_string[TOX_ADDRESS_SIZE * 2 + 1];
|
||||||
char address[TOX_ADDRESS_SIZE];
|
char bin_id[TOX_ADDRESS_SIZE];
|
||||||
tox_self_get_address(m, (uint8_t *) address);
|
tox_self_get_address(m, (uint8_t *) bin_id);
|
||||||
|
|
||||||
size_t i;
|
if (bin_id_to_string(bin_id, sizeof(bin_id), id_string, sizeof(id_string)) == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to print ID.");
|
||||||
for (i = 0; i < TOX_ADDRESS_SIZE; ++i) {
|
return;
|
||||||
char d[3];
|
|
||||||
snprintf(d, sizeof(d), "%02X", address[i] & 0xff);
|
|
||||||
strcat(id, d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", id);
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", id_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_myqr(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
{
|
||||||
|
char id_string[TOX_ADDRESS_SIZE * 2 + 1];
|
||||||
|
char bin_id[TOX_ADDRESS_SIZE];
|
||||||
|
tox_self_get_address(m, (uint8_t *) bin_id);
|
||||||
|
|
||||||
|
if (bin_id_to_string(bin_id, sizeof(bin_id), id_string, sizeof(id_string)) == -1) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char nick[TOX_MAX_NAME_LENGTH];
|
||||||
|
tox_self_get_name(m, (uint8_t *) nick);
|
||||||
|
size_t nick_len = tox_self_get_name_size(m);
|
||||||
|
nick[nick_len] = '\0';
|
||||||
|
|
||||||
|
size_t data_file_len = strlen(DATA_FILE);
|
||||||
|
char dir[data_file_len];
|
||||||
|
size_t dir_len = get_base_dir(DATA_FILE, data_file_len, dir);
|
||||||
|
|
||||||
|
char qr_path[dir_len + nick_len + strlen(QRCODE_FILENAME_EXT) + 1];
|
||||||
|
snprintf(qr_path, sizeof(qr_path), "%s%s%s", dir, nick, QRCODE_FILENAME_EXT);
|
||||||
|
|
||||||
|
FILE *output = fopen(qr_path, "wb");
|
||||||
|
|
||||||
|
if (output == NULL) {
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ID_to_QRcode(id_string, output) == -1) {
|
||||||
|
fclose(output);
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to create QR code.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "QR code has been printed to the file '%s'", qr_path);
|
||||||
|
|
||||||
|
fclose(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
@ -36,6 +36,7 @@ void cmd_groupchat(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_
|
|||||||
void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
void cmd_myqr(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_nick(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_nick(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_note(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_note(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
void cmd_nospam(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
void cmd_nospam(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
|
||||||
|
@ -70,9 +70,9 @@ extern struct user_settings *user_settings;
|
|||||||
extern struct Winthread Winthread;
|
extern struct Winthread Winthread;
|
||||||
|
|
||||||
#ifdef AUDIO
|
#ifdef AUDIO
|
||||||
#define AC_NUM_GROUP_COMMANDS 41
|
#define AC_NUM_GROUP_COMMANDS 42
|
||||||
#else
|
#else
|
||||||
#define AC_NUM_GROUP_COMMANDS 37
|
#define AC_NUM_GROUP_COMMANDS 38
|
||||||
#endif /* AUDIO */
|
#endif /* AUDIO */
|
||||||
|
|
||||||
/* groupchat command names used for tab completion. */
|
/* groupchat command names used for tab completion. */
|
||||||
@ -96,6 +96,7 @@ static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = {
|
|||||||
{ "/mod" },
|
{ "/mod" },
|
||||||
{ "/myid" },
|
{ "/myid" },
|
||||||
{ "/mykey" },
|
{ "/mykey" },
|
||||||
|
{ "/myqr" },
|
||||||
{ "/nick" },
|
{ "/nick" },
|
||||||
{ "/note" },
|
{ "/note" },
|
||||||
{ "/passwd" },
|
{ "/passwd" },
|
||||||
@ -402,6 +403,9 @@ void redraw_groupchat_win(ToxWindow *self)
|
|||||||
getmaxyx(stdscr, y2, x2);
|
getmaxyx(stdscr, y2, x2);
|
||||||
y2 -= 2;
|
y2 -= 2;
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ctx->sidebar) {
|
if (ctx->sidebar) {
|
||||||
delwin(ctx->sidebar);
|
delwin(ctx->sidebar);
|
||||||
ctx->sidebar = NULL;
|
ctx->sidebar = NULL;
|
||||||
@ -1055,7 +1059,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
getyx(self->window, y, x);
|
getyx(self->window, y, x);
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
if (x2 <= 0)
|
if (x2 <= 0 || y2 <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (self->help->active) {
|
if (self->help->active) {
|
||||||
@ -1148,6 +1152,9 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
|
|||||||
int x2, y2;
|
int x2, y2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (x2 <= 0 || y2 <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
GroupChat *chat = &groupchats[self->num];
|
GroupChat *chat = &groupchats[self->num];
|
||||||
|
|
||||||
@ -1250,6 +1257,9 @@ static void groupchat_onInit(ToxWindow *self, Tox *m)
|
|||||||
int x2, y2;
|
int x2, y2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (x2 <= 0 || y2 <= 0)
|
||||||
|
exit_toxic_err("failed in groupchat_onInit", FATALERR_CURSES);
|
||||||
|
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2 - SIDEBAR_WIDTH - 1, 0, 0);
|
||||||
|
@ -60,6 +60,9 @@ static void help_init_window(ToxWindow *self, int height, int width)
|
|||||||
int y2, x2;
|
int y2, x2;
|
||||||
getmaxyx(stdscr, y2, x2);
|
getmaxyx(stdscr, y2, x2);
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
height = MIN(height, y2);
|
height = MIN(height, y2);
|
||||||
width = MIN(width, x2);
|
width = MIN(width, x2);
|
||||||
|
|
||||||
@ -156,6 +159,7 @@ static void help_draw_global(ToxWindow *self)
|
|||||||
wprintw(win, " /nospam : Change part of your Tox ID to stop spam\n");
|
wprintw(win, " /nospam : Change part of your Tox ID to stop spam\n");
|
||||||
wprintw(win, " /log <on> or <off> : Enable/disable logging\n");
|
wprintw(win, " /log <on> or <off> : Enable/disable logging\n");
|
||||||
wprintw(win, " /myid : Print your Tox ID\n");
|
wprintw(win, " /myid : Print your Tox ID\n");
|
||||||
|
wprintw(win, " /myqr : Print your Tox ID's QR code to a file.\n");
|
||||||
wprintw(win, " /clear : Clear window history\n");
|
wprintw(win, " /clear : Clear window history\n");
|
||||||
wprintw(win, " /close : Close the current chat window\n");
|
wprintw(win, " /close : Close the current chat window\n");
|
||||||
wprintw(win, " /quit or /exit : Exit Toxic\n");
|
wprintw(win, " /quit or /exit : Exit Toxic\n");
|
||||||
@ -329,7 +333,7 @@ void help_onKey(ToxWindow *self, wint_t key)
|
|||||||
#elif AUDIO
|
#elif AUDIO
|
||||||
help_init_window(self, 18, 80);
|
help_init_window(self, 18, 80);
|
||||||
#else
|
#else
|
||||||
help_init_window(self, 9, 80);
|
help_init_window(self, 10, 80);
|
||||||
#endif
|
#endif
|
||||||
self->help->type = HELP_CHAT;
|
self->help->type = HELP_CHAT;
|
||||||
break;
|
break;
|
||||||
|
@ -167,6 +167,24 @@ int hex_string_to_bytes(char *buf, int size, const char *keystr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Converts a binary representation of a Tox ID into a string.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int bin_id_to_string(const char *bin_id, size_t bin_id_size, char *output, size_t output_size)
|
||||||
|
{
|
||||||
|
if (bin_id_size != TOX_ADDRESS_SIZE || output_size < (TOX_ADDRESS_SIZE * 2 + 1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < TOX_ADDRESS_SIZE; ++i)
|
||||||
|
snprintf(&output[i*2], output_size - (i * 2), "%02X", bin_id[i] & 0xff);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns 1 if the string is empty, 0 otherwise */
|
/* Returns 1 if the string is empty, 0 otherwise */
|
||||||
int string_is_empty(const char *string)
|
int string_is_empty(const char *string)
|
||||||
{
|
{
|
||||||
@ -281,6 +299,24 @@ size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname)
|
|||||||
return strlen(namebuf);
|
return strlen(namebuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Gets the base directory of path and puts it in dir.
|
||||||
|
* dir must have at least as much space as path_len.
|
||||||
|
*
|
||||||
|
* Returns the length of the base directory.
|
||||||
|
*/
|
||||||
|
size_t get_base_dir(const char *path, size_t path_len, char *dir)
|
||||||
|
{
|
||||||
|
size_t dir_len = char_rfind(path, '/', path_len);
|
||||||
|
|
||||||
|
if (dir_len != 0 && dir_len < path_len)
|
||||||
|
++dir_len; /* Leave trailing slash */
|
||||||
|
|
||||||
|
memcpy(dir, path, dir_len);
|
||||||
|
dir[dir_len] = '\0';
|
||||||
|
|
||||||
|
return dir_len;
|
||||||
|
}
|
||||||
|
|
||||||
/* converts str to all lowercase */
|
/* converts str to all lowercase */
|
||||||
void str_to_lower(char *str)
|
void str_to_lower(char *str)
|
||||||
{
|
{
|
||||||
@ -363,8 +399,8 @@ int char_find(int idx, const char *s, char ch)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns index of the last instance of ch in s starting at len
|
/* returns index of the last instance of ch in s starting at len.
|
||||||
returns 0 if char not found (skips 0th index) */
|
returns 0 if char not found (skips 0th index). */
|
||||||
int char_rfind(const char *s, char ch, int len)
|
int char_rfind(const char *s, char ch, int len)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -53,6 +53,13 @@ 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);
|
||||||
|
|
||||||
|
/* Converts a binary representation of a Tox ID into a string.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int bin_id_to_string(const char *bin_id, size_t bin_id_size, char *output, size_t output_size);
|
||||||
|
|
||||||
/* get the current unix time (not thread safe) */
|
/* get the current unix time (not thread safe) */
|
||||||
uint64_t get_unix_time(void);
|
uint64_t get_unix_time(void);
|
||||||
|
|
||||||
@ -106,6 +113,14 @@ void filter_str(char *str, size_t len);
|
|||||||
/* gets base file name from path or original file name if no path is supplied */
|
/* gets base file name from path or original file name if no path is supplied */
|
||||||
size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname);
|
size_t get_file_name(char *namebuf, size_t bufsize, const char *pathname);
|
||||||
|
|
||||||
|
/* Gets the base directory of path and puts it in dir.
|
||||||
|
* dir must have at least as much space as path_len.
|
||||||
|
*
|
||||||
|
* Returns the length of the base directory on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
size_t get_base_dir(const char *path, size_t path_len, char *dir);
|
||||||
|
|
||||||
/* converts str to all lowercase */
|
/* converts str to all lowercase */
|
||||||
void str_to_lower(char *str);
|
void str_to_lower(char *str);
|
||||||
|
|
||||||
|
@ -202,12 +202,12 @@ size_t write_lookup_data(void *data, size_t size, size_t nmemb, void *user_point
|
|||||||
struct Recv_Data *recv_data = (struct Recv_Data *) user_pointer;
|
struct Recv_Data *recv_data = (struct Recv_Data *) user_pointer;
|
||||||
size_t real_size = size * nmemb;
|
size_t real_size = size * nmemb;
|
||||||
|
|
||||||
if (real_size > MAX_RECV_LOOKUP_DATA_SIZE)
|
if (real_size >= MAX_RECV_LOOKUP_DATA_SIZE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
memcpy(&recv_data->data, data, real_size);
|
memcpy(&recv_data->data, data, real_size);
|
||||||
recv_data->size = real_size;
|
recv_data->size = real_size;
|
||||||
recv_data->data[real_size] = 0;
|
recv_data->data[real_size] = '\0';
|
||||||
|
|
||||||
return real_size;
|
return real_size;
|
||||||
}
|
}
|
||||||
|
19
src/prompt.c
19
src/prompt.c
@ -50,11 +50,11 @@ extern struct Winthread Winthread;
|
|||||||
extern FriendsList Friends;
|
extern FriendsList Friends;
|
||||||
FriendRequests FrndRequests;
|
FriendRequests FrndRequests;
|
||||||
#ifdef VIDEO
|
#ifdef VIDEO
|
||||||
#define AC_NUM_GLOB_COMMANDS 22
|
#define AC_NUM_GLOB_COMMANDS 23
|
||||||
#elif AUDIO
|
#elif AUDIO
|
||||||
#define AC_NUM_GLOB_COMMANDS 20
|
#define AC_NUM_GLOB_COMMANDS 21
|
||||||
#else
|
#else
|
||||||
#define AC_NUM_GLOB_COMMANDS 18
|
#define AC_NUM_GLOB_COMMANDS 19
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Array of global command names used for tab completion. */
|
/* Array of global command names used for tab completion. */
|
||||||
@ -71,6 +71,7 @@ static const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
|
|||||||
{ "/join" },
|
{ "/join" },
|
||||||
{ "/log" },
|
{ "/log" },
|
||||||
{ "/myid" },
|
{ "/myid" },
|
||||||
|
{ "/myqr" },
|
||||||
{ "/nick" },
|
{ "/nick" },
|
||||||
{ "/note" },
|
{ "/note" },
|
||||||
{ "/nospam" },
|
{ "/nospam" },
|
||||||
@ -186,7 +187,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
getyx(self->window, y, x);
|
getyx(self->window, y, x);
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
if (x2 <= 0)
|
if (x2 <= 0 || y2 <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ignore non-menu related input if active */
|
/* ignore non-menu related input if active */
|
||||||
@ -257,6 +258,9 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
|
|||||||
int x2, y2;
|
int x2, y2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
pthread_mutex_lock(&Winthread.lock);
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
@ -432,6 +436,10 @@ void prompt_init_statusbar(ToxWindow *self, Tox *m)
|
|||||||
{
|
{
|
||||||
int x2, y2;
|
int x2, y2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
exit_toxic_err("failed in prompt_init_statusbar", FATALERR_CURSES);
|
||||||
|
|
||||||
(void) y2;
|
(void) y2;
|
||||||
|
|
||||||
/* Init statusbar info */
|
/* Init statusbar info */
|
||||||
@ -489,6 +497,9 @@ static void prompt_onInit(ToxWindow *self, Tox *m)
|
|||||||
int y2, x2;
|
int y2, x2;
|
||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
exit_toxic_err("failed in prompt_onInit", FATALERR_CURSES);
|
||||||
|
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
|
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT + 1, x2, 0, 0);
|
||||||
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
|
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - CHATBOX_HEIGHT, 0);
|
||||||
|
89
src/qr_code.c
Normal file
89
src/qr_code.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/* qr_obj_code.c
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Toxic All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This file is part of Toxic.
|
||||||
|
*
|
||||||
|
* Toxic is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Toxic is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <qrencode.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "toxic.h"
|
||||||
|
#include "windows.h"
|
||||||
|
#include "qr_code.h"
|
||||||
|
|
||||||
|
#define BORDER_LEN 1
|
||||||
|
#define CHAR_1 "\342\226\210"
|
||||||
|
#define CHAR_2 "\342\226\204"
|
||||||
|
#define CHAR_3 "\342\226\200"
|
||||||
|
|
||||||
|
/* Converts a tox ID string into a QRcode and prints it to the given file stream.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int ID_to_QRcode(const char *tox_id, FILE *fp)
|
||||||
|
{
|
||||||
|
if (fp == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
QRcode *qr_obj = QRcode_encodeString(tox_id, 0, QR_ECLEVEL_L, QR_MODE_8, 0);
|
||||||
|
|
||||||
|
if (qr_obj == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
size_t width = qr_obj->width;
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < width + BORDER_LEN * 2; ++i)
|
||||||
|
fprintf(fp, "%s", CHAR_1);
|
||||||
|
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
for (i = 0; i < width; i += 2) {
|
||||||
|
for (j = 0; j < BORDER_LEN; ++j)
|
||||||
|
fprintf(fp, "%s", CHAR_1);
|
||||||
|
|
||||||
|
const unsigned char *row_1 = qr_obj->data + width * i;
|
||||||
|
const unsigned char *row_2 = row_1 + width;
|
||||||
|
|
||||||
|
for (j = 0; j < width; ++j) {
|
||||||
|
bool x = row_1[j] & 1;
|
||||||
|
bool y = (i + 1) < width ? (row_2[j] & 1) : false;
|
||||||
|
|
||||||
|
if (x && y)
|
||||||
|
fprintf(fp, " ");
|
||||||
|
else if (x)
|
||||||
|
fprintf(fp, "%s", CHAR_2);
|
||||||
|
else if (y)
|
||||||
|
fprintf(fp, "%s", CHAR_3);
|
||||||
|
else
|
||||||
|
fprintf(fp, "%s", CHAR_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < BORDER_LEN; ++j)
|
||||||
|
fprintf(fp, "%s", CHAR_1);
|
||||||
|
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
QRcode_free(qr_obj);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
35
src/qr_code.h
Normal file
35
src/qr_code.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* qr_code.h
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Toxic All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This file is part of Toxic.
|
||||||
|
*
|
||||||
|
* Toxic is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Toxic is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QR_CODE
|
||||||
|
#define QR_CODE
|
||||||
|
|
||||||
|
#define QRCODE_FILENAME_EXT ".QRcode"
|
||||||
|
|
||||||
|
/* Converts a tox ID string into a QRcode and prints it to the given file stream.
|
||||||
|
*
|
||||||
|
* Returns 0 on success.
|
||||||
|
* Returns -1 on failure.
|
||||||
|
*/
|
||||||
|
int ID_to_QRcode(const char *tox_id, FILE *fp);
|
||||||
|
|
||||||
|
#endif /* QR_CODE */
|
13
src/toxic.c
13
src/toxic.c
@ -549,18 +549,21 @@ static void first_time_encrypt(const char *msg)
|
|||||||
system("clear");
|
system("clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store Tox profile data to given location
|
/* Store Tox profile data to path.
|
||||||
*
|
*
|
||||||
* Return 0 if stored successfully.
|
* Return 0 if stored successfully.
|
||||||
* Return -1 on error.
|
* Return -1 on error.
|
||||||
*/
|
*/
|
||||||
#define TEMP_PROFILE_SAVE_NAME "toxic_profile.tmp"
|
#define TEMP_PROFILE_EXT ".tmp"
|
||||||
int store_data(Tox *m, const char *path)
|
int store_data(Tox *m, const char *path)
|
||||||
{
|
{
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
FILE *fp = fopen(TEMP_PROFILE_SAVE_NAME, "wb");
|
char temp_path[strlen(path) + strlen(TEMP_PROFILE_EXT) + 1];
|
||||||
|
snprintf(temp_path, sizeof(temp_path), "%s%s", path, TEMP_PROFILE_EXT);
|
||||||
|
|
||||||
|
FILE *fp = fopen(temp_path, "wb");
|
||||||
|
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
@ -585,11 +588,13 @@ int store_data(Tox *m, const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fwrite(enc_data, enc_len, 1, fp) != 1) {
|
if (fwrite(enc_data, enc_len, 1, fp) != 1) {
|
||||||
|
fprintf(stderr, "Failed to write profile data.\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else { /* data will not be encrypted */
|
} else { /* data will not be encrypted */
|
||||||
if (fwrite(data, data_len, 1, fp) != 1) {
|
if (fwrite(data, data_len, 1, fp) != 1) {
|
||||||
|
fprintf(stderr, "Failed to write profile data.\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -597,7 +602,7 @@ int store_data(Tox *m, const char *path)
|
|||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
if (rename(TEMP_PROFILE_SAVE_NAME, path) != 0)
|
if (rename(temp_path, path) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -88,6 +88,7 @@ typedef enum _FATAL_ERRS {
|
|||||||
FATALERR_PROXY = -10, /* Tox network failed to init using a proxy */
|
FATALERR_PROXY = -10, /* Tox network failed to init using a proxy */
|
||||||
FATALERR_ENCRYPT = -11, /* Data file encryption failure */
|
FATALERR_ENCRYPT = -11, /* Data file encryption failure */
|
||||||
FATALERR_TOX_INIT = -12, /* Tox instance failed to initialize */
|
FATALERR_TOX_INIT = -12, /* Tox instance failed to initialize */
|
||||||
|
FATALERR_CURSES = -13, /* Unrecoverable Ncurses error */
|
||||||
} FATAL_ERRS;
|
} FATAL_ERRS;
|
||||||
|
|
||||||
/* Fixes text color problem on some terminals.
|
/* Fixes text color problem on some terminals.
|
||||||
|
@ -153,9 +153,10 @@ int stop_video_transmission(Call *call, int friend_number)
|
|||||||
CallControl.video_bit_rate = 0;
|
CallControl.video_bit_rate = 0;
|
||||||
toxav_bit_rate_set(CallControl.av, friend_number, -1, CallControl.video_bit_rate, NULL);
|
toxav_bit_rate_set(CallControl.av, friend_number, -1, CallControl.video_bit_rate, NULL);
|
||||||
|
|
||||||
if ( call->vin_idx != -1 )
|
if ( call->vin_idx != -1 ) {
|
||||||
close_video_device(vdt_input, call->vin_idx);
|
close_video_device(vdt_input, call->vin_idx);
|
||||||
call->vin_idx = -1;
|
call->vin_idx = -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -190,12 +191,12 @@ void callback_recv_video_starting(uint32_t friend_number)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Call* this_call = &CallControl.calls[friend_number];
|
// Call* this_call = &CallControl.calls[friend_number];
|
||||||
|
|
||||||
if ( this_call->vout_idx != -1 )
|
// if ( this_call->vout_idx != -1 )
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
open_primary_video_device(vdt_output, &this_call->vout_idx);
|
// open_primary_video_device(vdt_output, &this_call->vout_idx);
|
||||||
}
|
}
|
||||||
void callback_recv_video_end(uint32_t friend_number)
|
void callback_recv_video_end(uint32_t friend_number)
|
||||||
{
|
{
|
||||||
@ -243,37 +244,37 @@ void cmd_video(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M
|
|||||||
{
|
{
|
||||||
return; // TODO: Fix video
|
return; // TODO: Fix video
|
||||||
|
|
||||||
const char *error_str;
|
// const char *error_str;
|
||||||
Call* this_call = &CallControl.calls[self->num];
|
// Call* this_call = &CallControl.calls[self->num];
|
||||||
|
|
||||||
if ( argc != 0 ) {
|
// if ( argc != 0 ) {
|
||||||
error_str = "Unknown arguments.";
|
// error_str = "Unknown arguments.";
|
||||||
goto on_error;
|
// goto on_error;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if ( !CallControl.av ) {
|
// if ( !CallControl.av ) {
|
||||||
error_str = "ToxAV not supported!";
|
// error_str = "ToxAV not supported!";
|
||||||
goto on_error;
|
// goto on_error;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if ( !self->stb->connection ) {
|
// if ( !self->stb->connection ) {
|
||||||
error_str = "Friend is offline.";
|
// error_str = "Friend is offline.";
|
||||||
goto on_error;
|
// goto on_error;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if ( !self->is_call ) {
|
// if ( !self->is_call ) {
|
||||||
error_str = "Not in call!";
|
// error_str = "Not in call!";
|
||||||
goto on_error;
|
// goto on_error;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if ( this_call->vin_idx == -1 )
|
// if ( this_call->vin_idx == -1 )
|
||||||
callback_video_starting(self->num);
|
// callback_video_starting(self->num);
|
||||||
else
|
// else
|
||||||
callback_video_end(self->num);
|
// callback_video_end(self->num);
|
||||||
|
|
||||||
return;
|
// return;
|
||||||
on_error:
|
// on_error:
|
||||||
print_err (self, error_str);
|
// print_err (self, error_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_list_video_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
void cmd_list_video_devices(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
|
||||||
|
@ -505,6 +505,9 @@ void on_window_resize(void)
|
|||||||
getmaxyx(stdscr, y2, x2);
|
getmaxyx(stdscr, y2, x2);
|
||||||
y2 -= 2;
|
y2 -= 2;
|
||||||
|
|
||||||
|
if (y2 <= 0 || x2 <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
for (i = 0; i < MAX_WINDOWS_NUM; ++i) {
|
||||||
|
Loading…
Reference in New Issue
Block a user