Exemplo n.º 1
0
static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int peernum, const char *action,
                                    uint16_t len)
{
    if (self->num != groupnum)
        return;

    ChatContext *ctx = self->chatwin;

    char nick[TOX_MAX_NAME_LENGTH];
    get_group_nick_truncate(m, nick, peernum, groupnum);

    char selfnick[TOX_MAX_NAME_LENGTH];
    tox_self_get_name(m, (uint8_t *) selfnick);

    size_t n_len = tox_self_get_name_size(m);
    selfnick[n_len] = '\0';

    if (strcasestr(action, selfnick)) {
        sound_notify(self, generic_message, NT_WNDALERT_0, NULL);

        if (self->active_box != -1)
            box_silent_notify2(self, NT_NOFOCUS, self->active_box, "* %s %s", nick, action );
        else
            box_silent_notify(self, NT_NOFOCUS, &self->active_box, self->name, "* %s %s", nick, action);
    }
    else {
        sound_notify(self, silent, NT_WNDALERT_1, NULL);
    }

    char timefrmt[TIME_STR_SIZE];
    get_time_str(timefrmt, sizeof(timefrmt));

    line_info_add(self, timefrmt, nick, NULL, IN_ACTION, 0, 0, "%s", action);
    write_to_log(action, nick, ctx->log, true);
}
Exemplo n.º 2
0
int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indicator, const char* title, const char* format, ...)
{
    if (notifications_are_disabled(flags)) {
        tab_notify(self, flags);
        return -1;
    }

#ifdef BOX_NOTIFY

    int id = sound_notify(self, notif, flags, id_indicator);

    control_lock();

#ifdef SOUND_NOTIFY
    if (id == -1) { /* Could not play */

        for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].active; id ++);
        if ( id == ACTIVE_NOTIFS_MAX ) {
            control_unlock();
            return -1; /* Full */
        }

        actives[id].active = 1;
        actives[id].id_indicator = id_indicator;
        if (id_indicator) *id_indicator = id;
    }
#else
    if (id == -1)
        return -1;
#endif    /* SOUND_NOTIFY */

    snprintf(actives[id].title, sizeof(actives[id].title), "%s", title);
    if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");

    va_list __ARGS__; va_start (__ARGS__, format);
    vsnprintf (actives[id].messages[0], MAX_BOX_MSG_LEN, format, __ARGS__);
    va_end (__ARGS__);

    if (strlen(actives[id].messages[0]) > MAX_BOX_MSG_LEN - 3)
        strcpy(actives[id].messages[0] + MAX_BOX_MSG_LEN - 3, "...");

    actives[id].box = notify_notification_new(actives[id].title, actives[id].messages[0], NULL);
    actives[id].size++;
    actives[id].n_timeout = get_unix_time() + Control.notif_timeout / 1000;

    notify_notification_set_timeout(actives[id].box, Control.notif_timeout);
    notify_notification_set_app_name(actives[id].box, "toxic");
    /*notify_notification_add_action(actives[id].box, "lel", "default", m_notify_action, self, NULL);*/
    notify_notification_show(actives[id].box, NULL);

    control_unlock();
    return id;
#else
    return sound_notify(self, notif, flags, id_indicator);
