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

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

    if (key == 0x107 || key == 0x8 || key == 0x7f) {  /* BACKSPACE key: Remove character behind pos */
        if (ctx->pos > 0) {
            cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
            del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);

            if (x == 0)
                wmove(self->window, y-1, x2 - cur_len);
            else
                wmove(self->window, y, x - cur_len);
        } else {
            beep();
        }
    }

    else if (key == KEY_DC) {      /* DEL key: Remove character at pos */
        if (ctx->pos != ctx->len)
            del_char_buf_frnt(ctx->line, &ctx->pos, &ctx->len);
        else
            beep();
    }

    else if (key == T_KEY_DISCARD) {    /* CTRL-U: Delete entire line behind pos */
        if (ctx->pos > 0) {
            discard_buf(ctx->line, &ctx->pos, &ctx->len);
            wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_KILL) {    /* CTRL-K: Delete entire line in front of pos */
        if (ctx->pos != ctx->len)
            kill_buf(ctx->line, &ctx->pos, &ctx->len);
        else
            beep();
    }

    else if (key == KEY_HOME) {    /* HOME key: Move cursor to beginning of line */
        if (ctx->pos > 0) {
            ctx->pos = 0;
            wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        }
    } 

    else if (key == KEY_END) {     /* END key: move cursor to end of line */
        if (ctx->pos != ctx->len) {
            ctx->pos = ctx->len;
            mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, (CHATBOX_HEIGHT-1)*x2)), y2, x2);
        }
    }

    else if (key == KEY_LEFT) {
        if (ctx->pos > 0) {
            --ctx->pos;
            cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));

            if (x == 0)
                wmove(self->window, y-1, x2 - cur_len);
            else
                wmove(self->window, y, x - cur_len);
        } else {
            beep();
        }
    } 

    else if (key == KEY_RIGHT) {
        if (ctx->pos < ctx->len) {
            cur_len = MAX(1, wcwidth(ctx->line[ctx->pos]));
            ++ctx->pos;

            if (x == x2-1)
                wmove(self->window, y+1, 0);
            else
                wmove(self->window, y, x + cur_len);
        } else {
            beep();
        }
    } 

    else if (key == KEY_UP) {    /* fetches previous item in history */
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, LN_HIST_MV_UP);
        mv_curs_end(self->window, ctx->len, y2, x2);
    }

    else if (key == KEY_DOWN) {    /* fetches next item in history */
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, LN_HIST_MV_DWN);
        mv_curs_end(self->window, ctx->len, y2, x2);
    }

    else if (key == '\t') {    /* TAB key: completes command */
        if (ctx->len > 1 && ctx->line[0] == '/') {
            int diff = complete_line(ctx->line, &ctx->pos, &ctx->len, chat_cmd_list, AC_NUM_CHAT_COMMANDS,
                                     MAX_CMDNAME_SIZE);

            if (diff != -1) {
                if (x + diff > x2 - 1) {
                    int ofst = (x + diff - 1) - (x2 - 1);
                    wmove(self->window, y+1, ofst);
                } else {
                    wmove(self->window, y, x+diff);
                }
            } else {
                beep();
            }
        } else {
            beep();
        }
    }

    else
#if HAVE_WIDECHAR
    if (iswprint(key))
#else
    if (isprint(key))
