1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-26 22:13:26 +01:00

Merge pull request #113 from graboy/master

Fixed support for wide characters
This commit is contained in:
JFreegman 2014-03-30 17:22:41 -04:00
commit bd817e77f0
6 changed files with 485 additions and 476 deletions

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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];

View File

@ -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,32 @@ void draw_active_window(Tox *m)
wrefresh(a->window);
/* Handle input */
bool ltr;
#ifdef HAVE_WIDECHAR
if (wget_wch(stdscr, &ch) == ERR)
#else
if ((ch = getch()) == ERR)
#endif
int status = wget_wch(stdscr, &ch);
if (status == ERR)
return;
if (ch == T_KEY_NEXT || ch == T_KEY_PREV) {
if (status == OK)
ltr = iswprint(ch);
else /* if (status == KEY_CODE_YES) */
ltr = false;
#else
ch = getch();
if (ch == ERR)
return;
/* 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);
}
}