#endif   /* BOX_NOTIFY */
}
Exemplo n.º 3
0
int box_notify(ToxWindow* self, Notification notif, uint64_t flags, int* id_indicator, char* title, const char* format, ...)
{
    if ((flags & NT_RESTOL && Control.cooldown > time(NULL)) ||
       ((flags & NT_NOFOCUS && Control.this_window == get_focused_window_id()) ))
        return -1;
        
#ifdef _BOX_NOTIFY
    
    int id = sound_notify(self, notif, flags, id_indicator);
    
    control_lock();
    
#ifdef _SOUND_NOTIFY
    if (id == -1) { /* Could not play */
        
        for (id = 0; id < ACTIVE_NOTIFS_MAX && actives[id].active; id ++);
        if ( id == ACTIVE_NOTIFS_MAX ) {
            control_unlock();
            return -1; /* Full */
        }
        
        actives[id].active = 1;    
        actives[id].id_indicator = id_indicator;
        if (id_indicator) *id_indicator = id;
    }
#endif
        
    strncpy(actives[id].title, title, 24);
    if (strlen(title) > 23) strcpy(actives[id].title + 20, "...");

    va_list __ARGS__; va_start (__ARGS__, format);
    vsnprintf (actives[id].messages[0], 127, format, __ARGS__);
    va_end (__ARGS__);
    
    if (strlen(actives[id].messages[0]) > 124) 
        strcpy(actives[id].messages[0] + 124, "...");
    
    actives[id].box = notify_notification_new(actives[id].title, actives[id].messages[0], NULL);
    actives[id].size ++;
    actives[id].n_timeout = time(NULL) + Control.notif_timeout / 1000;
    
    notify_notification_set_timeout(actives[id].box, Control.notif_timeout);
    notify_notification_set_app_name(actives[id].box, "toxic");
    /*notify_notification_add_action(actives[id].box, "lel", "default", m_notify_action, self, NULL);*/
    notify_notification_show(actives[id].box, NULL);
    
    control_unlock();
    return id;
#else
    return sound_notify(self, notif, flags, id_indicator);
#endif
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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);
        }
    }
}
Exemplo n.º 7
0
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);
        }
    }
}
Exemplo n.º 8
0
static void groupchat_onGroupMessage(ToxWindow *self, Tox *m, int groupnum, int peernum,
                                     const char *msg, uint16_t len)
{
    if (self->num != groupnum)
        return;

    ChatContext *ctx = self->chatwin;

    char nick[TOX_MAX_NAME_LENGTH];
    get_group_nick_truncate(m, nick, peernum, groupnum);

    char selfnick[TOX_MAX_NAME_LENGTH];
    tox_self_get_name(m, (uint8_t *) selfnick);

    size_t sn_len = tox_self_get_name_size(m);
    selfnick[sn_len] = '\0';

    int nick_clr = strcmp(nick, selfnick) == 0 ? GREEN : CYAN;

    /* Only play sound if mentioned by someone else */
    if (strcasestr(msg, selfnick) && strcmp(selfnick, nick)) {
        sound_notify(self, generic_message, NT_WNDALERT_0, NULL);

        if (self->active_box != -1)
            box_silent_notify2(self, NT_NOFOCUS, self->active_box, "%s %s", nick, msg);
        else
            box_silent_notify(self, NT_NOFOCUS, &self->active_box, self->name, "%s %s", nick, msg);

        nick_clr = RED;
    }
    else {
        sound_notify(self, silent, NT_WNDALERT_1, NULL);
    }

    char timefrmt[TIME_STR_SIZE];
    get_time_str(timefrmt, sizeof(timefrmt));

    line_info_add(self, timefrmt, nick, NULL, IN_MSG, 0, nick_clr, "%s", msg);
    write_to_log(msg, nick, ctx->log, false);
}
Exemplo n.º 9
0
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);
        }
    }
}
Exemplo n.º 10
0
void do_file_senders(Tox *m)
{
    int i;

    for (i = 0; i < max_file_senders_index; ++i) {
        if (!file_senders[i].active)
            continue;

        if (file_senders[i].queue_pos > 0) {
            --file_senders[i].queue_pos;
            continue;
        }

        ToxWindow *self = file_senders[i].toxwin;
        char *filename = file_senders[i].filename;
        int filenum = file_senders[i].filenum;
        int32_t friendnum = file_senders[i].friendnum;

        /* kill file transfer if chatwindow is closed */
        if (self->chatwin == NULL) {
            close_file_sender(self, m, i, NULL, TOX_FILECONTROL_KILL, filenum, friendnum);
            continue;
        }

        /* If file transfer has timed out kill transfer and send kill control */
        if (timed_out(file_senders[i].timestamp, get_unix_time(), TIMEOUT_FILESENDER)) {
            char msg[MAX_STR_SIZE];
            snprintf(msg, sizeof(msg), "File transfer for '%s' timed out.", filename);
            close_file_sender(self, m, i, msg, TOX_FILECONTROL_KILL, filenum, friendnum);
            sound_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, NULL);
            
            if (self->active_box != -1)
                box_notify2(self, error, NT_NOFOCUS | NT_WNDALERT_2, self->active_box, "%s", msg);
            else
                box_notify(self, error, NT_NOFOCUS | NT_WNDALERT_2, &self->active_box, self->name, "%s", msg);
            continue;
        }

        send_file_data(self, m, i, friendnum, filenum, filename);
        file_senders[i].queue_pos = num_active_file_senders - 1;
    }
}
Exemplo n.º 11
0
static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length)
{
    ChatContext *ctx = self->chatwin;

    char timefrmt[TIME_STR_SIZE];
    get_time_str(timefrmt, sizeof(timefrmt));

    line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data);
    write_to_log("Friend request with the message '%s'", "", ctx->log, true);

    int n = add_friend_request(key, data);

    if (n == -1) {
        const char *errmsg = "Friend request queue is full. Discarding request.";
        line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg);
        return;
    }

    line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Type \"/accept %d\" or \"/decline %d\"", n, n);
    sound_notify(self, generic_message, NT_WNDALERT_1 | NT_NOTIFWND, NULL);
}
Exemplo n.º 12
0
/* copies history item at hst_pos to line. Sets pos and len to the len of the history item.
   hst_pos is decremented or incremented depending on key_dir.

   resets line if at end of history */
