diff --git a/Makefile b/Makefile index f6f4209..392b257 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ LDFLAGS = $(USER_LDFLAGS) OBJ = chat.o chat_commands.o configdir.o dns.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 += 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 +OBJ += group_commands.o term_mplex.o avatars.o # Check on wich system we are running UNAME_S = $(shell uname -s) diff --git a/src/avatars.c b/src/avatars.c new file mode 100644 index 0000000..fb7007d --- /dev/null +++ b/src/avatars.c @@ -0,0 +1,214 @@ +/* avatars.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 . + * + */ + +#include +#include +#include + +#include "misc_tools.h" +#include "file_transfers.h" +#include "friendlist.h" + +extern FriendsList Friends; + +static struct Avatar { + char name[MAX_STR_SIZE + 1]; + size_t name_len; + char path[PATH_MAX + 1]; + size_t path_len; + off_t size; + bool is_set; +} Avatar; + + +static void avatar_clear(void) +{ + memset(&Avatar, 0, sizeof(struct Avatar)); +} + +/* Sends avatar to friendnum. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +int avatar_send(Tox *m, uint32_t friendnum) +{ + TOX_ERR_FILE_SEND err; + uint32_t filenum = tox_file_send(m, friendnum, TOX_FILE_KIND_AVATAR, (size_t) Avatar.size, + NULL, (uint8_t *) Avatar.name, Avatar.name_len, &err); + + if (!Avatar.is_set) + return 0; + + if (err != TOX_ERR_FILE_SEND_OK) { + fprintf(stderr, "tox_file_send failed for friendnumber %d (error %d)\n", friendnum, err); + return -1; + } + + struct FileTransfer *ft = get_new_file_sender(friendnum); + + if (!ft) + return -1; + + ft->file = fopen(Avatar.path, "r"); + + if (ft->file == NULL) + return -1; + + ft->file_size = Avatar.size; + + if (ft->file_size == 0) { + fclose(ft->file); + return -1; + } + + memcpy(ft->file_name, Avatar.name, Avatar.name_len + 1); + ft->state = FILE_TRANSFER_PENDING; + ft->filenum = filenum; + ft->friendnum = friendnum; + ft->direction = FILE_TRANSFER_SEND; + ft->file_type = TOX_FILE_KIND_AVATAR; + + return 0; +} + +/* Sends avatar to all friends */ +static void avatar_send_all(Tox *m) +{ + size_t i; + + for (i = 0; i < Friends.max_idx; ++i) { + if (Friends.list[i].connection_status != TOX_CONNECTION_NONE) + avatar_send(m, Friends.list[i].num); + } +} + +/* Sets avatar to path and sends it to all online contacts. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +int avatar_set(Tox *m, const char *path, size_t path_len) +{ + avatar_clear(); + + if (path_len == 0 || path_len >= sizeof(Avatar.path)) + return -1; + + FILE *fp = fopen(path, "rb"); + + if (fp == NULL) + return -1; + + char PNG_signature[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; + + if (check_file_signature(PNG_signature, sizeof(PNG_signature), fp) != 0) { + fclose(fp); + return -1; + } + + fclose(fp); + + get_file_name(Avatar.name, sizeof(Avatar.name), path); + Avatar.name_len = strlen(Avatar.name); + memcpy(Avatar.path, path, sizeof(Avatar.path)); + Avatar.path_len = path_len; + Avatar.size = file_size(path); + Avatar.is_set = 1; + + avatar_send_all(m); + + return 0; +} + +/* Unsets avatar and sends to all online contacts. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +void avatar_unset(Tox *m) +{ + avatar_clear(); + avatar_send_all(m); +} + +void on_avatar_file_control(Tox *m, struct FileTransfer *ft, TOX_FILE_CONTROL control) +{ + switch (control) { + case TOX_FILE_CONTROL_RESUME: + if (ft->state == FILE_TRANSFER_PENDING) { + ft->state = FILE_TRANSFER_STARTED; + } else if (ft->state == FILE_TRANSFER_PAUSED) { + ft->state = FILE_TRANSFER_STARTED; + } + break; + + case TOX_FILE_CONTROL_PAUSE: + ft->state = FILE_TRANSFER_PAUSED; + break; + + case TOX_FILE_CONTROL_CANCEL: + close_file_transfer(NULL, m, ft, -1, NULL, silent); + break; + } +} + +void on_avatar_chunk_request(Tox *m, struct FileTransfer *ft, uint64_t position, size_t length) +{ + if (ft->state != FILE_TRANSFER_STARTED) + return; + + if (length == 0) { + close_file_transfer(NULL, m, ft, -1, NULL, silent); + return; + } + + if (ft->file == NULL) { + close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent); + return; + } + + if (ft->position != position) { + if (fseek(ft->file, position, SEEK_SET) == -1) { + close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent); + return; + } + + ft->position = position; + } + + uint8_t send_data[length]; + size_t send_length = fread(send_data, 1, sizeof(send_data), ft->file); + + if (send_length != length) { + close_file_transfer(NULL, m, ft, TOX_FILE_CONTROL_CANCEL, NULL, silent); + return; + } + + TOX_ERR_FILE_SEND_CHUNK err; + tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err); + + if (err != TOX_ERR_FILE_SEND_CHUNK_OK) + fprintf(stderr, "tox_file_send_chunk failed in avatar callback (error %d)\n", err); + + ft->position += send_length; +} diff --git a/src/avatars.h b/src/avatars.h new file mode 100644 index 0000000..4ef2c60 --- /dev/null +++ b/src/avatars.h @@ -0,0 +1,50 @@ +/* avatars.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 . + * + */ + +#ifndef AVATARS_H +#define AVATARS_H + +/* Sends avatar to friendnum. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +int avatar_send(Tox *m, uint32_t friendnum); + +/* Sets avatar to path and sends it to all online contacts. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +int avatar_set(Tox *m, const char *path, size_t length); + +/* Unsets avatar and sends to all online contacts. + * + * Returns 0 on success. + * Returns -1 on failure. + */ +void avatar_unset(Tox *m); + +void on_avatar_chunk_request(Tox *m, struct FileTransfer *ft, uint64_t position, size_t length); +void on_avatar_file_control(Tox *m, struct FileTransfer *ft, TOX_FILE_CONTROL control); + +#endif /* AVATARS_H */ diff --git a/src/chat.c b/src/chat.c index c8683be..9eaed52 100644 --- a/src/chat.c +++ b/src/chat.c @@ -298,7 +298,7 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum, struct FileTransfer *ft = get_file_transfer_struct(friendnum, filenum); - if (ft == NULL) + if (!ft) return; if (ft->state != FILE_TRANSFER_STARTED) @@ -339,10 +339,10 @@ static void chat_onFileChunkRequest(ToxWindow *self, Tox *m, uint32_t friendnum, } TOX_ERR_FILE_SEND_CHUNK err; - tox_file_send_chunk(m, friendnum, filenum, position, send_data, send_length, &err); + tox_file_send_chunk(m, ft->friendnum, ft->filenum, position, send_data, send_length, &err); if (err != TOX_ERR_FILE_SEND_CHUNK_OK) - fprintf(stderr, "tox_file_send_chunk failed (error %d)\n", err); + fprintf(stderr, "tox_file_send_chunk failed in chat callback (error %d)\n", err); ft->position += send_length; ft->bps += send_length; @@ -356,7 +356,7 @@ static void chat_onFileRecvChunk(ToxWindow *self, Tox *m, uint32_t friendnum, ui struct FileTransfer *ft = get_file_transfer_struct(friendnum, filenum); - if (ft == NULL) + if (!ft) return; if (ft->state != FILE_TRANSFER_STARTED) @@ -389,12 +389,12 @@ static void chat_onFileRecvChunk(ToxWindow *self, Tox *m, uint32_t friendnum, ui static void chat_onFileControl(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_t filenum, TOX_FILE_CONTROL control) { - if (self->num != friendnum) + if (friendnum != self->num) return; struct FileTransfer *ft = get_file_transfer_struct(friendnum, filenum); - if (ft == NULL) + if (!ft) return; char msg[MAX_STR_SIZE]; @@ -411,18 +411,14 @@ static void chat_onFileControl(ToxWindow *self, Tox *m, uint32_t friendnum, uint line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", progline); sound_notify(self, silent, NT_NOFOCUS | NT_BEEP | NT_WNDALERT_2, NULL); ft->line_id = self->chatwin->hst->line_end->id + 2; - - break; - } - - /* transfer is resumed */ - if (ft->state == FILE_TRANSFER_PAUSED) { + } else if (ft->state == FILE_TRANSFER_PAUSED) { /* transfer is resumed */ ft->state = FILE_TRANSFER_STARTED; } break; case TOX_FILE_CONTROL_PAUSE: + ft->state = FILE_TRANSFER_PAUSED; break; case TOX_FILE_CONTROL_CANCEL: @@ -501,6 +497,7 @@ static void chat_onFileRecv(ToxWindow *self, Tox *m, uint32_t friendnum, uint32_ ft->file_size = file_size; ft->friendnum = friendnum; ft->filenum = filenum; + ft->file_type = TOX_FILE_KIND_DATA; snprintf(ft->file_path, sizeof(ft->file_path), "%s", file_path); snprintf(ft->file_name, sizeof(ft->file_name), "%s", filename); diff --git a/src/chat_commands.c b/src/chat_commands.c index 4937aaa..3352f47 100644 --- a/src/chat_commands.c +++ b/src/chat_commands.c @@ -123,7 +123,7 @@ void cmd_join_group(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*ar #ifdef AUDIO else groupnum = toxav_join_av_groupchat(m, self->num, (uint8_t *) groupkey, length, - write_device_callback_group, NULL); + NULL, NULL); #endif if (groupnum == -1) { @@ -277,6 +277,7 @@ void cmd_sendfile(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv ft->filenum = filenum; ft->friendnum = self->num; ft->direction = FILE_TRANSFER_SEND; + ft->file_type = TOX_FILE_KIND_DATA; char sizestr[32]; bytes_convert_str(sizestr, sizeof(sizestr), filesize); diff --git a/src/file_transfers.c b/src/file_transfers.c index 4ac5c1b..771f958 100644 --- a/src/file_transfers.c +++ b/src/file_transfers.c @@ -230,7 +230,15 @@ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnum) size_t i; for (i = 0; i < MAX_FILES; ++i) { - close_file_transfer(NULL, m, &Friends.list[friendnum].file_sender[i], -1, NULL, silent); - close_file_transfer(NULL, m, &Friends.list[friendnum].file_receiver[i], -1, NULL, silent); + close_file_transfer(NULL, m, &Friends.list[friendnum].file_sender[i], TOX_FILE_CONTROL_CANCEL, NULL, silent); + close_file_transfer(NULL, m, &Friends.list[friendnum].file_receiver[i], TOX_FILE_CONTROL_CANCEL, NULL, silent); } } + +void kill_all_file_transfers(Tox *m) +{ + size_t i; + + for (i = 0; i < Friends.max_idx; ++i) + kill_all_file_transfers_friend(m, Friends.list[i].num); +} diff --git a/src/file_transfers.h b/src/file_transfers.h index ba12886..52b19e1 100644 --- a/src/file_transfers.h +++ b/src/file_transfers.h @@ -52,6 +52,7 @@ struct FileTransfer { FILE *file; FILE_TRANSFER_STATE state; FILE_TRANSFER_DIRECTION direction; + uint8_t file_type; char file_name[TOX_MAX_FILENAME_LENGTH + 1]; char file_path[PATH_MAX + 1]; /* Not used by senders */ double bps; @@ -59,8 +60,8 @@ struct FileTransfer { uint32_t friendnum; size_t index; uint64_t file_size; - uint64_t last_progress; uint64_t position; + uint64_t last_progress; uint32_t line_id; }; @@ -107,4 +108,6 @@ void close_file_transfer(ToxWindow *self, Tox *m, struct FileTransfer *ft, int C /* Kills all active file transfers for friendnum */ void kill_all_file_transfers_friend(Tox *m, uint32_t friendnum); +void kill_all_file_transfers(Tox *m); + #endif /* #define FILE_TRANSFERS_H */ diff --git a/src/friendlist.c b/src/friendlist.c index dd76371..c8df965 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -38,6 +38,7 @@ #include "notify.h" #include "help.h" #include "log.h" +#include "avatars.h" #ifdef AUDIO #include "audio_call.h" @@ -330,11 +331,15 @@ static void friendlist_onConnectionChange(ToxWindow *self, Tox *m, uint32_t num, if (num >= Friends.max_idx) return; - if (connection_status == TOX_CONNECTION_NONE) + if (connection_status == TOX_CONNECTION_NONE) { --Friends.num_online; - else if (Friends.list[num].connection_status == TOX_CONNECTION_NONE) + } else if (Friends.list[num].connection_status == TOX_CONNECTION_NONE) { ++Friends.num_online; + if (avatar_send(m, num) == -1) + fprintf(stderr, "avatar_send failed for friend %d\n", num); + } + Friends.list[num].connection_status = connection_status; update_friend_last_online(num, get_unix_time()); store_data(m, DATA_FILE); @@ -403,13 +408,19 @@ void friendlist_onFriendAdded(ToxWindow *self, Tox *m, uint32_t num, bool sort) Friends.list[i].status = TOX_USER_STATUS_NONE; Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON; - TOX_ERR_FRIEND_GET_PUBLIC_KEY err; - tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &err); + TOX_ERR_FRIEND_GET_PUBLIC_KEY pkerr; + tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &pkerr); - if (err != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) - fprintf(stderr, "tox_friend_get_public_key failed (error %d)\n", err); + if (pkerr != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) + fprintf(stderr, "tox_friend_get_public_key failed (error %d)\n", pkerr); - update_friend_last_online(i, tox_friend_get_last_online(m, num, NULL)); + TOX_ERR_FRIEND_GET_LAST_ONLINE loerr; + uint64_t t = tox_friend_get_last_online(m, num, &loerr); + + if (loerr != TOX_ERR_FRIEND_GET_LAST_ONLINE_OK) + t = 0; + + update_friend_last_online(i, t); char tempname[TOX_MAX_NAME_LENGTH] = {0}; get_nick_truncate(m, tempname, num); @@ -945,6 +956,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) pthread_mutex_lock(&Winthread.lock); tox_friend_get_status_message(m, Friends.list[f].num, (uint8_t *) statusmsg, NULL); size_t s_len = tox_friend_get_status_message_size(m, Friends.list[f].num, NULL); + statusmsg[s_len] = '\0'; pthread_mutex_unlock(&Winthread.lock); filter_str(statusmsg, s_len); @@ -962,7 +974,7 @@ static void friendlist_onDraw(ToxWindow *self, Tox *m) Friends.list[f].statusmsg_len = maxlen; } - if (Friends.list[f].statusmsg[0]) + if (Friends.list[f].statusmsg_len > 0) wprintw(self->window, " %s", Friends.list[f].statusmsg); wprintw(self->window, "\n"); diff --git a/src/global_commands.c b/src/global_commands.c index 7ad7e86..5d7c6b1 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -35,6 +35,7 @@ #include "prompt.h" #include "help.h" #include "term_mplex.h" +#include "avatars.h" extern char *DATA_FILE; extern ToxWindow *prompt; @@ -198,72 +199,37 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX void cmd_avatar(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { - // if (argc < 2) { - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: No file path supplied."); - // return; - // } + if (argc < 2 || strlen(argv[1]) < 3) { + avatar_unset(m); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar is not set."); + return; + } - // /* turns the avatar off */ - // if (strlen(argv[1]) < 3) { - // tox_unset_avatar(m); - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "No avatar set."); - // return; - // } + if (argv[1][0] != '\"') { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Path must be enclosed in quotes."); + return; + } - // if (argv[1][0] != '\"') { - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Path must be enclosed in quotes."); - // return; - // } + /* remove opening and closing quotes */ + char path[MAX_STR_SIZE]; + snprintf(path, sizeof(path), "%s", &argv[1][1]); + int len = strlen(path) - 1; - // /* remove opening and closing quotes */ - // char path[MAX_STR_SIZE]; - // snprintf(path, sizeof(path), "%s", &argv[1][1]); - // int len = strlen(path) - 1; - // path[len] = '\0'; + if (len <= 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid path."); + return; + } - // off_t sz = file_size(path); + path[len] = '\0'; + char filename[MAX_STR_SIZE]; + get_file_name(filename, sizeof(filename), path); - // if (sz <= 8) { - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Invalid file."); - // return; - // } + if (avatar_set(m, path, len) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar."); + return; + } - // FILE *fp = fopen(path, "rb"); - - // if (fp == NULL) { - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Could not open file."); - // return; - // } - - // char PNG_signature[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; - - // if (check_file_signature(PNG_signature, sizeof(PNG_signature), fp) != 0) { - // fclose(fp); - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: File type not supported."); - // return; - // } - - // char *avatar = malloc(sz); - - // if (avatar == NULL) - // exit_toxic_err("Failed in cmd_avatar", FATALERR_MEMORY); - - // if (fread(avatar, sz, 1, fp) != 1) { - // fclose(fp); - // free(avatar); - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar: Read fail."); - // return; - // } - - // if (tox_set_avatar(m, TOX_AVATAR_FORMAT_PNG, (const uint8_t *) avatar, (uint32_t) sz) == -1) - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set avatar"); - - // char filename[MAX_STR_SIZE]; - // get_file_name(filename, sizeof(filename), path); - // line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar set to '%s'", filename); - - // fclose(fp); - // free(avatar); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Avatar set to '%s'", filename); } void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) @@ -372,7 +338,7 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg groupnum = tox_add_groupchat(m); #ifdef AUDIO else - groupnum = toxav_add_av_groupchat(m, write_device_callback_group, NULL); + groupnum = toxav_add_av_groupchat(m, NULL, NULL); #endif if (groupnum == -1) { diff --git a/src/toxic.c b/src/toxic.c index d8820a0..55f5a19 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -124,6 +124,7 @@ void exit_toxic_success(Tox *m) store_data(m, DATA_FILE); memset(&user_password, 0, sizeof(struct user_password)); kill_all_windows(m); + kill_all_file_transfers(m); terminate_notify(); #ifdef AUDIO @@ -506,7 +507,7 @@ int store_data(Tox *m, const char *path) fclose(fp); return -1; } - } else { + } else { /* data will not be encrypted */ if (fwrite(data, data_len, 1, fp) != 1) { fclose(fp); return -1; diff --git a/src/toxic.h b/src/toxic.h index 2339df9..6129fab 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -121,9 +121,4 @@ void on_file_recv(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint32_t k void on_typing_change(Tox *m, uint32_t friendnumber, bool is_typing, void *userdata); void on_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *userdata); -#ifdef AUDIO -void write_device_callback_group(Tox *m, int groupnum, int peernum, const int16_t *pcm, unsigned int samples, - uint8_t channels, unsigned int sample_rate, void *arg); -#endif /* AUDIO */ - #endif /* #define TOXIC_H */ diff --git a/src/windows.c b/src/windows.c index ebd1e60..de41a31 100644 --- a/src/windows.c +++ b/src/windows.c @@ -33,8 +33,10 @@ #include "chat.h" #include "line_info.h" #include "misc_tools.h" - +#include "avatars.h" #include "settings.h" +#include "file_transfers.h" + extern char *DATA_FILE; extern struct Winthread Winthread; static ToxWindow windows[MAX_WINDOWS_NUM]; @@ -215,6 +217,16 @@ void on_group_titlechange(Tox *m, int groupnumber, int peernumber, const uint8_t void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, size_t length, void *userdata) { + struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber); + + if (!ft) + return; + + if (ft->file_type == TOX_FILE_KIND_AVATAR) { + on_avatar_chunk_request(m, ft, position, length); + return; + } + size_t i; for (i = 0; i < MAX_WINDOWS_NUM; ++i) { @@ -226,6 +238,11 @@ void on_file_chunk_request(Tox *m, uint32_t friendnumber, uint32_t filenumber, u void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data, size_t length, void *user_data) { + struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber); + + if (!ft) + return; + size_t i; for (i = 0; i < MAX_WINDOWS_NUM; ++i) { @@ -237,6 +254,16 @@ void on_file_recv_chunk(Tox *m, uint32_t friendnumber, uint32_t filenumber, uint void on_file_control(Tox *m, uint32_t friendnumber, uint32_t filenumber, TOX_FILE_CONTROL control, void *userdata) { + struct FileTransfer *ft = get_file_transfer_struct(friendnumber, filenumber); + + if (!ft) + return; + + if (ft->file_type == TOX_FILE_KIND_AVATAR) { + on_avatar_file_control(m, ft, control); + return; + } + size_t i; for (i = 0; i < MAX_WINDOWS_NUM; ++i) { @@ -272,20 +299,6 @@ void on_read_receipt(Tox *m, uint32_t friendnumber, uint32_t receipt, void *user windows[i].onReadReceipt(&windows[i], m, friendnumber, receipt); } } - -#ifdef AUDIO -void write_device_callback_group(Tox *m, int groupnum, int peernum, const int16_t *pcm, unsigned int samples, - uint8_t channels, unsigned int sample_rate, void *arg) -{ - size_t i; - - for (i = 0; i < MAX_WINDOWS_NUM; ++i) { - if (windows[i].onWriteDevice != NULL) - windows[i].onWriteDevice(&windows[i], m, groupnum, peernum, pcm, samples, channels, samples); - } -} -#endif /* AUDIO */ - /* CALLBACKS END */ int add_window(Tox *m, ToxWindow w)