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(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE); if (diff != -1) { if (x + diff > x2 - 1) { wmove(self->window, y, x + diff); ctx->start += diff; } else { wmove(self->window, y, x + diff); } } else { beep(); } } else { beep(); } } else if (key == '\n') { rm_trailing_spaces_buf(ctx); 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_info_add(self, NULL, NULL, NULL, line, PROMPT, 0, 0); execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE); wclear(ctx->linewin); wmove(self->window, y2 - CURS_Y_OFFSET, 0); reset_buf(ctx); } }
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); } }
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); } }
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) { ChatContext *ctx = self->chatwin; StatusBar *statusbar = self->stb; int x, y, y2, x2; getyx(self->window, y, x); getmaxyx(self->window, y2, x2); if (x2 <= 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); if (ctx->line[0] != '/' && !ctx->self_is_typing && statusbar->is_online) set_self_typingstatus(self, m, 1); return; } if (line_info_onKey(self, key)) return; input_handle(self, key, x, y, x2, y2); if (key == '\t' && ctx->len > 1 && ctx->line[0] == '/') { /* TAB key: auto-complete */ int diff = -1; if (wcsncmp(ctx->line, L"/sendfile \"", wcslen(L"/sendfile \"")) == 0) { diff = dir_match(self, m, ctx->line); } else { diff = complete_line(self, chat_cmd_list, AC_NUM_CHAT_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 { notify(self, error, 0); } } 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) { kill_chat_window(self); return; } 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)) { char selfname[TOX_MAX_NAME_LENGTH]; uint16_t len = tox_get_self_name(m, (uint8_t *) selfname); selfname[len] = '\0'; char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); line_info_add(self, timefrmt, selfname, NULL, OUT_MSG, 0, 0, line); if (!statusbar->is_online || tox_send_message(m, self->num, (uint8_t *) line, strlen(line)) == 0) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to send message."); } else { write_to_log(line, selfname, ctx->log, false); } } wclear(ctx->linewin); wmove(self->window, y2 - CURS_Y_OFFSET, 0); reset_buf(ctx); } if (ctx->len <= 0 && ctx->self_is_typing) set_self_typingstatus(self, m, 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 = -1; if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) diff = dir_match(self, m, ctx->line, L"/avatar"); else if (wcsncmp(ctx->line, L"/status ", wcslen(L"/status ")) == 0){ const char status_cmd_list[3][8] = { {"online"}, {"away"}, {"busy"}, }; diff = complete_line(self, status_cmd_list, 3, 8); } else diff = complete_line(self, glob_cmd_list, AC_NUM_GLOB_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 == '\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); } }