Пример #1
0
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = (ChatContext *) self->chatwin;
    StatusBar *statusbar = (StatusBar *) self->stb;

    int x, y, y2, x2;
    getyx(self->window, y, x);
    getmaxyx(self->window, y2, x2);
    /* BACKSPACE key: Remove one character from line */
    if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            ctx->line[--ctx->pos] = L'\0';

            if (x == 0)
                mvwdelch(self->window, y - 1, x2 - 1);
            else
                mvwdelch(self->window, y, x - 1);
        }
    } else
        /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR
        if (iswprint(key)) {
#else
        if (isprint(key)) {
#endif
            if (ctx->pos < (MAX_STR_SIZE-1)) {
                mvwaddstr(self->window, y, x, wc_to_char(key));
                ctx->line[ctx->pos++] = key;
                ctx->line[ctx->pos] = L'\0';
            }
        }
    /* RETURN key: Execute command or print line */
        else if (key == '\n') {
            uint8_t *line = wcs_to_char(ctx->line);
            line[ctx->pos+1] = '\0';
            wclear(ctx->linewin);
            wmove(self->window, y2 - CURS_Y_OFFSET, 0);
            wclrtobot(self->window);
            bool close_win = false;
            if (line[0] == '/') {
                if (close_win = !strncmp(line, "/close", strlen("/close"))) {
                    int f_num = self->num;
                    delwin(ctx->linewin);
                    delwin(statusbar->topline);
                    del_window(self);
                    disable_chatwin(f_num);
                } else if (!strncmp(line, "/me ", strlen("/me ")))
                    send_action(self, ctx, m, line + strlen("/me "));
                else if (!strncmp(line, "/help", strlen("/help")))
                    print_chat_help(ctx);
                else if (!strncmp(line, "/invite", strlen("/invite")))
                    chat_groupinvite(self, ctx, m, line + strlen("/invite "));
                else if(!strncmp(line, "/sendfile ", strlen("/sendfile ")))
                    chat_sendfile(self, ctx, m, line + strlen("/sendfile "));
                else
                    execute(ctx->history, self->prompt, m, line, ctx->pos);
            } else {
                /* make sure the string has at least non-space character */
                if (!string_is_empty(line)) {
                    uint8_t selfname[TOX_MAX_NAME_LENGTH];
                    tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH);

                    print_time(ctx->history);
                    wattron(ctx->history, COLOR_PAIR(GREEN));
                    wprintw(ctx->history, "%s: ", selfname);
                    wattroff(ctx->history, COLOR_PAIR(GREEN));

                    if (line[0] == '>') {
                        wattron(ctx->history, COLOR_PAIR(GREEN));
                        wprintw(ctx->history, "%s\n", line);
                        wattroff(ctx->history, COLOR_PAIR(GREEN));
                    } else
                        wprintw(ctx->history, "%s\n", line);

                    if (!statusbar->is_online
                            || tox_sendmessage(m, self->num, line, strlen(line) + 1) == 0) {
                        wattron(ctx->history, COLOR_PAIR(RED));
                        wprintw(ctx->history, " * Failed to send message.\n");
                        wattroff(ctx->history, COLOR_PAIR(RED));
                    }
                }
            }

            if (close_win) {
                free(ctx);
                free(statusbar);
            } else {
                ctx->line[0] = L'\0';
                ctx->pos = 0;
            }

            free(line);
        }
}

