mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-23 02:03:02 +01:00
Fixed character support
This commit is contained in:
parent
1420618eb0
commit
cce7892d94
312
src/chat.c
312
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;
|
ChatContext *ctx = self->chatwin;
|
||||||
StatusBar *statusbar = self->stb;
|
StatusBar *statusbar = self->stb;
|
||||||
@ -510,7 +510,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
int cur_len = 0;
|
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;
|
bool scroll = ctx->hst->scroll_mode ? false : true;
|
||||||
line_info_toggle_scroll(self, scroll);
|
line_info_toggle_scroll(self, scroll);
|
||||||
}
|
}
|
||||||
@ -521,124 +521,8 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */
|
if (ltr) {
|
||||||
if (ctx->pos > 0) {
|
/* prevents buffer overflows and strange behaviour when cursor goes past the window */
|
||||||
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 ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) {
|
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);
|
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] != '/')
|
if (!ctx->self_is_typing && ctx->line[0] != '/')
|
||||||
set_typingstatus(self, m, 1);
|
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)
|
} else { /* if (!ltr) */
|
||||||
memset(&line, 0, sizeof(line));
|
|
||||||
|
|
||||||
wclear(ctx->linewin);
|
if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */
|
||||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
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))
|
if (x == 0)
|
||||||
add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);
|
wmove(self->window, y-1, x2 - cur_len);
|
||||||
|
else
|
||||||
if (line[0] == '/') {
|
wmove(self->window, y, x - cur_len);
|
||||||
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 {
|
} else {
|
||||||
execute(ctx->history, self, m, line, CHAT_COMMAND_MODE);
|
beep();
|
||||||
}
|
|
||||||
} 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);
|
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)
|
if (ctx->len <= 0 && ctx->self_is_typing)
|
||||||
|
@ -322,7 +322,7 @@ static void draw_popup(ToxWindow *self, Tox *m)
|
|||||||
wrefresh(self->popup);
|
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)
|
if (num_friends == 0)
|
||||||
return;
|
return;
|
||||||
@ -337,23 +337,25 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == '\n') {
|
if (key != ltr) {
|
||||||
/* Jump to chat window if already open */
|
if (key == '\n') {
|
||||||
if (friends[f].chatwin != -1) {
|
/* Jump to chat window if already open */
|
||||||
set_active_window(friends[f].chatwin);
|
if (friends[f].chatwin != -1) {
|
||||||
} else if (get_num_active_windows() < MAX_WINDOWS_NUM) {
|
set_active_window(friends[f].chatwin);
|
||||||
friends[f].chatwin = add_window(m, new_chat(m, friends[f].num));
|
} else if (get_num_active_windows() < MAX_WINDOWS_NUM) {
|
||||||
set_active_window(friends[f].chatwin);
|
friends[f].chatwin = add_window(m, new_chat(m, friends[f].num));
|
||||||
} else {
|
set_active_window(friends[f].chatwin);
|
||||||
uint8_t *msg = "* Warning: Too many windows are open.";
|
} else {
|
||||||
line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, RED);
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
336
src/groupchat.c
336
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;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
getmaxyx(self->window, y2, x2);
|
getmaxyx(self->window, y2, x2);
|
||||||
int cur_len = 0;
|
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;
|
bool scroll = ctx->hst->scroll_mode ? false : true;
|
||||||
line_info_toggle_scroll(self, scroll);
|
line_info_toggle_scroll(self, scroll);
|
||||||
}
|
}
|
||||||
@ -345,143 +345,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key: Remove character behind pos */
|
if (ltr) {
|
||||||
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 ( (ctx->len < MAX_STR_SIZE-1) && (ctx->len < (x2 * (CHATBOX_HEIGHT - 1)-1)) ) {
|
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);
|
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
|
else
|
||||||
wmove(self->window, y, x + MAX(1, wcwidth(key)));
|
wmove(self->window, y, x + MAX(1, wcwidth(key)));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* RETURN key: Execute command or print line */
|
} else { /* if (!ltr) */
|
||||||
else if (key == '\n') {
|
|
||||||
uint8_t line[MAX_STR_SIZE];
|
|
||||||
|
|
||||||
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
|
if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key: Remove character behind pos */
|
||||||
memset(&line, 0, sizeof(line));
|
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);
|
if (x == 0)
|
||||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
wmove(self->window, y-1, x2 - cur_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) {
|
|
||||||
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
|
else
|
||||||
print_groupchat_help(self);
|
wmove(self->window, y, x - cur_len);
|
||||||
|
|
||||||
} else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
|
|
||||||
send_group_action(self, ctx, m, line + strlen("/me "));
|
|
||||||
} else {
|
} else {
|
||||||
execute(ctx->history, self, m, line, GROUPCHAT_COMMAND_MODE);
|
beep();
|
||||||
}
|
|
||||||
} 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);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
241
src/prompt.c
241
src/prompt.c
@ -119,7 +119,7 @@ static int add_friend_request(uint8_t *public_key)
|
|||||||
return -1;
|
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;
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
@ -127,11 +127,14 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
getyx(ctx->history, y, x);
|
getyx(ctx->history, y, x);
|
||||||
getmaxyx(ctx->history, y2, x2);
|
getmaxyx(ctx->history, y2, x2);
|
||||||
|
|
||||||
/* this is buggy */
|
/* TODO this is buggy */
|
||||||
//if (key == T_KEY_ESC) { /* ESC key: Toggle history scroll mode */
|
/* ESC key: Toggle history scroll mode */
|
||||||
// bool scroll = ctx->hst->scroll_mode ? false : true;
|
/*
|
||||||
// line_info_toggle_scroll(self, scroll);
|
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 we're in scroll mode ignore rest of function */
|
||||||
if (ctx->hst->scroll_mode) {
|
if (ctx->hst->scroll_mode) {
|
||||||
@ -139,127 +142,123 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BACKSPACE key: Remove one character from line */
|
if (ltr) {
|
||||||
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)) {
|
if (ctx->len < (MAX_STR_SIZE-1)) {
|
||||||
add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);
|
add_char_to_buf(ctx->line, &ctx->pos, &ctx->len, key);
|
||||||
}
|
}
|
||||||
}
|
} else { /* if (!ltr) */
|
||||||
/* 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)
|
/* BACKSPACE key: Remove one character from line */
|
||||||
memset(&line, 0, sizeof(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))
|
else if (key == KEY_DC) { /* DEL key: Remove character at pos */
|
||||||
add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_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);
|
else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */
|
||||||
execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);
|
if (ctx->pos > 0) {
|
||||||
reset_buf(ctx->line, &ctx->pos, &ctx->len);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ typedef struct PromptBuf PromptBuf;
|
|||||||
typedef struct ChatContext ChatContext;
|
typedef struct ChatContext ChatContext;
|
||||||
|
|
||||||
struct ToxWindow {
|
struct ToxWindow {
|
||||||
void(*onKey)(ToxWindow *, Tox *, wint_t);
|
void(*onKey)(ToxWindow *, Tox *, wint_t, bool);
|
||||||
void(*onDraw)(ToxWindow *, Tox *);
|
void(*onDraw)(ToxWindow *, Tox *);
|
||||||
void(*onInit)(ToxWindow *, Tox *);
|
void(*onInit)(ToxWindow *, Tox *);
|
||||||
void(*onFriendRequest)(ToxWindow *, Tox *, uint8_t *, uint8_t *, uint16_t);
|
void(*onFriendRequest)(ToxWindow *, Tox *, uint8_t *, uint8_t *, uint16_t);
|
||||||
|
@ -394,18 +394,30 @@ void draw_active_window(Tox *m)
|
|||||||
wrefresh(a->window);
|
wrefresh(a->window);
|
||||||
|
|
||||||
/* Handle input */
|
/* Handle input */
|
||||||
|
bool ltr;
|
||||||
#ifdef HAVE_WIDECHAR
|
#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
|
#else
|
||||||
if ((ch = getch()) == ERR)
|
ch = getch();
|
||||||
#endif
|
|
||||||
|
if (ch == ERR)
|
||||||
return;
|
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);
|
set_next_window((int) ch);
|
||||||
} else {
|
} else {
|
||||||
pthread_mutex_lock(&Winthread.lock);
|
pthread_mutex_lock(&Winthread.lock);
|
||||||
a->onKey(a, m, ch);
|
a->onKey(a, m, ch, ltr);
|
||||||
pthread_mutex_unlock(&Winthread.lock);
|
pthread_mutex_unlock(&Winthread.lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user