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); } }
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) { 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); } } }
BOOL sCommand_add_command_without_command_name(sCommand* self, sCommand* command, char* sname, int sline) { int i; for(i=1; i<command->mArgsNum; i++) { if(command->mArgsFlags[i] & XYZSH_ARGUMENT_ENV) { sBuf buf; memset(&buf, 0, sizeof(sBuf)); buf.mBuf = MALLOC(64); buf.mBuf[0] = 0; buf.mSize = 64; char* p = command->mArgs[i]; while(*p) { if(*p == PARSER_MAGIC_NUMBER_ENV) { p++; char buf2[128]; char* p2 = buf2; while(*p != PARSER_MAGIC_NUMBER_ENV) { *p2++ = *p++; } p++; *p2 = 0; int num = atoi(buf2) + self->mEnvsNum; snprintf(buf2, 128, "%d", num); add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV); add_str_to_buf(&buf, buf2, strlen(buf2)); add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV); } else { add_char_to_buf(&buf, *p++); } } if(!sCommand_add_arg(self, MANAGED buf.mBuf, command->mArgsFlags[i] & XYZSH_ARGUMENT_ENV, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED_HEAD, command->mArgsFlags[i] & XYZSH_ARGUMENT_GLOB, command->mArgsFlags[i] & XYZSH_ARGUMENT_OPTION, sname, sline)) { return FALSE; } } else { char* arg = STRDUP(command->mArgs[i]); if(!sCommand_add_arg(self, MANAGED arg, command->mArgsFlags[i] & XYZSH_ARGUMENT_ENV, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED, command->mArgsFlags[i] & XYZSH_ARGUMENT_QUOTED_HEAD, command->mArgsFlags[i] & XYZSH_ARGUMENT_GLOB, command->mArgsFlags[i] & XYZSH_ARGUMENT_OPTION, sname, sline)) { return FALSE; } } } for(i=0; i<command->mEnvsNum; i++) { sEnv* env = command->mEnvs + i; if(env->mFlags & ENV_FLAGS_KIND_ENV) { if(!sCommand_add_env(self, MANAGED STRDUP(env->mName), MANAGED STRDUP(env->mInitValue), MANAGED STRDUP(env->mKey), env->mFlags & ENV_FLAGS_KEY_ENV, env->mFlags & ENV_FLAGS_KEY_QUOTED_STRING, sname, sline)) { return FALSE; } } else { if(!sCommand_add_env_block(self, env->mBlock, env->mLineField, sname, sline)) { return FALSE; } } } for(i=0; i<command->mBlocksNum; i++) { sObject* block = block_clone_on_stack(command->mBlocks[i], T_BLOCK); if(!sCommand_add_block(self, block, sname, sline)) { return FALSE; } } for(i=0; i<command->mRedirectsNum; i++) { int flags = command->mRedirects[i]; if(flags & REDIRECT_ENV) { sBuf buf; memset(&buf, 0, sizeof(sBuf)); buf.mBuf = MALLOC(64); buf.mBuf[0] = 0; buf.mSize = 64; char* p = command->mRedirectsFileNames[i]; while(*p) { if(*p == PARSER_MAGIC_NUMBER_ENV) { p++; char buf2[128]; char* p2 = buf2; while(*p != PARSER_MAGIC_NUMBER_ENV) { *p2++ = *p++; } p++; *p2 = 0; int num = atoi(buf2) + self->mEnvsNum; snprintf(buf2, 128, "%d", num); add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV); add_str_to_buf(&buf, buf2, strlen(buf2)); add_char_to_buf(&buf, PARSER_MAGIC_NUMBER_ENV); } else { add_char_to_buf(&buf, *p++); } } if(!sCommand_add_redirect(self, MANAGED buf.mBuf, flags & REDIRECT_ENV, flags & REDIRECT_QUOTED, flags & REDIRECT_GLOB, flags & REDIRECT_KIND, sname, sline)) { return FALSE; } } else { if(!sCommand_add_redirect(self, MANAGED STRDUP(command->mRedirectsFileNames[i]), flags & REDIRECT_ENV, flags & REDIRECT_QUOTED, flags & REDIRECT_GLOB, flags & REDIRECT_KIND, sname, sline)) { return FALSE; } } } return TRUE; }