static void friendlist_onFileRecv(ToxWindow *self, Tox *m, uint32_t num, uint32_t filenum, uint64_t file_size, const char *filename, size_t name_length) { if (num >= Friends.max_idx) { return; } if (Friends.list[num].chatwin != -1) { return; } if (get_num_active_windows() < MAX_WINDOWS_NUM) { Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num)); return; } tox_file_control(m, num, filenum, TOX_FILE_CONTROL_CANCEL, NULL); char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, num); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "* File transfer from %s failed: too many windows are open.", nick); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); }
static void friendlist_onAV(ToxWindow *self, ToxAV *av, uint32_t friend_number, int state) { assert(0); if( friend_number >= Friends.max_idx) return; assert(0); Tox *m = toxav_get_tox(av); if (Friends.list[friend_number].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { if(state != TOXAV_FRIEND_CALL_STATE_FINISHED) { Friends.list[friend_number].chatwin = add_window(m, new_chat(m, Friends.list[friend_number].num)); set_active_window(Friends.list[friend_number].chatwin); } } else { char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, Friends.list[friend_number].num); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Audio action from: %s!", nick); const char *errmsg = "* Warning: Too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); } } }
static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index) { int id = toxav_get_peer_id(av, call_index, 0); if ( id != av_ErrorUnknown && id >= Friends.max_idx) return; Tox *m = toxav_get_tox(av); if (Friends.list[id].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { if (toxav_get_call_state(av, call_index) == av_CallStarting) { /* Only open windows when call is incoming */ Friends.list[id].chatwin = add_window(m, new_chat(m, Friends.list[id].num)); } } else { char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, Friends.list[id].num); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, 0, "Audio action from: %s!", nick); const char *errmsg = "* Warning: Too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg); sound_notify(prompt, error, NT_WNDALERT_1, NULL); } } }
static void friendlist_onMessage(ToxWindow *self, Tox *m, uint32_t num, Tox_Message_Type type, const char *str, size_t length) { if (num >= Friends.max_idx) { return; } if (Friends.list[num].chatwin != -1) { return; } if (get_num_active_windows() < MAX_WINDOWS_NUM) { Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num)); return; } char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, num); char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); line_info_add(prompt, timefrmt, nick, NULL, IN_MSG, 0, 0, "%s", str); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Warning: Too many windows are open."); sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL); }
void friendlist_onFriendAdded(ToxWindow *self, Tox *m, uint32_t num, bool sort) { realloc_friends(Friends.max_idx + 1); memset(&Friends.list[Friends.max_idx], 0, sizeof(ToxicFriend)); uint32_t i; for (i = 0; i <= Friends.max_idx; ++i) { if (Friends.list[i].active) { continue; } ++Friends.num_friends; Friends.list[i].num = num; Friends.list[i].active = true; Friends.list[i].chatwin = -1; Friends.list[i].connection_status = TOX_CONNECTION_NONE; 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 pkerr; tox_friend_get_public_key(m, num, (uint8_t *) Friends.list[i].pub_key, &pkerr); if (pkerr != TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) { fprintf(stderr, "tox_friend_get_public_key failed (error %d)\n", pkerr); } Tox_Err_Friend_Get_Last_Online loerr; time_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); snprintf(Friends.list[i].name, sizeof(Friends.list[i].name), "%s", tempname); Friends.list[i].namelength = strlen(Friends.list[i].name); if (i == Friends.max_idx) { ++Friends.max_idx; } if (sort) { sort_friendlist_index(); } #ifdef AUDIO init_friend_AV(i); #endif return; } }
static void chat_onInit(ToxWindow *self, Tox *m) { curs_set(1); int x2, y2; getmaxyx(self->window, y2, x2); self->x = x2; /* Init statusbar info */ StatusBar *statusbar = self->stb; statusbar->status = tox_get_user_status(m, self->num); statusbar->is_online = tox_get_friend_connection_status(m, self->num) == 1; char statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {'\0'}; uint16_t s_len = tox_get_status_message(m, self->num, (uint8_t *) statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH); statusmsg[s_len] = '\0'; snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg); statusbar->statusmsg_len = s_len; char nick[TOX_MAX_NAME_LENGTH]; int n_len = get_nick_truncate(m, nick, self->num); snprintf(statusbar->nick, sizeof(statusbar->nick), "%s", nick); statusbar->nick_len = n_len; /* Init subwindows */ ChatContext *ctx = self->chatwin; statusbar->topline = subwin(self->window, 2, 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->hst = calloc(1, sizeof(struct history)); ctx->log = calloc(1, sizeof(struct chatlog)); if (ctx->log == NULL || ctx->hst == NULL) exit_toxic_err("failed in chat_onInit", FATALERR_MEMORY); line_info_init(ctx->hst); if (friends[self->num].logging_on) log_enable(nick, friends[self->num].pub_key, ctx->log); execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); scrollok(ctx->history, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0); }
static void chat_onAction(ToxWindow *self, Tox *m, int32_t num, const char *action, uint16_t len) { if (self->num != num) return; ChatContext *ctx = self->chatwin; char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, num); char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); line_info_add(self, timefrmt, nick, NULL, ACTION, 0, 0, action); write_to_log(action, nick, ctx->log, true); notify(self, generic_message, NT_WNDALERT_1 | NT_NOFOCUS); }
void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort) { if (Friends.max_idx < 0) return; Friends.num_friends = tox_count_friendlist(m); realloc_friends(Friends.max_idx + 1); memset(&Friends.list[Friends.max_idx], 0, sizeof(ToxicFriend)); int i; for (i = 0; i <= Friends.max_idx; ++i) { if (Friends.list[i].active) continue; Friends.list[i].num = num; Friends.list[i].active = true; Friends.list[i].chatwin = -1; Friends.list[i].online = false; Friends.list[i].status = TOX_USERSTATUS_NONE; Friends.list[i].logging_on = (bool) user_settings->autolog == AUTOLOG_ON; tox_get_client_id(m, num, (uint8_t *) Friends.list[i].pub_key); update_friend_last_online(i, tox_get_last_online(m, i)); char tempname[TOX_MAX_NAME_LENGTH] = {0}; int len = get_nick_truncate(m, tempname, num); if (len == -1 || tempname[0] == '\0') { strcpy(Friends.list[i].name, UNKNOWN_NAME); Friends.list[i].namelength = strlen(UNKNOWN_NAME); } else { /* Enforce toxic's maximum name length */ snprintf(Friends.list[i].name, sizeof(Friends.list[i].name), "%s", tempname); Friends.list[i].namelength = strlen(Friends.list[i].name); } if (i == Friends.max_idx) ++Friends.max_idx; if (sort) sort_friendlist_index(); return; } }
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, uint8_t type, const char *group_pub_key, uint16_t length) { if (num >= Friends.max_idx) return; if (Friends.list[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num)); } else { char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, num); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Group chat invite from %s failed: too many windows are open.", nick); sound_notify(prompt, error, NT_WNDALERT_1, NULL); } } }
static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum , uint8_t status) { if (friendnum < 0) return; ChatContext *ctx = self->chatwin; char nick[TOX_MAX_NAME_LENGTH] = {0}; /* stop removing this initiation */ get_nick_truncate(m, nick, friendnum); if (!nick[0]) snprintf(nick, sizeof(nick), "%s", UNKNOWN_NAME); char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); const char *msg; if (status == 1) { msg = "has come online"; line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, GREEN, msg); write_to_log(msg, nick, ctx->log, true); if (self->active_box != -1) box_notify2(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, "%s has come online", nick ); else box_notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, "Toxic", "%s has come online", nick ); } else { msg = "has gone offline"; line_info_add(self, timefrmt, nick, NULL, CONNECTION, 0, RED, msg); write_to_log(msg, nick, ctx->log, true); if (self->active_box != -1) box_notify2(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, "%s has gone offline", nick ); else box_notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, "Toxic", "%s has gone offline", nick ); } }
void friendlist_onFriendAdded(ToxWindow *self, Tox *m, int32_t num, bool sort) { if (max_friends_index < 0 || max_friends_index >= MAX_FRIENDS_NUM) return; int i; for (i = 0; i <= max_friends_index; ++i) { if (!friends[i].active) { friends[i].num = num; friends[i].active = true; friends[i].chatwin = -1; friends[i].online = false; friends[i].status = TOX_USERSTATUS_NONE; friends[i].logging_on = (bool) user_settings_->autolog == AUTOLOG_ON; tox_get_client_id(m, num, (uint8_t *) friends[i].pub_key); update_friend_last_online(i, tox_get_last_online(m, i)); char tempname[TOX_MAX_NAME_LENGTH] = {0}; int len = get_nick_truncate(m, tempname, num); if (len == -1 || tempname[0] == '\0') { strcpy(friends[i].name, UNKNOWN_NAME); friends[i].namelength = strlen(UNKNOWN_NAME); } else { /* Enforce toxic's maximum name length */ friends[i].namelength = len; snprintf(friends[i].name, sizeof(friends[i].name), "%s", tempname); } num_friends = tox_count_friendlist(m); if (i == max_friends_index) ++max_friends_index; if (sort) sort_friendlist_index(); return; } } }
static void chat_onGroupInvite(ToxWindow *self, Tox *m, int32_t friendnumber, const char *group_pub_key) { if (self->num != friendnumber) return; const char *msg; char name[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, name, friendnumber); msg = "%s has invited you to a group chat."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg, name); line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/join\" to join the chat."); memcpy(friends[friendnumber].groupchat_key, group_pub_key, sizeof(friends[friendnumber].groupchat_key)); friends[friendnumber].groupchat_pending = true; notify(self, generic_message, NT_WNDALERT_2); }
static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, const char *group_pub_key) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); notify(self, generic_message, NT_WNDALERT_0 | NT_NOFOCUS); } else { char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, num); const char *msg = "* Group chat invite from %s failed: too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg, nick); notify(prompt, error, NT_WNDALERT_1); } } }
static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, uint8_t filenum, uint64_t filesize, const char *filename, uint16_t filename_len) { if (num >= Friends.max_idx) return; if (Friends.list[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { Friends.list[num].chatwin = add_window(m, new_chat(m, Friends.list[num].num)); } else { tox_file_send_control(m, num, 1, filenum, TOX_FILECONTROL_KILL, 0, 0); char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, num); line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, "* File transfer from %s failed: too many windows are open.", nick); sound_notify(prompt, error, NT_WNDALERT_1, NULL); } } }
static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, const char *str, uint16_t len) { if (num >= max_friends_index) return; if (friends[num].chatwin == -1) { if (get_num_active_windows() < MAX_WINDOWS_NUM) { friends[num].chatwin = add_window(m, new_chat(m, friends[num].num)); notify(self, generic_message, NT_WNDALERT_0 | NT_NOFOCUS); } else { char nick[TOX_MAX_NAME_LENGTH]; get_nick_truncate(m, nick, num); char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); line_info_add(prompt, timefrmt, nick, NULL, IN_MSG, 0, 0, str); const char *msg = "* Warning: Too many windows are open."; line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg); notify(prompt, error, NT_WNDALERT_1); } } }
ToxWindow new_chat(Tox *m, int32_t friendnum) { ToxWindow ret; memset(&ret, 0, sizeof(ret)); ret.active = true; ret.is_chat = true; ret.onKey = &chat_onKey; ret.onDraw = &chat_onDraw; ret.onInit = &chat_onInit; ret.onMessage = &chat_onMessage; ret.onConnectionChange = &chat_onConnectionChange; ret.onTypingChange = & chat_onTypingChange; ret.onGroupInvite = &chat_onGroupInvite; ret.onNickChange = &chat_onNickChange; ret.onStatusChange = &chat_onStatusChange; ret.onStatusMessageChange = &chat_onStatusMessageChange; ret.onAction = &chat_onAction; ret.onFileSendRequest = &chat_onFileSendRequest; ret.onFileControl = &chat_onFileControl; ret.onFileData = &chat_onFileData; #ifdef _AUDIO ret.onInvite = &chat_onInvite; ret.onRinging = &chat_onRinging; ret.onStarting = &chat_onStarting; ret.onEnding = &chat_onEnding; ret.onError = &chat_onError; ret.onStart = &chat_onStart; ret.onCancel = &chat_onCancel; ret.onReject = &chat_onReject; ret.onEnd = &chat_onEnd; ret.onRequestTimeout = &chat_onRequestTimeout; ret.onPeerTimeout = &chat_onPeerTimeout; ret.call_idx = -1; ret.device_selection[0] = ret.device_selection[1] = -1; #endif /* _AUDIO */ #ifdef _SOUND_NOTIFY ret.active_sound = -1; #endif /* _SOUND_NOTIFY */ char nick[TOX_MAX_NAME_LENGTH]; int n_len = get_nick_truncate(m, nick, friendnum); chat_set_window_name(&ret, nick, n_len); ChatContext *chatwin = calloc(1, sizeof(ChatContext)); StatusBar *stb = calloc(1, sizeof(StatusBar)); Help *help = calloc(1, sizeof(Help)); if (stb == NULL || chatwin == NULL || help == NULL) exit_toxic_err("failed in new_chat", FATALERR_MEMORY); ret.chatwin = chatwin; ret.stb = stb; ret.help = help; ret.num = friendnum; return ret; }