From cce7892d949cc061cecb72f5969a90878273105f Mon Sep 17 00:00:00 2001 From: Grayson MacKenzie Date: Sun, 30 Mar 2014 16:40:13 -0400 Subject: [PATCH] Fixed character support --- src/chat.c | 312 ++++++++++++++++++++-------------------- src/friendlist.c | 34 ++--- src/groupchat.c | 336 ++++++++++++++++++++++---------------------- src/prompt.c | 241 ++++++++++++++++--------------- src/toxic_windows.h | 10 +- src/windows.c | 24 +++- 6 files changed, 482 insertions(+), 475 deletions(-) diff --git a/src/chat.c b/src/chat.c index 539ec6b..be27afa 100644 --- a/src/chat.c +++ b/src/chat.c @@ -500,7 +500,7 @@ static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *acti } } -static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) +static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) { ChatContext *ctx = self->chatwin; StatusBar *statusbar = self->stb; @@ -510,7 +510,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) getmaxyx(self->window, y2, x2); int cur_len = 0; - if (key == T_KEY_ESC) { /* ESC key: Toggle history scroll mode */ + if (ltr && (key == T_KEY_ESC)) { /* ESC key: Toggle history scroll mode */ bool scroll = ctx->hst->scroll_mode ? false : true; line_info_toggle_scroll(self, scroll); } @@ -521,124 +521,8 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) return; } - if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */ - 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 || key == T_KEY_C_A) { /* HOME/C-a key: Move cursor to start of line */ - if (ctx->pos > 0) { - ctx->pos = 0; - wmove(self->window, y2 - CURS_Y_OFFSET, 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; - 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, MOVE_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, MOVE_DOWN); - 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 (ltr) { + /* 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); @@ -650,50 +534,164 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key) if (!ctx->self_is_typing && ctx->line[0] != '/') set_typingstatus(self, m, 1); - } - /* 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)); + } else { /* if (!ltr) */ - wclear(ctx->linewin); - wmove(self->window, y2 - CURS_Y_OFFSET, 0); + if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */ + 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 (!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 (strcmp(line, "/close") == 0) { - if (ctx->self_is_typing) - set_typingstatus(self, m, 0); - - kill_chat_window(self); - return; - } else if (strncmp(line, "/me ", strlen("/me ")) == 0) { - send_action(self, ctx, m, line + strlen("/me ")); + if (x == 0) + wmove(self->window, y-1, x2 - cur_len); + else + wmove(self->window, y, x - cur_len); } 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); - - uint8_t timefrmt[TIME_STR_SIZE]; - get_time_str(timefrmt); - - line_info_add(self, timefrmt, selfname, NULL, line, OUT_MSG, 0, 0); - - if (!statusbar->is_online || tox_send_message(m, self->num, line, strlen(line) + 1) == 0) { - uint8_t *errmsg = " * Failed to send message."; - line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED); - } else { - write_to_log(line, selfname, ctx->log, false); + beep(); } } - reset_buf(ctx->line, &ctx->pos, &ctx->len); + 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 || key == T_KEY_C_A) { /* HOME/C-a key: Move cursor to start of line */ + if (ctx->pos > 0) { + ctx->pos = 0; + wmove(self->window, y2 - CURS_Y_OFFSET, 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; + 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, MOVE_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, MOVE_DOWN); + 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(); + } + } + + /* 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); + + 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 (strcmp(line, "/close") == 0) { + if (ctx->self_is_typing) + set_typingstatus(self, m, 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)) { + uint8_t selfname[TOX_MAX_NAME_LENGTH]; + tox_get_self_name(m, selfname); + + uint8_t timefrmt[TIME_STR_SIZE]; + get_time_str(timefrmt); + + line_info_add(self, timefrmt, selfname, NULL, line, OUT_MSG, 0, 0); + + if (!statusbar->is_online || tox_send_message(m, self->num, line, strlen(line) + 1) == 0) { + uint8_t *errmsg = " * Failed to send message."; + line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED); + } else { + write_to_log(line, selfname, ctx->log, false); + } + } + + reset_buf(ctx->line, &ctx->pos, &ctx->len); + } } if (ctx->len <= 0 && ctx->self_is_typing) diff --git a/src/friendlist.c b/src/friendlist.c index df26897..df2ab7f 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -322,7 +322,7 @@ static void draw_popup(ToxWindow *self, Tox *m) wrefresh(self->popup); } -static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key) +static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) { if (num_friends == 0) return; @@ -337,23 +337,25 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key) return; } - if (key == '\n') { - /* Jump to chat window if already open */ - if (friends[f].chatwin != -1) { - set_active_window(friends[f].chatwin); - } else if (get_num_active_windows() < MAX_WINDOWS_NUM) { - friends[f].chatwin = add_window(m, new_chat(m, friends[f].num)); - set_active_window(friends[f].chatwin); - } else { - uint8_t *msg = "* Warning: Too many windows are open."; - line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); + if (key != ltr) { + if (key == '\n') { + /* Jump to chat window if already open */ + if (friends[f].chatwin != -1) { + set_active_window(friends[f].chatwin); + } else if (get_num_active_windows() < MAX_WINDOWS_NUM) { + friends[f].chatwin = add_window(m, new_chat(m, friends[f].num)); + set_active_window(friends[f].chatwin); + } else { + uint8_t *msg = "* Warning: Too many windows are open."; + line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED); - alert_window(prompt, WINDOW_ALERT_1, true); + alert_window(prompt, WINDOW_ALERT_1, true); + } + } else if (key == KEY_DC) { + del_friend_activate(self, m, f); + } else { + select_friend(self, m, key); } - } else if (key == KEY_DC) { - del_friend_activate(self, m, f); - } else { - select_friend(self, m, key); } } diff --git a/src/groupchat.c b/src/groupchat.c index e1c470f..106174b 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -325,7 +325,7 @@ static void send_group_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t } } -static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key) +static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) { ChatContext *ctx = self->chatwin; @@ -334,7 +334,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key) getmaxyx(self->window, y2, x2); int cur_len = 0; - if (key == T_KEY_ESC) { /* ESC key: Toggle history scroll mode */ + if (ltr && (key == T_KEY_ESC) ) { /* ESC key: Toggle history scroll mode */ bool scroll = ctx->hst->scroll_mode ? false : true; line_info_toggle_scroll(self, scroll); } @@ -345,143 +345,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key) return; } - 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 || key == T_KEY_C_A) { /* HOME/C-a key: Move cursor to start of line */ - if (ctx->pos > 0) { - ctx->pos = 0; - wmove(self->window, y2 - CURS_Y_OFFSET, 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; - 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, MOVE_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, MOVE_DOWN); - mv_curs_end(self->window, ctx->len, y2, x2); - } - - else if (key == '\t') { /* TAB key: completes peer name */ - if (ctx->len > 0) { - int diff; - - if ((ctx->line[0] != '/') || (ctx->line[1] == 'm' && ctx->line[2] == 'e')) - diff = complete_line(ctx->line, &ctx->pos, &ctx->len, groupchats[self->num].peer_names, - groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH); - else - diff = complete_line(ctx->line, &ctx->pos, &ctx->len, glob_cmd_list, AC_NUM_GLOB_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(); - } - } - - /* Scroll peerlist up and down one position if list overflows window */ - else if (key == KEY_NPAGE) { - 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 == KEY_PPAGE) { - if (groupchats[self->num].side_pos > 0) - --groupchats[self->num].side_pos; - } - - 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 (ltr) { 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); @@ -490,45 +354,177 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key) 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]; + } else { /* if (!ltr) */ - if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) - memset(&line, 0, sizeof(line)); + 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); - wclear(ctx->linewin); - wmove(self->window, y2 - CURS_Y_OFFSET, 0); - - - 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 (strcmp(line, "/close") == 0) { - close_groupchat(self, m, self->num); - return; - } else if (strcmp(line, "/help") == 0) { - if (strcmp(line, "help global") == 0) - execute(ctx->history, self, m, "/help", GLOBAL_COMMAND_MODE); + if (x == 0) + wmove(self->window, y-1, x2 - cur_len); else - print_groupchat_help(self); - - } else if (strncmp(line, "/me ", strlen("/me ")) == 0) { - send_group_action(self, ctx, m, line + strlen("/me ")); + wmove(self->window, y, x - cur_len); } else { - execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE); - } - } else if (!string_is_empty(line)) { - if (tox_group_message_send(m, self->num, line, strlen(line) + 1) == -1) { - uint8_t *errmsg = " * Failed to send message."; - line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED); + beep(); } } - reset_buf(ctx->line, &ctx->pos, &ctx->len); + 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 || key == T_KEY_C_A) { /* HOME/C-a key: Move cursor to start of line */ + if (ctx->pos > 0) { + ctx->pos = 0; + wmove(self->window, y2 - CURS_Y_OFFSET, 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; + 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, MOVE_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, MOVE_DOWN); + mv_curs_end(self->window, ctx->len, y2, x2); + } + + else if (key == '\t') { /* TAB key: completes peer name */ + if (ctx->len > 0) { + int diff; + + if ((ctx->line[0] != '/') || (ctx->line[1] == 'm' && ctx->line[2] == 'e')) + diff = complete_line(ctx->line, &ctx->pos, &ctx->len, groupchats[self->num].peer_names, + groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH); + else + diff = complete_line(ctx->line, &ctx->pos, &ctx->len, glob_cmd_list, AC_NUM_GLOB_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(); + } + } + + /* Scroll peerlist up and down one position if list overflows window */ + else if (key == KEY_NPAGE) { + 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 == KEY_PPAGE) { + if (groupchats[self->num].side_pos > 0) + --groupchats[self->num].side_pos; + } + + /* 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); + + + 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 (strcmp(line, "/close") == 0) { + close_groupchat(self, m, self->num); + return; + } else if (strcmp(line, "/help") == 0) { + if (strcmp(line, "help global") == 0) + execute(ctx->history, self, m, "/help", GLOBAL_COMMAND_MODE); + else + print_groupchat_help(self); + + } 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, line, strlen(line) + 1) == -1) { + uint8_t *errmsg = " * Failed to send message."; + line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED); + } + } + + reset_buf(ctx->line, &ctx->pos, &ctx->len); + } } } diff --git a/src/prompt.c b/src/prompt.c index 64c4817..eea1e21 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -119,7 +119,7 @@ static int add_friend_request(uint8_t *public_key) return -1; } -static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key) +static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) { ChatContext *ctx = self->chatwin; @@ -127,11 +127,14 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key) 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); - //} + /* TODO this is buggy */ + /* ESC key: Toggle history scroll mode */ + /* + if (key == T_KEY_ESC) { + 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) { @@ -139,127 +142,123 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t 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 (ltr) { 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}; + } else { /* if (!ltr) */ - if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) - memset(&line, 0, sizeof(line)); + /* 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(); + } + } - if (!string_is_empty(line)) - add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos); + 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(); + } + } - 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); + 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(); + } + } + + /* 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); + } } } diff --git a/src/toxic_windows.h b/src/toxic_windows.h index 58443e1..dffa46d 100644 --- a/src/toxic_windows.h +++ b/src/toxic_windows.h @@ -87,7 +87,7 @@ enum { MOVE_DOWN, }; -/* Fixes text color problem on some terminals. +/* Fixes text color problem on some terminals. Uncomment if necessary */ /* #define URXVT_FIX */ @@ -97,7 +97,7 @@ typedef struct PromptBuf PromptBuf; typedef struct ChatContext ChatContext; struct ToxWindow { - void(*onKey)(ToxWindow *, Tox *, wint_t); + void(*onKey)(ToxWindow *, Tox *, wint_t, bool); void(*onDraw)(ToxWindow *, Tox *); void(*onInit)(ToxWindow *, Tox *); void(*onFriendRequest)(ToxWindow *, Tox *, uint8_t *, uint8_t *, uint16_t); @@ -130,9 +130,9 @@ struct ToxWindow { void(*onEnd)(ToxWindow *, ToxAv *); void(*onRequestTimeout)(ToxWindow *, ToxAv *); void(*onPeerTimeout)(ToxWindow *, ToxAv *); - + #endif /* _SUPPORT_AUDIO */ - + char name[TOX_MAX_NAME_LENGTH]; int32_t num; /* corresponds to friendnumber in chat windows */ bool active; @@ -156,7 +156,7 @@ struct ToxWindow { /* statusbar info holder */ struct StatusBar { - WINDOW *topline; + WINDOW *topline; uint8_t statusmsg[TOX_MAX_STATUSMESSAGE_LENGTH]; uint16_t statusmsg_len; uint8_t nick[TOX_MAX_NAME_LENGTH]; diff --git a/src/windows.c b/src/windows.c index ad5f88e..e6d6dea 100644 --- a/src/windows.c +++ b/src/windows.c @@ -46,7 +46,7 @@ static int num_active_windows; void on_request(Tox *m, uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata) { int i; - + for (i = 0; i < MAX_WINDOWS_NUM; ++i) { if (windows[i].onFriendRequest != NULL) windows[i].onFriendRequest(&windows[i], m, public_key, data, length); @@ -394,18 +394,30 @@ void draw_active_window(Tox *m) wrefresh(a->window); /* Handle input */ + bool ltr; #ifdef HAVE_WIDECHAR - if (wget_wch(stdscr, &ch) == ERR) + int status = wget_wch(stdscr, &ch); + if (status == OK) + ltr = true; + else if (status == KEY_CODE_YES) + ltr = false; + else + return; #else - if ((ch = getch()) == ERR) -#endif + ch = getch(); + + if (ch == ERR) return; - if (ch == T_KEY_NEXT || ch == T_KEY_PREV) { + /* TODO verify if this works */ + ltr = isprint(ch); +#endif + + if (ltr && (ch == T_KEY_NEXT || ch == T_KEY_PREV) ) { set_next_window((int) ch); } else { pthread_mutex_lock(&Winthread.lock); - a->onKey(a, m, ch); + a->onKey(a, m, ch, ltr); pthread_mutex_unlock(&Winthread.lock); } }