#endif
    {   /* prevents buffer overflows and strange behaviour when cursor goes past the window */
        if ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) {
            add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);

            if (x == x2-1)
                wmove(self->window, y+1, 0);
            else
                wmove(self->window, y, x + MAX(1, wcwidth(key)));
        }
    }
    /* RETURN key: Execute command or print line */
    else if (key == '\n') {
        uint8_t line[MAX_STR_SIZE];

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

        wclear(ctx->linewin);
        wmove(self->window, y2 - CURS_Y_OFFSET, 0);
        wclrtobot(self->window);
        bool close_win = false;

        if (!string_is_empty(line))
            add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);

        if (line[0] == '/') {
            if (close_win = !strcmp(line, "/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 ")) == 0)
                send_action(self, ctx, m, line + strlen("/me "));
              else
                execute(ctx->history, self, m, line, CHAT_COMMAND_MODE);
        } else if (!string_is_empty(line)) {
            uint8_t selfname[TOX_MAX_NAME_LENGTH];
            tox_get_self_name(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_send_message(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 {
            reset_buf(ctx->line, &ctx->pos, &ctx->len);
        }
    }
}
Beispiel #2
0
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    PromptBuf *prt = self->promptbuf;

    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 (prt->pos > 0) {
            del_char_buf_bck(prt->line, &prt->pos, &prt->len);
            wmove(self->window, y, x-1);    /* not necessary but fixes a display glitch */
            prt->scroll = false;
        } else {
            beep();
        }
    }

    else if (key == KEY_DC) {      /* DEL key: Remove character at pos */
        if (prt->pos != prt->len) {
            del_char_buf_frnt(prt->line, &prt->pos, &prt->len);
            prt->scroll = false;
        } else {
            beep();
        }
    }

    else if (key == T_KEY_DISCARD) {    /* CTRL-U: Delete entire line behind pos */
        if (prt->pos > 0) {
            wmove(self->window, prt->orig_y, X_OFST);
            wclrtobot(self->window);
            discard_buf(prt->line, &prt->pos, &prt->len);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_KILL) {    /* CTRL-K: Delete entire line in front of pos */
        if (prt->len != prt->pos)
            kill_buf(prt->line, &prt->pos, &prt->len);
        else
            beep();
    }

    else if (key == KEY_HOME || key == T_KEY_C_A) {  /* HOME/C-a key: Move cursor to start of line */
        if (prt->pos != 0)
            prt->pos = 0;
    }

    else if (key == KEY_END || key == T_KEY_C_E) {   /* END/C-e key: move cursor to end of line */
        if (prt->pos != prt->len)
            prt->pos = prt->len;
    }

    else if (key == KEY_LEFT) {
        if (prt->pos > 0)
            --prt->pos;
        else
            beep();
    } 

    else if (key == KEY_RIGHT) {
        if (prt->pos < prt->len)
            ++prt->pos;
        else 
            beep();
    } 

    else if (key == KEY_UP) {     /* fetches previous item in history */
        wmove(self->window, prt->orig_y, X_OFST);
        fetch_hist_item(prt->line, &prt->pos, &prt->len, prt->ln_history, prt->hst_tot,
                        &prt->hst_pos, LN_HIST_MV_UP);

        /* adjust line y origin appropriately when window scrolls down */
        if (prt->at_bottom && prt->len >= x2 - X_OFST) {
            int px2 = prt->len >= x2 ? x2 : x2 - X_OFST;
            int p_ofst = px2 != x2 ? 0 : X_OFST;

            if (px2 <= 0)
                return;

            int k = prt->orig_y + ((prt->len + p_ofst) / px2);

            if (k >= y2) {
                wprintw(self->window, "\n");
                --prt->orig_y;
            }
        }
    }

    else if (key == KEY_DOWN) {    /* fetches next item in history */
        wmove(self->window, prt->orig_y, X_OFST);
        fetch_hist_item(prt->line, &prt->pos, &prt->len, prt->ln_history, prt->hst_tot,
                        &prt->hst_pos, LN_HIST_MV_DWN);
    }

    else if (key == '\t') {    /* TAB key: completes command */
        if (prt->len > 1 && prt->line[0] == '/') {
            if (complete_line(prt->line, &prt->pos, &prt->len, glob_cmd_list, AC_NUM_GLOB_COMMANDS,
                              MAX_CMDNAME_SIZE) == -1) 
                beep();
        } else {
            beep();
        }
    }

    else
#if HAVE_WIDECHAR
    if (iswprint(key))
#else
    if (isprint(key))
#endif
    {
        if (prt->len < (MAX_STR_SIZE-1)) {
            add_char_to_buf(prt->line, &prt->pos, &prt->len, key);
            prt->scroll = true;
        }
    }
    /* RETURN key: execute command */
    else if (key == '\n') {
        wprintw(self->window, "\n");
        uint8_t line[MAX_STR_SIZE];

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

        if (!string_is_empty(line))
            add_line_to_hist(prt->line, prt->len, prt->ln_history, &prt->hst_tot, &prt->hst_pos);

        execute(self->window, self, m, line, GLOBAL_COMMAND_MODE);
        reset_buf(prt->line, &prt->pos, &prt->len);
    }
}
Beispiel #3
0
static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
{
    ChatContext *ctx = self->chatwin;

    int x, y, y2, x2;
    getyx(ctx->history, y, x);
    getmaxyx(ctx->history, y2, x2);

    /* this is buggy */
    //if (key == T_KEY_ESC) {   /* ESC key: Toggle history scroll mode */
    //    bool scroll = ctx->hst->scroll_mode ? false : true;
    //    line_info_toggle_scroll(self, scroll);
    //}

    /* If we're in scroll mode ignore rest of function */
    if (ctx->hst->scroll_mode) {
        line_info_onKey(self, key);
        return;
    }

    /* BACKSPACE key: Remove one character from line */
    if (key == 0x107 || key == 0x8 || key == 0x7f) {
        if (ctx->pos > 0) {
            del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);
            wmove(ctx->history, y, x-1);    /* not necessary but fixes a display glitch */
        } else {
            beep();
        }
    }

    else if (key == KEY_DC) {      /* DEL key: Remove character at pos */
        if (ctx->pos != ctx->len) {
            del_char_buf_frnt(ctx->line, &ctx->pos, &ctx->len);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_DISCARD) {    /* CTRL-U: Delete entire line behind pos */
        if (ctx->pos > 0) {
            wmove(ctx->history, ctx->orig_y, X_OFST);
            wclrtobot(ctx->history);
            discard_buf(ctx->line, &ctx->pos, &ctx->len);
        } else {
            beep();
        }
    }

    else if (key == T_KEY_KILL) {    /* CTRL-K: Delete entire line in front of pos */
        if (ctx->len != ctx->pos)
            kill_buf(ctx->line, &ctx->pos, &ctx->len);
        else
            beep();
    }

    else if (key == KEY_HOME || key == T_KEY_C_A) {  /* HOME/C-a key: Move cursor to start of line */
        if (ctx->pos != 0)
            ctx->pos = 0;
    }

    else if (key == KEY_END || key == T_KEY_C_E) {   /* END/C-e key: move cursor to end of line */
        if (ctx->pos != ctx->len)
            ctx->pos = ctx->len;
    }

    else if (key == KEY_LEFT) {
        if (ctx->pos > 0)
            --ctx->pos;
        else
            beep();
    } 

    else if (key == KEY_RIGHT) {
        if (ctx->pos < ctx->len)
            ++ctx->pos;
        else 
            beep();
    } 

    else if (key == KEY_UP) {     /* fetches previous item in history */
        wmove(ctx->history, ctx->orig_y, X_OFST);
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, MOVE_UP);

        /* adjust line y origin appropriately when window scrolls down */
        if (ctx->at_bottom && ctx->len >= x2 - X_OFST) {
            int px2 = ctx->len >= x2 ? x2 : x2 - X_OFST;
            int p_ofst = px2 != x2 ? 0 : X_OFST;

            if (px2 <= 0)
                return;

            int k = ctx->orig_y + ((ctx->len + p_ofst) / px2);

            if (k >= y2) {
                --ctx->orig_y;
            }
        }
    }

    else if (key == KEY_DOWN) {    /* fetches next item in history */
        wmove(ctx->history, ctx->orig_y, X_OFST);
        fetch_hist_item(ctx->line, &ctx->pos, &ctx->len, ctx->ln_history, ctx->hst_tot,
                        &ctx->hst_pos, MOVE_DOWN);
    }

    else if (key == '\t') {    /* TAB key: completes command */
        if (ctx->len > 1 && ctx->line[0] == '/') {
            if (complete_line(ctx->line, &ctx->pos, &ctx->len, glob_cmd_list, AC_NUM_GLOB_COMMANDS,
                              MAX_CMDNAME_SIZE) == -1) 
                beep();
        } else {
            beep();
        }
    }

    else
#if HAVE_WIDECHAR
    if (iswprint(key))
#else
    if (isprint(key))
#endif
    {
        if (ctx->len < (MAX_STR_SIZE-1)) {
            add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);
        }
    }
    /* RETURN key: execute command */
    else if (key == '\n') {
        wprintw(ctx->history, "\n");
        uint8_t 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, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);

        line_info_add(self, NULL, NULL, NULL, line, PROMPT, 0, 0);
        execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);
        reset_buf(ctx->line, &ctx->pos, &ctx->len);
    }
}