void fetch_hist_item(ChatContext *ctx, int key_dir)
{
    if (key_dir == KEY_UP) {
        if (--ctx->hst_pos < 0) {
            ctx->hst_pos = 0;
            sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
        }
    } else {
        if (++ctx->hst_pos >= ctx->hst_tot) {
            ctx->hst_pos = ctx->hst_tot;
            reset_buf(ctx);
            return;
        }
    }

    const wchar_t *hst_line = ctx->ln_history[ctx->hst_pos];
    size_t h_len = wcslen(hst_line);

    wmemcpy(ctx->line, hst_line, h_len + 1);
    ctx->pos = h_len;
    ctx->len = h_len;
}
Exemplo n.º 13
0
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);
        }
    }
}
Exemplo n.º 14
0
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    if (x2 <= 0)
        return;

    /* ignore non-menu related input if active */
    if (self->help->active) {
        help_onKey(self, key);
        return;
    }

    if (ltr) {    /* char is printable */
        input_new_char(self, key, x, y, x2, y2);
        return;
    }

    if (line_info_onKey(self, key))
        return;

    input_handle(self, key, x, y, x2, y2);

    if (key == '\t') {    /* TAB key: auto-completes command */
        if (ctx->len > 1 && ctx->line[0] == '/') {
            int diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);

            if (diff != -1) {
                if (x + diff > x2 - 1) {
                    int wlen = wcswidth(ctx->line, sizeof(ctx->line));
                    ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
                }
            } else {
                sound_notify(self, error, 0, NULL);
            }
        } else {
            sound_notify(self, error, 0, NULL);
        }
    } else if (key == '\n') {
        rm_trailing_spaces_buf(ctx);

        char line[MAX_STR_SIZE] = {0};

        if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        if (!string_is_empty(line))
            add_line_to_hist(ctx);

        line_info_add(self, NULL, NULL, NULL, PROMPT, 0, 0, "%s", line);
        execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);

        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        reset_buf(ctx);
    }
}
Exemplo n.º 15
0
static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{

    if (self->help->active) {
        help_onKey(self, key);
        return;
    }

    if (key == 'h') {
        help_init_menu(self);
        return;
    }

    if (!blocklist_view && !Friends.num_friends && (key != KEY_RIGHT && key != KEY_LEFT))
        return;

    if (blocklist_view && !Blocked.num_blocked && (key != KEY_RIGHT && key != KEY_LEFT))
        return;

    int f = 0;

    if (blocklist_view == 1 && Blocked.num_blocked)
        f = Blocked.index[Blocked.num_selected];
    else if (Friends.num_friends)
        f = Friends.index[Friends.num_selected];

    /* lock screen and force decision on deletion popup */
    if (PendingDelete.active) {
        if (key == 'y' || key == 'n')
            del_friend_deactivate(self, m, key);

        return;
    }

    if (key == ltr)
        return;

    switch (key) {
        case '\n':
            if (blocklist_view)
                break;

            /* Jump to chat window if already open */
            if (Friends.list[f].chatwin != -1) {
                set_active_window(Friends.list[f].chatwin);
            } else if (get_num_active_windows() < MAX_WINDOWS_NUM) {
                Friends.list[f].chatwin = add_window(m, new_chat(m, Friends.list[f].num));
                set_active_window(Friends.list[f].chatwin);
            } else {
                const char *msg = "* Warning: Too many windows are open.";
                line_info_add(prompt, NULL, NULL, NULL, SYS_MSG, 0, RED, msg);
                sound_notify(prompt, notif_error, NT_WNDALERT_1, NULL);
            }

            break;

        case KEY_DC:
            del_friend_activate(self, m, f);
            break;

        case 'b':
            if (!blocklist_view)
                block_friend(m, f);
            else
                unblock_friend(m, f);
            break;

        case KEY_RIGHT:
        case KEY_LEFT:
            blocklist_view ^= 1;
            break;

        default:
            if (blocklist_view == 0)
                select_friend(self, key, &Friends.num_selected, Friends.num_friends);
            else
                select_friend(self, key, &Blocked.num_selected, Blocked.num_blocked);
            break;
    }
}
Exemplo n.º 16
0
static void line_info_scroll_up(struct history *hst)
{
    if (hst->line_start->prev)
        hst->line_start = hst->line_start->prev;
    else sound_notify(NULL, error, NT_ALWAYS, NULL);
}
Exemplo n.º 17
0
static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);

    if (x2 <= 0 || y2 <= 0)
        return;

    if (self->help->active) {
        help_onKey(self, key);
        return;
    }

    if (ltr) {    /* char is printable */
        input_new_char(self, key, x, y, x2, y2);
        return;
    }

    if (line_info_onKey(self, key))
        return;

    if (input_handle(self, key, x, y, x2, y2))
        return;

    if (key == '\t') {  /* TAB key: auto-completes peer name or command */
        if (ctx->len > 0) {
            int diff;

            /* TODO: make this not suck */
            if (ctx->line[0] != L'/' || wcscmp(ctx->line, L"/me") == 0) {
                diff = complete_line(self, groupchats[self->num].peer_names, groupchats[self->num].num_peers,
                                     TOX_MAX_NAME_LENGTH);
            } else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) {
                diff = dir_match(self, m, ctx->line, L"/avatar");
            } else {
                diff = complete_line(self, group_cmd_list, AC_NUM_GROUP_COMMANDS, MAX_CMDNAME_SIZE);
            }

            if (diff != -1) {
                if (x + diff > x2 - 1) {
                    int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
                    ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
                }
            } else {
                sound_notify(self, notif_error, 0, NULL);
            }
        } else {
            sound_notify(self, notif_error, 0, NULL);
        }
    } else if (key == user_settings->key_peer_list_down) {    /* Scroll peerlist up and down one position */
        int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;

        if (groupchats[self->num].side_pos < groupchats[self->num].num_peers - L)
            ++groupchats[self->num].side_pos;
    } else if (key == user_settings->key_peer_list_up) {
        if (groupchats[self->num].side_pos > 0)
            --groupchats[self->num].side_pos;
    } else if (key == '\n') {
        rm_trailing_spaces_buf(ctx);

        char line[MAX_STR_SIZE];

        if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
            memset(&line, 0, sizeof(line));

        if (!string_is_empty(line))
            add_line_to_hist(ctx);

        if (line[0] == '/') {
            if (strcmp(line, "/close") == 0) {
                close_groupchat(self, m, self->num);
                return;
            } else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
                send_group_action(self, ctx, m, line + strlen("/me "));
            } else {
                execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE);
            }
        } else if (!string_is_empty(line)) {
            if (tox_group_message_send(m, self->num, (uint8_t *) line, strlen(line)) == -1) {
                const char *errmsg = " * Failed to send message.";
                line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, errmsg);
            }
        }

        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        reset_buf(ctx);
    }
}
Exemplo n.º 18
0
static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnum, int peernum, uint8_t change)
{
    if (self->num != groupnum)
        return;

    if (groupnum > max_groupchat_index)
        return;

    groupchats[groupnum].num_peers = tox_group_number_peers(m, groupnum);
    int num_peers = groupchats[groupnum].num_peers;

    if (peernum > num_peers)
        return;

    /* get old peer name before updating name list */
    uint8_t oldpeername[TOX_MAX_NAME_LENGTH];

    if (change != TOX_CHAT_CHANGE_PEER_ADD) {
        memcpy(oldpeername, &groupchats[groupnum].oldpeer_names[peernum * TOX_MAX_NAME_LENGTH],
               sizeof(oldpeername));
        uint16_t old_n_len = groupchats[groupnum].oldpeer_name_lengths[peernum];
        oldpeername[old_n_len] = '\0';
    }

    /* Update name/len lists */
    uint8_t tmp_peerlist[num_peers][TOX_MAX_NAME_LENGTH];
    uint16_t tmp_peerlens[num_peers];

    if (tox_group_get_names(m, groupnum, tmp_peerlist, tmp_peerlens, num_peers) == -1) {
        memset(tmp_peerlist, 0, sizeof(tmp_peerlist));
        memset(tmp_peerlens, 0, sizeof(tmp_peerlens));
    }

    copy_peernames(groupnum, tmp_peerlist, tmp_peerlens, num_peers);

    /* get current peername then sort namelist */
    uint8_t peername[TOX_MAX_NAME_LENGTH];

    if (change != TOX_CHAT_CHANGE_PEER_DEL) {
        uint16_t n_len = groupchats[groupnum].peer_name_lengths[peernum];
        memcpy(peername, &groupchats[groupnum].peer_names[peernum * TOX_MAX_NAME_LENGTH], sizeof(peername));
        peername[n_len] = '\0';
    }

    qsort(groupchats[groupnum].peer_names, groupchats[groupnum].num_peers, TOX_MAX_NAME_LENGTH, qsort_strcasecmp_hlpr);

    ChatContext *ctx = self->chatwin;

    const char *event;
    char timefrmt[TIME_STR_SIZE];
    get_time_str(timefrmt, sizeof(timefrmt));

    switch (change) {
    case TOX_CHAT_CHANGE_PEER_ADD:
        if (!timed_out(groupchats[groupnum].start_time, GROUP_EVENT_WAIT))
            break;

        struct group_add_thrd *thrd = malloc(sizeof(struct group_add_thrd));
        thrd->m = m;
        thrd->peernum = peernum;
        thrd->groupnum = groupnum;
        thrd->self = self;
        thrd->timestamp = get_unix_time();

        if (pthread_attr_init(&thrd->attr) != 0) {
            free(thrd);
            return;
        }

        if (pthread_attr_setdetachstate(&thrd->attr, PTHREAD_CREATE_DETACHED) != 0) {
            pthread_attr_destroy(&thrd->attr);
            free(thrd);
            return;
        }

        if (pthread_create(&thrd->tid, &thrd->attr, group_add_wait, (void *) thrd) != 0) {
            pthread_attr_destroy(&thrd->attr);
            free(thrd);
            return;
        }

        break;

    case TOX_CHAT_CHANGE_PEER_DEL:
        event = "has left the room";
        line_info_add(self, timefrmt, (char *) oldpeername, NULL, DISCONNECTION, 0, RED, event);

        if (groupchats[self->num].side_pos > 0)
            --groupchats[self->num].side_pos;

        write_to_log(event, (char *) oldpeername, ctx->log, true);
        break;

    case TOX_CHAT_CHANGE_PEER_NAME:
        if (!timed_out(groupchats[self->num].start_time, GROUP_EVENT_WAIT))
            return;

        /* ignore initial name change (TODO: this is a bad way to do this) */
        if (strcmp((char *) oldpeername, DEFAULT_TOX_NAME) == 0)
            return;

        event = " is now known as ";
        line_info_add(self, timefrmt, (char *) oldpeername, (char *) peername, NAME_CHANGE, 0, 0, event);

        char tmp_event[TOXIC_MAX_NAME_LENGTH * 2 + 32];
        snprintf(tmp_event, sizeof(tmp_event), "is now known as %s", (char *) peername);
        write_to_log(tmp_event, (char *) oldpeername, ctx->log, true);
        break;
    }

    sound_notify(self, silent, NT_WNDALERT_2, NULL);
}
Exemplo n.º 19
0
static void line_info_scroll_down(struct history *hst)
{
    if (hst->line_start->next)
        hst->line_start = hst->line_start->next;
    else sound_notify(NULL, notif_error, NT_ALWAYS, NULL);
}