static void chat_onDraw(ToxWindow *self, Tox *m)
{
    curs_set(1);
    int x, y;
    getmaxyx(self->window, y, x);

    ChatContext *ctx = (ChatContext *) self->chatwin;

    /* Draw status bar */
    StatusBar *statusbar = (StatusBar *) self->stb;
    mvwhline(statusbar->topline, 1, 0, '-', x);
    wmove(statusbar->topline, 0, 0);

    /* Draw name, status and note in statusbar */
    if (statusbar->is_online) {
        char *status_text = "Unknown";
        int colour = WHITE;

        TOX_USERSTATUS status = statusbar->status;

        switch(status) {
        case TOX_USERSTATUS_NONE:
            status_text = "Online";
            colour = GREEN;
            break;
        case TOX_USERSTATUS_AWAY:
            status_text = "Away";
            colour = YELLOW;
            break;
        case TOX_USERSTATUS_BUSY:
            status_text = "Busy";
            colour = RED;
            break;
        }

        wattron(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, " %s ", self->name);
        wattroff(statusbar->topline, A_BOLD);
        wattron(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
        wprintw(statusbar->topline, "[%s]", status_text);
        wattroff(statusbar->topline, COLOR_PAIR(colour) | A_BOLD);
    } else {
        wattron(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, " %s ", self->name);
        wattroff(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, "[Offline]");
    }

    /* Reset statusbar->statusmsg on window resize */
    if (x != self->x) {
        uint8_t statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH] = {'\0'};
        tox_copy_statusmessage(m, self->num, statusmsg, TOX_MAX_STATUSMESSAGE_LENGTH);
        snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
        statusbar->statusmsg_len = tox_get_statusmessage_size(m, self->num);
    }

    self->x = x;

    /* Truncate note if it doesn't fit in statusbar */
    uint16_t maxlen = x - getcurx(statusbar->topline) - 6;
    if (statusbar->statusmsg_len > maxlen) {
        statusbar->statusmsg[maxlen] = '\0';
        statusbar->statusmsg_len = maxlen;
    }

    if (statusbar->statusmsg[0]) {
        wattron(statusbar->topline, A_BOLD);
        wprintw(statusbar->topline, " | %s | ", statusbar->statusmsg);
        wattroff(statusbar->topline, A_BOLD);
    }

    wprintw(statusbar->topline, "\n");
    mvwhline(ctx->linewin, 0, 0, '_', x);
    wrefresh(self->window);
}
Пример #2
0
static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = (ChatContext *) self->chatwin;
    struct tm *timeinfo = get_time();

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

    /* BACKSPACE key: Remove one character from line */
    if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            ctx->line[--ctx->pos] = L'\0';

            if (x == 0)
                mvwdelch(self->window, y - 1, x2 - 1);
            else
                mvwdelch(self->window, y, x - 1);
        }
    } else 
    /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR
    if (iswprint(key)) {
#else
    if (isprint(key)) {
#endif
        if (ctx->pos < (MAX_STR_SIZE-1)) {
            mvwaddstr(self->window, y, x, wc_to_char(key));
            ctx->line[ctx->pos++] = key;
            ctx->line[ctx->pos] = L'\0';
        }
    }

    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        uint8_t *line = wcs_to_char(ctx->line);
        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);
        bool close_win = false;

        if (line[0] == '/') {
            if (close_win = strncmp(line, "/close", strlen("/close")) == 0) {
                set_active_window(0);
                int groupnum = self->num;
                delwin(ctx->linewin);
                del_window(self);
                close_groupchatwin(m, groupnum);
            } else if (strncmp(line, "/help", strlen("/help")) == 0)
                print_groupchat_help(ctx);
              else
                execute(ctx->history, self->prompt, m, line, ctx->pos);
        } else {
            /* make sure the string has at least non-space character */
            if (!string_is_empty(line)) {
                // uint8_t selfname[TOX_MAX_NAME_LENGTH];
                // tox_getselfname(m, selfname, TOX_MAX_NAME_LENGTH);

                // wattron(ctx->history, COLOR_PAIR(CYAN));
                // wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
                // wattroff(ctx->history, COLOR_PAIR(CYAN));
                // wattron(ctx->history, COLOR_PAIR(GREEN));
                // wprintw(ctx->history, "%s: ", selfname);
                // wattroff(ctx->history, COLOR_PAIR(GREEN));
                // wprintw(ctx->history, "%s\n", line);

                if (tox_group_message_send(m, self->num, line, strlen(line) + 1) == -1) {
                    wattron(ctx->history, COLOR_PAIR(RED));
                    wprintw(ctx->history, " * Failed to send message.\n");
                    wattroff(ctx->history, COLOR_PAIR(RED));
                }
            }
        }

        if (close_win)
            free(ctx);
        else {
            ctx->line[0] = L'\0';
            ctx->pos = 0;
        }

        free(line);
    }
}

static void groupchat_onDraw(ToxWindow *self, Tox *m)
{
    curs_set(1);
    int x, y;
    getmaxyx(self->window, y, x);
    ChatContext *ctx = (ChatContext *) self->chatwin;
    mvwhline(ctx->linewin, 0, 0, '_', x);
    wrefresh(self->window);
}
Пример #3
0
Файл: chat.c Проект: gs93/toxic
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = (ChatContext *) self->x;
    struct tm *timeinfo = get_time();

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

    /* Add printable chars to buffer and print on input space */
#if HAVE_WIDECHAR
    if (iswprint(key)) {
#else
    if (isprint(key)) {
#endif
        if (ctx->pos != sizeof(ctx->line) - 1) {
            mvwaddstr(self->window, y, x, wc_to_char(key));
            ctx->line[ctx->pos++] = key;
            ctx->line[ctx->pos] = L'\0';
        }
    }

    /* BACKSPACE key: Remove one character from line */
    else if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            ctx->line[--ctx->pos] = L'\0';

            if (x == 0)
                mvwdelch(self->window, y - 1, x2 - 1);
            else
                mvwdelch(self->window, y, x - 1);
        }
    }

    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        char *line = wcs_to_char(ctx->line);
        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);

        if (line[0] == '/')
            execute(self, ctx, m, line);
        else {
            /* make sure the string has at least non-space character */
            if (!string_is_empty(line)) {
                uint8_t selfname[TOX_MAX_NAME_LENGTH];
                tox_getselfname(m, selfname, sizeof(selfname));

                wattron(ctx->history, COLOR_PAIR(2));
                wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
                wattroff(ctx->history, COLOR_PAIR(2));
                wattron(ctx->history, COLOR_PAIR(1));
                wprintw(ctx->history, "%s: ", selfname);
                wattroff(ctx->history, COLOR_PAIR(1));
                wprintw(ctx->history, "%s\n", line);

                if (tox_sendmessage(m, ctx->friendnum, (uint8_t *) line, strlen(line) + 1) == 0) {
                    wattron(ctx->history, COLOR_PAIR(3));
                    wprintw(ctx->history, " * Failed to send message.\n");
                    wattroff(ctx->history, COLOR_PAIR(3));
                }
            }
        }

        ctx->line[0] = L'\0';
        ctx->pos = 0;
        free(line);
    }
}

