mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-26 15:03:27 +01:00
commit
b9af1b3293
@ -12,14 +12,14 @@ DATAFILES = $(MISC_DIR)/DHTnodes $(MISC_DIR)/toxic.conf
|
|||||||
|
|
||||||
LIBS = libtoxcore ncursesw
|
LIBS = libtoxcore ncursesw
|
||||||
|
|
||||||
CFLAGS = -std=gnu99 -pthread -Wimplicit-function-declaration -Wreturn-type
|
CFLAGS = -std=gnu99 -pthread -Wimplicit-function-declaration -Wreturn-type -Werror
|
||||||
CFLAGS += -DTOXICVER="\"$(VERSION)\"" -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED
|
CFLAGS += -DTOXICVER="\"$(VERSION)\"" -DHAVE_WIDECHAR -D_XOPEN_SOURCE_EXTENDED
|
||||||
CFLAGS += -DPACKAGE_DATADIR="\"$(DATADIR)\""
|
CFLAGS += -DPACKAGE_DATADIR="\"$(DATADIR)\""
|
||||||
CFLAGS += $(USER_CFLAGS)
|
CFLAGS += $(USER_CFLAGS)
|
||||||
LDFLAGS = $(USER_LDFLAGS)
|
LDFLAGS = $(USER_LDFLAGS)
|
||||||
|
|
||||||
OBJ = chat.o chat_commands.o configdir.o dns.o execute.o
|
OBJ = chat.o chat_commands.o configdir.o dns.o execute.o
|
||||||
OBJ += file_senders.o friendlist.o global_commands.o groupchat.o line_info.o
|
OBJ += file_senders.o friendlist.o global_commands.o groupchat.o line_info.o input.o
|
||||||
OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o
|
OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o
|
||||||
|
|
||||||
# Variables for audio support
|
# Variables for audio support
|
||||||
|
245
src/chat.c
245
src/chat.c
@ -20,10 +20,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE /* needed for strcasestr() and wcwidth() */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -38,6 +34,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "line_info.h"
|
#include "line_info.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
#ifdef _SUPPORT_AUDIO
|
#ifdef _SUPPORT_AUDIO
|
||||||
#include "audio_call.h"
|
#include "audio_call.h"
|
||||||
@ -105,12 +102,15 @@ static void set_typingstatus(ToxWindow *self, Tox *m, uint8_t is_typing)
|
|||||||
ctx->self_is_typing = is_typing;
|
ctx->self_is_typing = is_typing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kill_chat_window(ToxWindow *self)
|
void kill_chat_window(ToxWindow *self, Tox *m)
|
||||||
{
|
{
|
||||||
set_active_window(0);
|
set_active_window(0);
|
||||||
ChatContext *ctx = self->chatwin;
|
ChatContext *ctx = self->chatwin;
|
||||||
StatusBar *statusbar = self->stb;
|
StatusBar *statusbar = self->stb;
|
||||||
|
|
||||||
|
if (ctx->self_is_typing)
|
||||||
|
set_typingstatus(self, m, 0);
|
||||||
|
|
||||||
log_disable(ctx->log);
|
log_disable(ctx->log);
|
||||||
line_info_cleanup(ctx->hst);
|
line_info_cleanup(ctx->hst);
|
||||||
|
|
||||||
@ -659,192 +659,75 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
if (x2 <= 0)
|
if (x2 <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int cur_len = 0; /* widechar size of current char */
|
|
||||||
int x2_is_odd = x2 % 2 != 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (ltr) { /* char is printable */
|
if (ltr) { /* char is printable */
|
||||||
if (ctx->len < MAX_STR_SIZE - 1) {
|
input_new_char(self, key, x, y, x2, y2);
|
||||||
add_char_to_buf(ctx, key);
|
|
||||||
cur_len = MAX(1, wcwidth(key));
|
|
||||||
wmove(self->window, y, x + cur_len);
|
|
||||||
|
|
||||||
if (x + cur_len >= x2)
|
if (ctx->line[0] != '/')
|
||||||
ctx->start += cur_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ctx->self_is_typing && ctx->line[0] != '/')
|
|
||||||
set_typingstatus(self, m, 1);
|
set_typingstatus(self, m, 1);
|
||||||
|
|
||||||
} else { /* if (!ltr) */
|
return;
|
||||||
if (line_info_onKey(self, key))
|
}
|
||||||
return;
|
|
||||||
|
|
||||||
if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */
|
if (line_info_onKey(self, key))
|
||||||
if (ctx->pos > 0) {
|
return;
|
||||||
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
|
|
||||||
del_char_buf_bck(ctx);
|
|
||||||
|
|
||||||
if (x <= 0) {
|
input_handle(self, key, x, y, x2, y2);
|
||||||
ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0;
|
|
||||||
int new_x = ctx->start == 0 ? ctx->pos : x2 - cur_len;
|
if (key == '\t') { /* TAB key: auto-completes command */
|
||||||
wmove(self->window, y, new_x);
|
if (ctx->len > 1 && ctx->line[0] == '/') {
|
||||||
|
int diff = complete_line(ctx, chat_cmd_list, AC_NUM_CHAT_COMMANDS, MAX_CMDNAME_SIZE);
|
||||||
|
|
||||||
|
if (diff != -1) {
|
||||||
|
if (x + diff > x2 - 1) {
|
||||||
|
wmove(self->window, y, x + diff);
|
||||||
|
ctx->start += diff;
|
||||||
} else {
|
} else {
|
||||||
wmove(self->window, y, x - cur_len);
|
wmove(self->window, y, x + diff);
|
||||||
}
|
}
|
||||||
|
} else beep();
|
||||||
|
} else beep();
|
||||||
|
|
||||||
|
} else if (key == '\n') {
|
||||||
|
rm_trailing_spaces_buf(ctx);
|
||||||
|
|
||||||
|
uint8_t line[MAX_STR_SIZE];
|
||||||
|
|
||||||
|
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
|
||||||
|
memset(&line, 0, sizeof(line));
|
||||||
|
|
||||||
|
if (!string_is_empty(line))
|
||||||
|
add_line_to_hist(ctx);
|
||||||
|
|
||||||
|
if (line[0] == '/') {
|
||||||
|
if (strcmp(line, "/close") == 0) {
|
||||||
|
kill_chat_window(self, m);
|
||||||
|
return;
|
||||||
|
} else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
|
||||||
|
send_action(self, ctx, m, line + strlen("/me "));
|
||||||
} else {
|
} else {
|
||||||
beep();
|
execute(ctx->history, self, m, line, CHAT_COMMAND_MODE);
|
||||||
}
|
}
|
||||||
}
|
} else if (!string_is_empty(line)) {
|
||||||
|
uint8_t selfname[TOX_MAX_NAME_LENGTH];
|
||||||
|
uint16_t len = tox_get_self_name(m, selfname);
|
||||||
|
selfname[len] = '\0';
|
||||||
|
|
||||||
else if (key == KEY_DC) { /* DEL key: Remove character at pos */
|
uint8_t timefrmt[TIME_STR_SIZE];
|
||||||
if (ctx->pos != ctx->len)
|
get_time_str(timefrmt, sizeof(timefrmt));
|
||||||
del_char_buf_frnt(ctx);
|
|
||||||
else
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */
|
line_info_add(self, timefrmt, selfname, NULL, line, OUT_MSG, 0, 0);
|
||||||
if (ctx->pos > 0) {
|
|
||||||
discard_buf(ctx);
|
if (!statusbar->is_online || tox_send_message(m, self->num, line, strlen(line)) == 0) {
|
||||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
uint8_t *errmsg = " * Failed to send message.";
|
||||||
|
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED);
|
||||||
} else {
|
} else {
|
||||||
beep();
|
write_to_log(line, selfname, ctx->log, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (key == T_KEY_KILL) { /* CTRL-K: Delete entire line in front of pos */
|
wclear(ctx->linewin);
|
||||||
if (ctx->pos != ctx->len)
|
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||||
kill_buf(ctx);
|
reset_buf(ctx);
|
||||||
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;
|
|
||||||
ctx->start = 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;
|
|
||||||
ctx->start = x2 * (ctx->len / x2);
|
|
||||||
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, MAX_STR_SIZE)), 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, x2 - cur_len);
|
|
||||||
ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0;
|
|
||||||
ctx->pos = ctx->start + x2 - 1;
|
|
||||||
} else {
|
|
||||||
wmove(self->window, y, x - cur_len);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == KEY_RIGHT) {
|
|
||||||
if (ctx->pos < ctx->len) {
|
|
||||||
++ctx->pos;
|
|
||||||
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
|
|
||||||
wmove(self->window, y, x + cur_len);
|
|
||||||
|
|
||||||
if (x + cur_len >= x2)
|
|
||||||
ctx->start += cur_len;
|
|
||||||
} else {
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == KEY_UP) { /* fetches previous item in history */
|
|
||||||
fetch_hist_item(ctx, MOVE_UP);
|
|
||||||
ctx->start = x2 * (ctx->len / x2);
|
|
||||||
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, MAX_STR_SIZE)), y2, x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == KEY_DOWN) { /* fetches next item in history */
|
|
||||||
fetch_hist_item(ctx, MOVE_DOWN);
|
|
||||||
ctx->start = x2 * (ctx->len / x2);
|
|
||||||
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, MAX_STR_SIZE)), y2, x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == '\t') { /* TAB key: completes command */
|
|
||||||
if (ctx->len > 1 && ctx->line[0] == '/') {
|
|
||||||
int diff = complete_line(ctx, chat_cmd_list, AC_NUM_CHAT_COMMANDS, MAX_CMDNAME_SIZE);
|
|
||||||
|
|
||||||
if (diff != -1) {
|
|
||||||
if (x + diff > x2 - 1) {
|
|
||||||
//int ofst = x + diff - x2;
|
|
||||||
wmove(self->window, y, x + diff);
|
|
||||||
ctx->start += x2 / 2;
|
|
||||||
} else {
|
|
||||||
wmove(self->window, y, x + diff);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RETURN key: Execute command or print line */
|
|
||||||
else if (key == '\n') {
|
|
||||||
rm_trailing_spaces_buf(ctx);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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];
|
|
||||||
uint16_t len = tox_get_self_name(m, selfname);
|
|
||||||
selfname[len] = '\0';
|
|
||||||
|
|
||||||
uint8_t timefrmt[TIME_STR_SIZE];
|
|
||||||
get_time_str(timefrmt, sizeof(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)) == 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->len <= 0 && ctx->self_is_typing)
|
if (ctx->len <= 0 && ctx->self_is_typing)
|
||||||
@ -863,16 +746,8 @@ static void chat_onDraw(ToxWindow *self, Tox *m)
|
|||||||
|
|
||||||
curs_set(1);
|
curs_set(1);
|
||||||
|
|
||||||
if (ctx->len > 0) {
|
if (ctx->len > 0)
|
||||||
uint8_t line[MAX_STR_SIZE];
|
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
|
||||||
|
|
||||||
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) {
|
|
||||||
reset_buf(ctx);
|
|
||||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
|
||||||
} else {
|
|
||||||
mvwprintw(ctx->linewin, 1, 0, "%s", &line[ctx->start]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Draw status bar */
|
/* Draw status bar */
|
||||||
StatusBar *statusbar = self->stb;
|
StatusBar *statusbar = self->stb;
|
||||||
|
@ -58,7 +58,7 @@ static struct _pendingDel {
|
|||||||
WINDOW *popup;
|
WINDOW *popup;
|
||||||
} pendingdelete;
|
} pendingdelete;
|
||||||
|
|
||||||
#define S_WEIGHT 100
|
#define S_WEIGHT 100000
|
||||||
|
|
||||||
static int index_name_cmp(const void *n1, const void *n2)
|
static int index_name_cmp(const void *n1, const void *n2)
|
||||||
{
|
{
|
||||||
|
258
src/groupchat.c
258
src/groupchat.c
@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _GNU_SOURCE
|
#ifndef _GNU_SOURCE
|
||||||
#define _GNU_SOURCE /* needed for strcasestr() and wcwidth() */
|
#define _GNU_SOURCE /* needed for strcasestr() */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -39,6 +39,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "line_info.h"
|
#include "line_info.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
extern char *DATA_FILE;
|
extern char *DATA_FILE;
|
||||||
|
|
||||||
@ -393,199 +394,80 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
if (x2 <= 0)
|
if (x2 <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int cur_len = 0; /* widechar len of current char */
|
|
||||||
int x2_is_odd = x2 % 2 != 0;
|
|
||||||
|
|
||||||
if (ltr) { /* char is printable */
|
if (ltr) { /* char is printable */
|
||||||
if (ctx->len < MAX_STR_SIZE - 1) {
|
input_new_char(self, key, x, y, x2, y2);
|
||||||
add_char_to_buf(ctx, key);
|
return;
|
||||||
cur_len = MAX(1, wcwidth(key));
|
}
|
||||||
wmove(self->window, y, x + cur_len);
|
|
||||||
|
|
||||||
if (x + cur_len >= x2)
|
if (line_info_onKey(self, key))
|
||||||
ctx->start += cur_len;
|
return;
|
||||||
}
|
|
||||||
} else { /* if (!ltr) */
|
|
||||||
|
|
||||||
if (line_info_onKey(self, key))
|
if (input_handle(self, key, x, y, x2, y2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (key == 0x107 || key == 0x8 || key == 0x7f) { /* BACKSPACE key */
|
if (key == '\t') { /* TAB key: auto-completes peer name or command */
|
||||||
if (ctx->pos > 0) {
|
if (ctx->len > 0) {
|
||||||
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
|
int diff;
|
||||||
del_char_buf_bck(ctx);
|
|
||||||
|
|
||||||
if (x <= 0) {
|
if ((ctx->line[0] != '/') || (ctx->line[1] == 'm' && ctx->line[2] == 'e'))
|
||||||
ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0;
|
diff = complete_line(ctx, groupchats[self->num].peer_names,
|
||||||
int new_x = ctx->start == 0 ? ctx->pos : x2 - cur_len;
|
|
||||||
wmove(self->window, y, new_x);
|
|
||||||
} 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);
|
|
||||||
else
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */
|
|
||||||
if (ctx->pos > 0) {
|
|
||||||
discard_buf(ctx);
|
|
||||||
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);
|
|
||||||
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;
|
|
||||||
ctx->start = 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;
|
|
||||||
ctx->start = x2 * (ctx->len / x2);
|
|
||||||
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, MAX_STR_SIZE)), y2, x2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == KEY_LEFT) {
|
|
||||||
if (ctx->pos > 0) {
|
|
||||||
--ctx->pos;
|
|
||||||
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
|
|
||||||
|
|
||||||
if (x <= 0) {
|
|
||||||
wmove(self->window, y, x2 - cur_len);
|
|
||||||
ctx->start = ctx->start >= x2 ? ctx->start - x2 : 0;
|
|
||||||
ctx->pos = ctx->start + x2 - 1;
|
|
||||||
} else {
|
|
||||||
wmove(self->window, y, x - cur_len);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == KEY_RIGHT) {
|
|
||||||
if (ctx->pos < ctx->len) {
|
|
||||||
++ctx->pos;
|
|
||||||
cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
|
|
||||||
wmove(self->window, y, x + cur_len);
|
|
||||||
|
|
||||||
if (x + cur_len >= x2)
|
|
||||||
ctx->start += cur_len;
|
|
||||||
} else {
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == KEY_UP) { /* fetches previous item in history */
|
|
||||||
fetch_hist_item(ctx, MOVE_UP);
|
|
||||||
ctx->start = x2 * (ctx->len / x2);
|
|
||||||
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, MAX_STR_SIZE)), y2, x2);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == KEY_DOWN) { /* fetches next item in history */
|
|
||||||
fetch_hist_item(ctx, MOVE_DOWN);
|
|
||||||
ctx->start = x2 * (ctx->len / x2);
|
|
||||||
mv_curs_end(self->window, MAX(0, wcswidth(ctx->line, MAX_STR_SIZE)), 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, groupchats[self->num].peer_names,
|
|
||||||
groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH);
|
groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH);
|
||||||
|
else
|
||||||
|
diff = complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);
|
||||||
|
|
||||||
|
if (diff != -1) {
|
||||||
|
if (x + diff > x2 - 1) {
|
||||||
|
wmove(self->window, y, x + diff);
|
||||||
|
ctx->start += diff;
|
||||||
|
} else {
|
||||||
|
wmove(self->window, y, x + diff);
|
||||||
|
}
|
||||||
|
} else beep();
|
||||||
|
} else beep();
|
||||||
|
} else if (key == T_KEY_C_RB) { /* Scroll peerlist up and down one position */
|
||||||
|
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
|
||||||
|
|
||||||
|
if (groupchats[self->num].side_pos < groupchats[self->num].num_peers - L)
|
||||||
|
++groupchats[self->num].side_pos;
|
||||||
|
} else if (key == T_KEY_C_LB) {
|
||||||
|
if (groupchats[self->num].side_pos > 0)
|
||||||
|
--groupchats[self->num].side_pos;
|
||||||
|
} else if (key == '\n') {
|
||||||
|
rm_trailing_spaces_buf(ctx);
|
||||||
|
|
||||||
|
uint8_t line[MAX_STR_SIZE];
|
||||||
|
|
||||||
|
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
|
||||||
|
memset(&line, 0, sizeof(line));
|
||||||
|
|
||||||
|
if (!string_is_empty(line))
|
||||||
|
add_line_to_hist(ctx);
|
||||||
|
|
||||||
|
if (line[0] == '/') {
|
||||||
|
if (strcmp(line, "/close") == 0) {
|
||||||
|
close_groupchat(self, m, self->num);
|
||||||
|
return;
|
||||||
|
} else if (strcmp(line, "/help") == 0) {
|
||||||
|
if (strcmp(line, "help global") == 0)
|
||||||
|
execute(ctx->history, self, m, "/help", GLOBAL_COMMAND_MODE);
|
||||||
else
|
else
|
||||||
diff = complete_line(ctx, glob_cmd_list, AC_NUM_GLOB_COMMANDS, MAX_CMDNAME_SIZE);
|
print_groupchat_help(self);
|
||||||
|
|
||||||
if (diff != -1) {
|
} else if (strncmp(line, "/me ", strlen("/me ")) == 0) {
|
||||||
if (x + diff > x2 - 1) {
|
send_group_action(self, ctx, m, line + strlen("/me "));
|
||||||
int ofst = (x + diff - 1) - (x2 - 1);
|
|
||||||
wmove(self->window, y + 1, ofst);
|
|
||||||
} else {
|
|
||||||
wmove(self->window, y, x + diff);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
beep();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
beep();
|
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) {
|
||||||
|
uint8_t *errmsg = " * Failed to send message.";
|
||||||
|
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scroll peerlist up and down one position if list overflows window */
|
wclear(ctx->linewin);
|
||||||
else if (key == T_KEY_C_RB) {
|
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
||||||
int L = y2 - CHATBOX_HEIGHT - SDBAR_OFST;
|
reset_buf(ctx);
|
||||||
|
|
||||||
if (groupchats[self->num].side_pos < groupchats[self->num].num_peers - L)
|
|
||||||
++groupchats[self->num].side_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (key == T_KEY_C_LB) {
|
|
||||||
if (groupchats[self->num].side_pos > 0)
|
|
||||||
--groupchats[self->num].side_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RETURN key: Execute command or print line */
|
|
||||||
else if (key == '\n') {
|
|
||||||
rm_trailing_spaces_buf(ctx);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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) {
|
|
||||||
uint8_t *errmsg = " * Failed to send message.";
|
|
||||||
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reset_buf(ctx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,16 +485,8 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m)
|
|||||||
scrollok(ctx->history, 0);
|
scrollok(ctx->history, 0);
|
||||||
curs_set(1);
|
curs_set(1);
|
||||||
|
|
||||||
if (ctx->len > 0) {
|
if (ctx->len > 0)
|
||||||
uint8_t line[MAX_STR_SIZE];
|
mvwprintw(ctx->linewin, 1, 0, "%ls", &ctx->line[ctx->start]);
|
||||||
|
|
||||||
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) {
|
|
||||||
reset_buf(ctx);
|
|
||||||
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
|
|
||||||
} else {
|
|
||||||
mvwprintw(ctx->linewin, 1, 0, "%s", &line[ctx->start]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wclear(ctx->sidebar);
|
wclear(ctx->sidebar);
|
||||||
mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x2);
|
mvwhline(ctx->linewin, 0, 0, ACS_HLINE, x2);
|
||||||
|
278
src/input.c
Normal file
278
src/input.c
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
/* input.c
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Toxic All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This file is part of Toxic.
|
||||||
|
*
|
||||||
|
* Toxic is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Toxic is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _GNU_SOURCE
|
||||||
|
#define _GNU_SOURCE /* needed for wcwidth() */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include "toxic.h"
|
||||||
|
#include "windows.h"
|
||||||
|
#include "misc_tools.h"
|
||||||
|
#include "toxic_strings.h"
|
||||||
|
#include "line_info.h"
|
||||||
|
|
||||||
|
/* add a char to input field and buffer */
|
||||||
|
void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
if (ctx->len >= MAX_STR_SIZE - 1) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cur_len = wcwidth(key);
|
||||||
|
|
||||||
|
/* this is the only place we need to do this check */
|
||||||
|
if (cur_len == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
add_char_to_buf(ctx, key);
|
||||||
|
|
||||||
|
if (x + cur_len >= mx_x) {
|
||||||
|
int s_len = wcwidth(ctx->line[ctx->start]);
|
||||||
|
int cdiff = cur_len - s_len;
|
||||||
|
ctx->start += 1 + MAX(0, cdiff);
|
||||||
|
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
|
||||||
|
} else {
|
||||||
|
wmove(self->window, y, x + cur_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete a char via backspace key from input field and buffer */
|
||||||
|
static void input_backspace(ToxWindow *self, int x, int y, int mx_x, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
if (ctx->pos <= 0) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cur_len = wcwidth(ctx->line[ctx->pos - 1]);
|
||||||
|
|
||||||
|
del_char_buf_bck(ctx);
|
||||||
|
|
||||||
|
int s_len = wcwidth(ctx->line[ctx->start - 1]);
|
||||||
|
int cdiff = s_len - cur_len;
|
||||||
|
|
||||||
|
if (ctx->start && (x >= mx_x - cur_len)) {
|
||||||
|
ctx->start = MAX(0, ctx->start - 1 + cdiff);
|
||||||
|
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
|
||||||
|
} else if (ctx->start && (ctx->pos == ctx->len)) {
|
||||||
|
ctx->start = MAX(0, ctx->start - cur_len);
|
||||||
|
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
|
||||||
|
} else if (ctx->start) {
|
||||||
|
ctx->start = MAX(0, ctx->start - cur_len);
|
||||||
|
} else {
|
||||||
|
wmove(self->window, y, x - cur_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* delete a char via delete key from input field and buffer */
|
||||||
|
static void input_delete(ToxWindow *self)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
if (ctx->pos >= ctx->len) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
del_char_buf_frnt(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deletes entire line before cursor from input field and buffer */
|
||||||
|
static void input_discard(ToxWindow *self, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
if (ctx->pos <= 0) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
discard_buf(ctx);
|
||||||
|
wmove(self->window, mx_y - CURS_Y_OFFSET, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* deletes entire line after cursor from input field and buffer */
|
||||||
|
static void input_kill(ChatContext *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->pos != ctx->len) {
|
||||||
|
kill_buf(ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
beep();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* moves cursor/line position to end of line in input field and buffer */
|
||||||
|
static void input_mv_end(ToxWindow *self, int x, int y, int mx_x, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
ctx->pos = ctx->len;
|
||||||
|
|
||||||
|
int wlen = wcswidth(ctx->line, sizeof(ctx->line));
|
||||||
|
ctx->start = MAX(0, 1 + (mx_x * (wlen / mx_x) - mx_x) + (wlen % mx_x));
|
||||||
|
|
||||||
|
int llen = wcswidth(&ctx->line[ctx->start], mx_x);
|
||||||
|
int new_x = wlen >= mx_x ? mx_x - 1 : llen;
|
||||||
|
|
||||||
|
wmove(self->window, y, new_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* moves cursor/line position to start of line in input field and buffer */
|
||||||
|
static void input_mv_home(ToxWindow *self, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
if (ctx->pos <= 0) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->pos = 0;
|
||||||
|
ctx->start = 0;
|
||||||
|
wmove(self->window, mx_y - CURS_Y_OFFSET, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* moves cursor/line position left in input field and buffer */
|
||||||
|
static void input_mv_left(ToxWindow *self, int x, int y, int mx_x, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
if (ctx->pos <= 0) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cur_len = wcwidth(ctx->line[ctx->pos - 1]);
|
||||||
|
|
||||||
|
--ctx->pos;
|
||||||
|
|
||||||
|
int s_len = wcwidth(ctx->line[ctx->start - 1]);
|
||||||
|
int cdiff = s_len - cur_len;
|
||||||
|
|
||||||
|
if (ctx->start && (x >= mx_x - cur_len)) {
|
||||||
|
ctx->start = MAX(0, ctx->start - 1 + cdiff);
|
||||||
|
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
|
||||||
|
} else if (ctx->start && (ctx->pos == ctx->len)) {
|
||||||
|
ctx->start = MAX(0, ctx->start - cur_len);
|
||||||
|
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
|
||||||
|
} else if (ctx->start) {
|
||||||
|
ctx->start = MAX(0, ctx->start - cur_len);
|
||||||
|
} else {
|
||||||
|
wmove(self->window, y, x - cur_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* moves cursor/line position right in input field and buffer */
|
||||||
|
static void input_mv_right(ToxWindow *self, int x, int y, int mx_x, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
if (ctx->pos >= ctx->len) {
|
||||||
|
beep();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
++ctx->pos;
|
||||||
|
|
||||||
|
int cur_len = MAX(1, wcwidth(ctx->line[ctx->pos - 1]));
|
||||||
|
|
||||||
|
if (x + cur_len >= mx_x) {
|
||||||
|
int s_len = wcwidth(ctx->line[ctx->start]);
|
||||||
|
int cdiff = cur_len - s_len;
|
||||||
|
ctx->start += 1 + MAX(0, cdiff);
|
||||||
|
wmove(self->window, y, wcswidth(&ctx->line[ctx->start], mx_x));
|
||||||
|
} else {
|
||||||
|
wmove(self->window, y, x + cur_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* puts a line history item in input field and buffer */
|
||||||
|
static void input_history(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
|
||||||
|
{
|
||||||
|
ChatContext *ctx = self->chatwin;
|
||||||
|
|
||||||
|
fetch_hist_item(ctx, key);
|
||||||
|
ctx->start = mx_x * (ctx->len / mx_x);
|
||||||
|
input_mv_end(self, x, y, mx_x, mx_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handles non-printable input keys that behave the same for all types of chat windows.
|
||||||
|
return true if key matches a function, false otherwise */
|
||||||
|
bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y)
|
||||||
|
{
|
||||||
|
bool match = true;
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
input_backspace(self, x, y, mx_x, mx_y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_DC:
|
||||||
|
input_delete(self);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_KEY_DISCARD:
|
||||||
|
input_discard(self, mx_y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_KEY_KILL:
|
||||||
|
input_kill(self->chatwin);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_HOME:
|
||||||
|
case T_KEY_C_A:
|
||||||
|
input_mv_home(self, mx_y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_END:
|
||||||
|
case T_KEY_C_E:
|
||||||
|
input_mv_end(self, x, y, mx_x, mx_y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_LEFT:
|
||||||
|
input_mv_left(self, x, y, mx_x, mx_y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_RIGHT:
|
||||||
|
input_mv_right(self, x, y, mx_x, mx_y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_UP:
|
||||||
|
case KEY_DOWN:
|
||||||
|
input_history(self, key, x, y, mx_x, mx_y);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
match = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
33
src/input.h
Normal file
33
src/input.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* input.h
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Toxic All Rights Reserved.
|
||||||
|
*
|
||||||
|
* This file is part of Toxic.
|
||||||
|
*
|
||||||
|
* Toxic is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Toxic is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Toxic. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _input_h
|
||||||
|
#define _input_h
|
||||||
|
|
||||||
|
/* add a char to input field and buffer for given chatcontext */
|
||||||
|
void input_new_char(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y);
|
||||||
|
|
||||||
|
/* Handles non-printable input keys that behave the same for all types of chat windows.
|
||||||
|
return true if key matches a function, false otherwise */
|
||||||
|
bool input_handle(ToxWindow *self, wint_t key, int x, int y, int mx_x, int mx_y);
|
||||||
|
|
||||||
|
#endif /* #define _input_h */
|
@ -188,13 +188,6 @@ int valid_nick(uint8_t *nick)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Moves cursor to the end of the line in given window */
|
|
||||||
void mv_curs_end(WINDOW *w, size_t len, int max_y, int max_x)
|
|
||||||
{
|
|
||||||
int new_x = len < max_x ? len : len % max_x;
|
|
||||||
wmove(w, max_y - CURS_Y_OFFSET, new_x);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* gets base file name from path or original file name if no path is supplied */
|
/* gets base file name from path or original file name if no path is supplied */
|
||||||
void get_file_name(uint8_t *namebuf, uint8_t *pathname)
|
void get_file_name(uint8_t *namebuf, uint8_t *pathname)
|
||||||
{
|
{
|
||||||
|
@ -79,9 +79,6 @@ int qsort_strcasecmp_hlpr(const void *nick1, const void *nick2);
|
|||||||
- must not contain contiguous spaces */
|
- must not contain contiguous spaces */
|
||||||
int valid_nick(uint8_t *nick);
|
int valid_nick(uint8_t *nick);
|
||||||
|
|
||||||
/* Moves the cursor to the end of the line in given window */
|
|
||||||
void mv_curs_end(WINDOW *w, size_t len, int max_y, int max_x);
|
|
||||||
|
|
||||||
/* gets base file name from path or original file name if no path is supplied */
|
/* gets base file name from path or original file name if no path is supplied */
|
||||||
void get_file_name(uint8_t *namebuf, uint8_t *pathname);
|
void get_file_name(uint8_t *namebuf, uint8_t *pathname);
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
|
|
||||||
else if (key == KEY_UP) { /* fetches previous item in history */
|
else if (key == KEY_UP) { /* fetches previous item in history */
|
||||||
wmove(ctx->history, ctx->orig_y, X_OFST);
|
wmove(ctx->history, ctx->orig_y, X_OFST);
|
||||||
fetch_hist_item(ctx, MOVE_UP);
|
fetch_hist_item(ctx, KEY_UP);
|
||||||
|
|
||||||
/* adjust line y origin appropriately when window scrolls down */
|
/* adjust line y origin appropriately when window scrolls down */
|
||||||
if (ctx->at_bottom && ctx->len >= x2 - X_OFST) {
|
if (ctx->at_bottom && ctx->len >= x2 - X_OFST) {
|
||||||
@ -215,7 +215,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
|
|||||||
|
|
||||||
else if (key == KEY_DOWN) { /* fetches next item in history */
|
else if (key == KEY_DOWN) { /* fetches next item in history */
|
||||||
wmove(ctx->history, ctx->orig_y, X_OFST);
|
wmove(ctx->history, ctx->orig_y, X_OFST);
|
||||||
fetch_hist_item(ctx, MOVE_DOWN);
|
fetch_hist_item(ctx, KEY_DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (key == '\t') { /* TAB key: completes command */
|
else if (key == '\t') { /* TAB key: completes command */
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#define UNKNOWN_NAME "Anonymous"
|
#define UNKNOWN_NAME "Anonymous"
|
||||||
|
|
||||||
#define MAX_FRIENDS_NUM 500
|
#define MAX_FRIENDS_NUM 500
|
||||||
#define MAX_STR_SIZE 1024
|
#define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH
|
||||||
#define MAX_CMDNAME_SIZE 64
|
#define MAX_CMDNAME_SIZE 64
|
||||||
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */
|
#define TOXIC_MAX_NAME_LENGTH 32 /* Must be <= TOX_MAX_NAME_LENGTH */
|
||||||
#define KEY_IDENT_DIGITS 2 /* number of hex digits to display for the pub-key based identifier */
|
#define KEY_IDENT_DIGITS 2 /* number of hex digits to display for the pub-key based identifier */
|
||||||
@ -54,11 +54,6 @@
|
|||||||
#define T_KEY_C_F 0x06 /* ctrl-f */
|
#define T_KEY_C_F 0x06 /* ctrl-f */
|
||||||
#define T_KEY_C_H 0x08 /* ctrl-h */
|
#define T_KEY_C_H 0x08 /* ctrl-h */
|
||||||
|
|
||||||
enum {
|
|
||||||
MOVE_UP,
|
|
||||||
MOVE_DOWN,
|
|
||||||
} KEY_DIRS;
|
|
||||||
|
|
||||||
typedef enum _FATAL_ERRS {
|
typedef enum _FATAL_ERRS {
|
||||||
FATALERR_MEMORY = -1, /* malloc() or calloc() failed */
|
FATALERR_MEMORY = -1, /* malloc() or calloc() failed */
|
||||||
FATALERR_FREAD = -2, /* fread() failed on critical read */
|
FATALERR_FREAD = -2, /* fread() failed on critical read */
|
||||||
|
@ -149,7 +149,7 @@ void add_line_to_hist(ChatContext *ctx)
|
|||||||
resets line if at end of history */
|
resets line if at end of history */
|
||||||
void fetch_hist_item(ChatContext *ctx, int key_dir)
|
void fetch_hist_item(ChatContext *ctx, int key_dir)
|
||||||
{
|
{
|
||||||
if (key_dir == MOVE_UP) {
|
if (key_dir == KEY_UP) {
|
||||||
if (--ctx->hst_pos < 0) {
|
if (--ctx->hst_pos < 0) {
|
||||||
ctx->hst_pos = 0;
|
ctx->hst_pos = 0;
|
||||||
beep();
|
beep();
|
||||||
@ -247,8 +247,8 @@ int complete_line(ChatContext *ctx, const void *list, int n_items, int size)
|
|||||||
|
|
||||||
wcscpy(ctx->line, newbuf);
|
wcscpy(ctx->line, newbuf);
|
||||||
|
|
||||||
ctx->len += (size_t) diff;
|
ctx->len += diff;
|
||||||
ctx->pos += (size_t) diff;
|
ctx->pos += diff;
|
||||||
|
|
||||||
return diff;
|
return diff;
|
||||||
}
|
}
|
||||||
|
@ -166,9 +166,9 @@ struct infobox {
|
|||||||
/* chat and groupchat window/buffer holder */
|
/* chat and groupchat window/buffer holder */
|
||||||
struct ChatContext {
|
struct ChatContext {
|
||||||
wchar_t line[MAX_STR_SIZE];
|
wchar_t line[MAX_STR_SIZE];
|
||||||
size_t pos;
|
int pos;
|
||||||
size_t len;
|
int len;
|
||||||
size_t start; /* the position to start printing line at */
|
int start; /* the position to start printing line at */
|
||||||
|
|
||||||
wchar_t ln_history[MAX_LINE_HIST][MAX_STR_SIZE]; /* history for input lines/commands */
|
wchar_t ln_history[MAX_LINE_HIST][MAX_STR_SIZE]; /* history for input lines/commands */
|
||||||
int hst_pos;
|
int hst_pos;
|
||||||
|
Loading…
Reference in New Issue
Block a user