void execute(ToxWindow *self, ChatContext *ctx, Tox *m, char *cmd)
{
    if (!strcmp(cmd, "/clear") || !strcmp(cmd, "/c")) {
        wclear(self->window);
        wclear(ctx->history);
        int x, y;
        getmaxyx(self->window, y, x);
        (void) x;
        wmove(self->window, y - CURS_Y_OFFSET, 0);
    }

    else if (!strcmp(cmd, "/help") || !strcmp(cmd, "/h"))
        print_help(ctx);

    else if (!strcmp(cmd, "/quit") || !strcmp(cmd, "/exit") || !strcmp(cmd, "/q")) {
        endwin();
        exit(0);
    }

    else if (!strncmp(cmd, "/me ", strlen("/me "))) {
        struct tm *timeinfo = get_time();
        char *action = strchr(cmd, ' ');

        if (action == NULL) {
            wprintw(self->window, "Invalid syntax.\n");
            return;
        }

        action++;

        wattron(ctx->history, COLOR_PAIR(2));
        wprintw(ctx->history, "[%02d:%02d:%02d] ", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
        wattroff(ctx->history, COLOR_PAIR(2));

        uint8_t selfname[TOX_MAX_NAME_LENGTH];
        int len = tox_getselfname(m, selfname, sizeof(selfname));
        char msg[MAX_STR_SIZE - len - 4];
        snprintf(msg, sizeof(msg), "* %s %s\n", (uint8_t *) selfname, action);

        wattron(ctx->history, COLOR_PAIR(5));
        wprintw(ctx->history, msg);
        wattroff(ctx->history, COLOR_PAIR(5));

        if (tox_sendaction(m, ctx->friendnum, (uint8_t *) msg, strlen(msg) + 1) < 0) {
            wattron(ctx->history, COLOR_PAIR(3));
            wprintw(ctx->history, " * Failed to send action\n");
            wattroff(ctx->history, COLOR_PAIR(3));
        }
    }

    else if (!strncmp(cmd, "/status ", strlen("/status "))) {
        char *status = strchr(cmd, ' ');
        char *msg;
        char *status_text;

        if (status == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        status++;
        TOX_USERSTATUS status_kind;

        if (!strncmp(status, "online", strlen("online"))) {
            status_kind = TOX_USERSTATUS_NONE;
            status_text = "ONLINE";
        }

        else if (!strncmp(status, "away", strlen("away"))) {
            status_kind = TOX_USERSTATUS_AWAY;
            status_text = "AWAY";
        }

        else if (!strncmp(status, "busy", strlen("busy"))) {
            status_kind = TOX_USERSTATUS_BUSY;
            status_text = "BUSY";
        }

        else {
            wprintw(ctx->history, "Invalid status.\n");
            return;
        }

        msg = strchr(status, ' ');

        if (msg == NULL) {
            tox_set_userstatus(m, status_kind);
            wprintw(ctx->history, "Status set to: %s\n", status_text);
        } else {
            msg++;
            tox_set_userstatus(m, status_kind);
            tox_set_statusmessage(m, ( uint8_t *) msg, strlen(msg) + 1);
            wprintw(ctx->history, "Status set to: %s, %s\n", status_text, msg);
        }
    }

    else if (!strncmp(cmd, "/nick ", strlen("/nick "))) {
        char *nick;
        nick = strchr(cmd, ' ');

        if (nick == NULL) {
            wprintw(ctx->history, "Invalid syntax.\n");
            return;
        }

        nick++;
        tox_setname(m, (uint8_t *) nick, strlen(nick) + 1);
        wprintw(ctx->history, "Nickname set to: %s\n", nick);
    }

    else if (!strcmp(cmd, "/myid")) {
        char id[TOX_FRIEND_ADDRESS_SIZE * 2 + 1] = {0};
        int i;
        uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
        tox_getaddress(m, address);

        for (i = 0; i < TOX_FRIEND_ADDRESS_SIZE; i++) {
            char xx[3];
            snprintf(xx, sizeof(xx), "%02X",  address[i] & 0xff);
            strcat(id, xx);
        }

        wprintw(ctx->history, "%s\n", id);
    }

    else if (strcmp(cmd, "/close") == 0) {
        int f_num = ctx->friendnum;
        delwin(ctx->linewin);
        del_window(self);
        disable_chatwin(f_num);
    }

    else
        wprintw(ctx->history, "Invalid command.\n");
}

static void chat_onDraw(ToxWindow *self, Tox *m)
{
    curs_set(1);
    int x, y;
    getmaxyx(self->window, y, x);
    (void) y;
    ChatContext *ctx = (ChatContext *) self->x;
    mvwhline(ctx->linewin, 0, 0, '_', x);
    wrefresh(self->window);
}