1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-12-23 19:43:26 +01:00

refactor prompt to allow scrolling

This commit is contained in:
Jfreegman 2014-03-25 03:17:22 -04:00
parent a40b6b1b1b
commit 5e941427d3
8 changed files with 252 additions and 209 deletions

View File

@ -53,22 +53,19 @@ void cmd_chat_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN);
#ifdef _SUPPORT_AUDIO
#define NUMLINES 11
#define NUMLINES 12
#else
#define NUMLINES 7
#define NUMLINES 8
#endif
uint8_t lines[NUMLINES][MAX_STR_SIZE] = {
#ifdef _SUPPORT_AUDIO
{ " /call : Audio call" },
{ " /cancel : Cancel call" },
{ " /answer : Answer incomming call" },
{ " /hangup : Hangup active call" },
#endif /* _SUPPORT_AUDIO */
{ " /invite <n> : Invite friend to a group chat" },
{ " /join : Join a pending group chat" },
{ " /log <on> or <off> : Enable/disable logging" },
@ -76,7 +73,7 @@ void cmd_chat_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
{ " /savefile <n> : Receive a file" },
{ " /close : Close the current chat window" },
{ " /help : Print this message again" },
//{ " /help global : Show a list of global commands" },
{ " /help global : Show a list of global commands" },
};
int i;
@ -84,7 +81,7 @@ void cmd_chat_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg
for (i = 0; i < NUMLINES; ++i)
line_info_add(self, NULL, NULL, NULL, lines[i], SYS_MSG, 0, 0);
msg = " * Use ESC key to toggle history scroll mode";
msg = " * Use ESC key to toggle history scroll mode\n";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN);
}

View File

@ -32,6 +32,7 @@
#include "execute.h"
#include "chat_commands.h"
#include "global_commands.h"
#include "line_info.h"
struct cmd_func {
const char *name;
@ -76,7 +77,7 @@ static struct cmd_func chat_commands[] = {
/* Parses input command and puts args into arg array.
Returns number of arguments on success, -1 on failure. */
static int parse_command(WINDOW *w, char *cmd, char (*args)[MAX_STR_SIZE])
static int parse_command(WINDOW *w, ToxWindow *self, char *cmd, char (*args)[MAX_STR_SIZE])
{
int num_args = 0;
bool cmd_end = false; /* flags when we get to the end of cmd */
@ -88,7 +89,8 @@ static int parse_command(WINDOW *w, char *cmd, char (*args)[MAX_STR_SIZE])
end = strchr(cmd+1, '\"');
if (end++ == NULL) { /* Increment past the end quote */
wprintw(w, "Invalid argument. Did you forget a closing \"?\n");
uint8_t *errmsg = "Invalid argument. Did you forget a closing \"?";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return -1;
}
@ -131,7 +133,7 @@ void execute(WINDOW* w, ToxWindow *self, Tox *m, char *cmd, int mode)
return;
char args[MAX_NUM_ARGS][MAX_STR_SIZE] = {0};
int num_args = parse_command(w, cmd, args);
int num_args = parse_command(w, self, cmd, args);
if (num_args == -1)
return;
@ -153,5 +155,6 @@ void execute(WINDOW* w, ToxWindow *self, Tox *m, char *cmd, int mode)
if (do_command(w, self, m, num_args, GLOBAL_NUM_COMMANDS, global_commands, args) == 0)
return;
wprintw(w, "Invalid command.\n");
uint8_t *errmsg = "Invalid command.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
}

View File

@ -106,7 +106,6 @@ static void friendlist_onMessage(ToxWindow *self, Tox *m, int32_t num, uint8_t *
nick[TOXIC_MAX_NAME_LENGTH] = '\0';
wprintw(prompt->window, "%s: %s\n", nick, str);
prep_prompt_win();
wattron(prompt->window, COLOR_PAIR(RED));
wprintw(prompt->window, "* Warning: Too many windows are open.\n");
wattron(prompt->window, COLOR_PAIR(RED));
@ -211,7 +210,6 @@ static void friendlist_onFileSendRequest(ToxWindow *self, Tox *m, int32_t num, u
tox_get_name(m, num, nick);
nick[TOXIC_MAX_NAME_LENGTH] = '\0';
prep_prompt_win();
wattron(prompt->window, COLOR_PAIR(RED));
wprintw(prompt->window, "* File transfer from %s failed: too many windows are open.\n", nick);
wattron(prompt->window, COLOR_PAIR(RED));
@ -234,7 +232,6 @@ static void friendlist_onGroupInvite(ToxWindow *self, Tox *m, int32_t num, uint8
tox_get_name(m, num, nick);
nick[TOXIC_MAX_NAME_LENGTH] = '\0';
prep_prompt_win();
wattron(prompt->window, COLOR_PAIR(RED));
wprintw(prompt->window, "* Group chat invite from %s failed: too many windows are open.\n", nick);
wattron(prompt->window, COLOR_PAIR(RED));
@ -343,7 +340,6 @@ static void friendlist_onKey(ToxWindow *self, Tox *m, wint_t key)
friends[f].chatwin = add_window(m, new_chat(m, friends[f].num));
set_active_window(friends[f].chatwin);
} else {
prep_prompt_win();
wattron(prompt->window, COLOR_PAIR(RED));
wprintw(prompt->window, "* Warning: Too many windows are open.\n");
wattron(prompt->window, COLOR_PAIR(RED));
@ -539,8 +535,7 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av)
tox_get_name(m, id, nick);
nick[TOXIC_MAX_NAME_LENGTH] = '\0';
wprintw(prompt->window, "Audio action from: %s!\n", nick);
prep_prompt_win();
wattron(prompt->window, COLOR_PAIR(RED));
wprintw(prompt->window, "* Warning: Too many windows are open.\n");
wattron(prompt->window, COLOR_PAIR(RED));

View File

@ -30,6 +30,7 @@
#include "toxic_windows.h"
#include "misc_tools.h"
#include "friendlist.h"
#include "line_info.h"
extern char *DATA_FILE;
extern ToxWindow *prompt;
@ -42,30 +43,34 @@ extern uint8_t num_frnd_requests;
/* command functions */
void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
/* check arguments */
uint8_t *msg;
if (argc != 1) {
wprintw(window, "Invalid syntax.\n");
return;
msg = "Invalid syntax.";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
return;
}
int req = atoi(argv[1]);
if ((req == 0 && strcmp(argv[1], "0"))|| req >= MAX_FRIENDS_NUM) {
wprintw(window, "No pending friend request with that number.\n");
msg = "No pending friend request with that number.";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
return;
}
if (!strlen(pending_frnd_requests[req])) {
wprintw(window, "No pending friend request with that number.\n");
msg = "No pending friend request with that number.";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
return;
}
int32_t friendnum = tox_add_friend_norequest(m, pending_frnd_requests[req]);
if (friendnum == -1)
wprintw(window, "Failed to add friend.\n");
msg = "Failed to add friend.";
else {
wprintw(window, "Friend request accepted.\n");
msg = "Friend request accepted.";
on_friendadded(m, friendnum, true);
}
@ -79,12 +84,16 @@ void cmd_accept(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
}
num_frnd_requests = i;
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
}
void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
uint8_t *errmsg;
if (argc < 1) {
wprintw(window, "Invalid syntax.\n");
errmsg = "Invalid syntax.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -95,7 +104,8 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
uint8_t *temp = argv[2];
if (temp[0] != '\"') {
wprintw(window, "Message must be enclosed in quotes.\n");
errmsg = "Message must be enclosed in quotes.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -108,7 +118,8 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
}
if (strlen(id) != 2 * TOX_FRIEND_ADDRESS_SIZE) {
wprintw(window, "Invalid ID length.\n");
errmsg = "Invalid ID length.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -123,7 +134,8 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
xx[2] = '\0';
if (sscanf(xx, "%02x", &x) != 1) {
wprintw(window, "Invalid ID.\n");
errmsg = "Invalid ID.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -138,31 +150,33 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
switch (f_num) {
case TOX_FAERR_TOOLONG:
wprintw(window, "Message is too long.\n");
errmsg = "Message is too long.";
break;
case TOX_FAERR_NOMESSAGE:
wprintw(window, "Please add a message to your request.\n");
errmsg = "Please add a message to your request.";
break;
case TOX_FAERR_OWNKEY:
wprintw(window, "That appears to be your own ID.\n");
errmsg = "That appears to be your own ID.";
break;
case TOX_FAERR_ALREADYSENT:
wprintw(window, "Friend request has already been sent.\n");
errmsg = "Friend request has already been sent.";
break;
case TOX_FAERR_UNKNOWN:
wprintw(window, "Undefined error when adding friend.\n");
errmsg = "Undefined error when adding friend.";
break;
case TOX_FAERR_BADCHECKSUM:
wprintw(window, "Bad checksum in address.\n");
errmsg = "Bad checksum in address.";
break;
case TOX_FAERR_SETNEWNOSPAM:
wprintw(window, "Nospam was different (is this contact already added?)\n");
errmsg = "Nospam was different (is this contact already added?";
break;
default:
wprintw(window, "Friend request sent.\n");
errmsg = "Friend request sent.";
on_friendadded(m, f_num, true);
break;
}
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
}
void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -173,9 +187,12 @@ void cmd_clear(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[M
void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
uint8_t *errmsg;
/* check arguments */
if (argc != 3) {
wprintw(window, "Invalid syntax.\n");
errmsg = "Invalid syntax.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -185,7 +202,8 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
char *key = argv[3];
if (atoi(port) == 0) {
wprintw(window, "Invalid syntax.\n");
errmsg = "Invalid syntax.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -197,48 +215,46 @@ void cmd_connect(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)
void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
uint8_t *errmsg;
if (get_num_active_windows() >= MAX_WINDOWS_NUM) {
wattron(window, COLOR_PAIR(RED));
wprintw(window, " * Warning: Too many windows are open.\n");
wattron(window, COLOR_PAIR(RED));
errmsg = " * Warning: Too many windows are open.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, RED);
return;
}
int groupnum = tox_add_groupchat(m);
if (groupnum == -1) {
wprintw(window, "Group chat instance failed to initialize.\n");
errmsg = "Group chat instance failed to initialize.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
if (init_groupchat_win(prompt, m, groupnum) == -1) {
wprintw(window, "Group chat window failed to initialize.\n");
errmsg = "Group chat window failed to initialize.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
tox_del_groupchat(m, groupnum);
return;
}
wprintw(window, "Group chat created as %d.\n", groupnum);
uint8_t msg[MAX_STR_SIZE];
snprintf(msg, sizeof(msg), "Group chat created as %d.", groupnum);
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
}
void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
uint8_t *msg;
struct chatlog *log = self->chatwin->log;
if (argc == 0) {
if (log->log_on) {
wprintw(window, "Logging for this window is ");
wattron(window, COLOR_PAIR(GREEN) | A_BOLD);
wprintw(window, "[on]");
wattroff(window, COLOR_PAIR(GREEN) | A_BOLD);
wprintw(window, ". Type \"/log off\" to disable.\n");
} else {
wprintw(window, "Logging for this window is ");
wattron(window, COLOR_PAIR(RED) | A_BOLD);
wprintw(window, "[off]");
wattroff(window, COLOR_PAIR(RED) | A_BOLD);
wprintw(window, ". Type \"/log on\" to enable.\n");
}
if (log->log_on)
msg = "Logging for this window is ON. Type \"/log off\" to disable.";
else
msg = "Logging for this window is OFF. Type \"/log on\" to enable.";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
return;
}
@ -257,10 +273,8 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
log_enable(self->name, NULL, log);
}
wprintw(window, "Logging ");
wattron(window, COLOR_PAIR(GREEN) | A_BOLD);
wprintw(window, "[on]\n");
wattroff(window, COLOR_PAIR(GREEN) | A_BOLD);
msg = "Logging enabled";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
return;
} else if (!strcmp(swch, "0") || !strcmp(swch, "off")) {
if (self->is_chat)
@ -268,14 +282,13 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
log_disable(log);
wprintw(window, "Logging ");
wattron(window, COLOR_PAIR(RED) | A_BOLD);
wprintw(window, "[off]\n");
wattroff(window, COLOR_PAIR(RED) | A_BOLD);
msg = "Logging disabled";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
return;
}
wprintw(window, "Invalid option. Use \"/log on\" and \"/log off\" to toggle logging.\n");
msg = "Invalid option. Use \"/log on\" and \"/log off\" to toggle logging.";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
}
void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -292,14 +305,17 @@ void cmd_myid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
strcat(id, xx);
}
wprintw(window, "%s\n", id);
line_info_add(self, NULL, NULL, NULL, id, SYS_MSG, 0, 0);
}
void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
uint8_t *errmsg;
/* check arguments */
if (argc < 1) {
wprintw(window, "Invalid name.\n");
errmsg = "Invalid name.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -313,7 +329,8 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
}
if (!valid_nick(nick)) {
wprintw(window, "Invalid name.\n");
errmsg = "Invalid name.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -330,15 +347,19 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
uint8_t *errmsg;
if (argc < 1) {
wprintw(window, "Wrong number of arguments.\n");
errmsg = "Wrong number of arguments.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
uint8_t *msg = argv[1];
if (msg[0] != '\"') {
wprintw(window, "Note must be enclosed in quotes.\n");
errmsg = "Note must be enclosed in quotes.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -351,33 +372,43 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
wclear(window);
wattron(window, COLOR_PAIR(CYAN) | A_BOLD);
wprintw(window, "\n\nGlobal commands:\n");
wattroff(window, COLOR_PAIR(CYAN) | A_BOLD);
uint8_t *msg = "Global commands:";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN);
wprintw(window, " /add <id> <msg> : Add friend with optional message\n");
wprintw(window, " /accept <n> : Accept friend request\n");
wprintw(window, " /connect <ip> <port> <key> : Manually connect to a DHT node\n");
wprintw(window, " /status <type> <msg> : Set status with optional note\n");
wprintw(window, " /note <msg> : Set a personal note\n");
wprintw(window, " /nick <nick> : Set your nickname\n");
wprintw(window, " /log <on> or <off> : Enable/disable logging\n");
wprintw(window, " /groupchat : Create a group chat\n");
wprintw(window, " /myid : Print your ID\n");
wprintw(window, " /help : Print this message again\n");
wprintw(window, " /clear : Clear the window\n");
wprintw(window, " /quit or /exit : Exit Toxic\n");
#ifdef _SUPPORT_AUDIO
wprintw(window, " /lsdev <type> : List devices where type: in|out\n");
wprintw(window, " /sdev <type> <id> : Set active device\n");
#define NUMLINES 14
#else
#define NUMLINES 12
#endif
uint8_t lines[NUMLINES][MAX_STR_SIZE] = {
{ " /add <id> <msg> : Add friend with optional message" },
{ " /accept <n> : Accept friend request" },
{ " /connect <ip> <port> <key> : Manually connect to a DHT node" },
{ " /status <type> <msg> : Set status with optional note" },
{ " /note <msg> : Set a personal note" },
{ " /nick <nick> : Set your nickname" },
{ " /log <on> or <off> : Enable/disable logging" },
{ " /groupchat : Create a group chat" },
{ " /myid : Print your ID" },
{ " /help : Print this message again" },
{ " /clear : Clear the window" },
{ " /quit or /exit : Exit Toxic" },
#ifdef _SUPPORT_AUDIO
{ " /lsdev <type> : List devices where type: in|out" },
{ " /sdev <type> <id> : Set active device" },
#endif /* _SUPPORT_AUDIO */
wattron(window, COLOR_PAIR(CYAN) | A_BOLD);
wprintw(window, " * Argument messages must be enclosed in quotation marks.\n");
wprintw(window, " * Use ctrl-o and ctrl-p to navigate through the tabs.\n\n");
wattroff(window, COLOR_PAIR(CYAN) | A_BOLD);
};
int i;
for (i = 0; i < NUMLINES; ++i)
line_info_add(self, NULL, NULL, NULL, lines[i], SYS_MSG, 0, 0);
msg = " * Argument messages must be enclosed in quotation marks.\n"
" * Use ctrl-o and ctrl-p to navigate through the tabs.\n";
line_info_add(self, NULL, NULL, NULL, msg, SYS_MSG, 1, CYAN);
}
void cmd_quit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
@ -388,16 +419,19 @@ void cmd_quit(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
uint8_t *msg = NULL;
uint8_t *errmsg;
if (argc >= 2) {
msg = argv[2];
if (msg[0] != '\"') {
wprintw(window, "Note must be enclosed in quotes.\n");
errmsg = "Note must be enclosed in quotes.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
} else if (argc != 1) {
wprintw(window, "Wrong number of arguments.\n");
errmsg = "Wrong number of arguments.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}
@ -418,7 +452,8 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[
else if (!strcmp(l_status, "busy"))
status_kind = TOX_USERSTATUS_BUSY;
else {
wprintw(window, "Invalid status. Valid statuses are: online, busy and away.\n");
errmsg = "Invalid status. Valid statuses are: online, busy and away.";
line_info_add(self, NULL, NULL, NULL, errmsg, SYS_MSG, 0, 0);
return;
}

View File

@ -34,7 +34,6 @@
void line_info_init(struct history *hst)
{
hst->line_root = malloc(sizeof(struct line_info));
memset(hst->line_root, 0, sizeof(struct line_info));
if (hst->line_root == NULL) {
endwin();
@ -42,6 +41,7 @@ void line_info_init(struct history *hst)
exit(EXIT_FAILURE);
}
memset(hst->line_root, 0, sizeof(struct line_info));
hst->line_start = hst->line_root;
hst->line_end = hst->line_start;
}
@ -64,8 +64,7 @@ static void line_info_reset_start(struct history *hst)
void line_info_toggle_scroll(ToxWindow *self, bool scroll)
{
ChatContext *ctx = self->chatwin;
WINDOW *win = self->is_prompt ? self->window : ctx->history;
WINDOW *win = self->chatwin->history;
struct history *hst = self->chatwin->hst;
if (scroll) {
@ -94,10 +93,8 @@ void line_info_cleanup(struct history *hst)
void line_info_add(ToxWindow *self, uint8_t *tmstmp, uint8_t *name1, uint8_t *name2, uint8_t *msg,
uint8_t msgtype, uint8_t bold, uint8_t colour)
{
WINDOW *win = self->is_prompt ? self->window : self->chatwin->history;
struct history *hst = self->chatwin->hst;
struct line_info *new_line = malloc(sizeof(struct line_info));
memset(new_line, 0, sizeof(struct line_info));
if (new_line == NULL) {
endwin();
@ -105,17 +102,18 @@ void line_info_add(ToxWindow *self, uint8_t *tmstmp, uint8_t *name1, uint8_t *na
exit(EXIT_FAILURE);
}
memset(new_line, 0, sizeof(struct line_info));
int len = 1; /* there will always be a newline */
/* for type-specific formatting in print function */
switch (msgtype) {
case OUT_MSG:
case IN_MSG:
len += 2;
break;
case ACTION:
len += 3;
break;
default:
len += 2;
break;
}
if (msg) {
@ -143,7 +141,7 @@ void line_info_add(ToxWindow *self, uint8_t *tmstmp, uint8_t *name1, uint8_t *na
hst->line_end = new_line;
/* If chat history exceeds limit move root forward and free old root */
if (++(hst->line_items) >= MAX_HISTORY) {
if (++hst->line_items > MAX_HISTORY) {
--hst->line_items;
struct line_info *tmp = hst->line_root->next;
tmp->prev = NULL;
@ -159,10 +157,12 @@ void line_info_add(ToxWindow *self, uint8_t *tmstmp, uint8_t *name1, uint8_t *na
int y, y2, x, x2;
getmaxyx(self->window, y2, x2);
getyx(win, y, x);
getyx(self->chatwin->history, y, x);
int n = self->is_prompt ? 0 : CHATBOX_HEIGHT;
/* move line_start forward proportionate to the number of new rows */
if (y >= y2 - CHATBOX_HEIGHT) {
if (y >= y2 - n) {
int i;
int lines = 1 + (len / x2);
@ -177,7 +177,8 @@ void line_info_add(ToxWindow *self, uint8_t *tmstmp, uint8_t *name1, uint8_t *na
void line_info_print(ToxWindow *self)
{
ChatContext *ctx = self->chatwin;
WINDOW *win = self->is_prompt ? self->window : win;
WINDOW *win = ctx->history;
wclear(win);
wmove(win, 1, 0);
int y2, x2;
@ -186,7 +187,7 @@ void line_info_print(ToxWindow *self)
struct line_info *line = ctx->hst->line_start;
int numlines = 0;
while(line && numlines <= x2) {
while(line && numlines <= y2) {
uint8_t type = line->msgtype;
numlines += line->len / x2;
@ -199,10 +200,10 @@ void line_info_print(ToxWindow *self)
int nameclr = GREEN;
if (type == IN_MSG)
nameclr = CYAN;
if (line->colour)
nameclr = line->colour;
else if (type == IN_MSG)
nameclr = CYAN;
wattron(win, COLOR_PAIR(nameclr));
wprintw(win, "%s: ", line->name1);
@ -249,6 +250,31 @@ void line_info_print(ToxWindow *self)
wattroff(win, COLOR_PAIR(line->colour));
break;
case PROMPT:
wattron(win, COLOR_PAIR(GREEN));
wprintw(win, "$ ");
wattroff(win, COLOR_PAIR(GREEN));
if (line->msg[0])
wprintw(win, "%s", line->msg);
wprintw(win, "\n");
break;
case CONNECTION:
wattron(win, COLOR_PAIR(BLUE));
wprintw(win, "%s", line->timestamp);
wattroff(win, COLOR_PAIR(BLUE));
wattron(win, COLOR_PAIR(line->colour));
wattron(win, A_BOLD);
wprintw(win, "* %s ", line->name1);
wattroff(win, A_BOLD);
wprintw(win, "%s\n", line->msg);
wattroff(win, COLOR_PAIR(line->colour));
break;
}
line = line->next;

View File

@ -26,6 +26,7 @@ enum {
SYS_MSG,
IN_MSG,
OUT_MSG,
PROMPT,
ACTION,
CONNECTION,
} LINE_TYPE;

View File

@ -60,6 +60,7 @@
#include "prompt.h"
#include "misc_tools.h"
#include "file_senders.h"
#include "line_info.h"
#ifdef _SUPPORT_AUDIO
#include "audio_call.h"
@ -272,6 +273,8 @@ int init_connection(Tox *m)
static void do_connection(Tox *m, ToxWindow *prompt)
{
uint8_t msg[MAX_STR_SIZE] = {0};
static int conn_try = 0;
static int conn_err = 0;
static bool dht_on = false;
@ -281,21 +284,21 @@ static void do_connection(Tox *m, ToxWindow *prompt)
if (!dht_on && !is_connected && !(conn_try++ % 100)) {
if (!conn_err) {
if ((conn_err = init_connection(m))) {
prep_prompt_win();
wprintw(prompt->window, "\nAuto-connect failed with error code %d\n", conn_err);
snprintf(msg, sizeof(msg), "\nAuto-connect failed with error code %d", conn_err);
}
}
} else if (!dht_on && is_connected) {
dht_on = true;
prompt_update_connectionstatus(prompt, dht_on);
prep_prompt_win();
wprintw(prompt->window, "DHT connected.\n");
snprintf(msg, sizeof(msg), "DHT connected.");
} else if (dht_on && !is_connected) {
dht_on = false;
prompt_update_connectionstatus(prompt, dht_on);
prep_prompt_win();
wprintw(prompt->window, "\nDHT disconnected. Attempting to reconnect.\n");
snprintf(msg, sizeof(msg), "\nDHT disconnected. Attempting to reconnect.");
}
if (msg[0])
line_info_add(prompt, NULL, NULL, NULL, msg, SYS_MSG, 0, 0);
}
static void load_friendlist(Tox *m)

View File

@ -65,25 +65,6 @@ const uint8_t glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
#endif /* _SUPPORT_AUDIO */
};
/* prevents input string from eating system messages: call this prior to printing a prompt message
TODO: This is only a partial fix */
void prep_prompt_win(void)
{
ChatContext *ctx = prompt->chatwin;
if (ctx->len <= 0)
return;
wprintw(prompt->window, "\n");
if (!ctx->at_bottom) {
wmove(prompt->window, ctx->orig_y - 1, X_OFST);
++ctx->orig_y;
} else {
wmove(prompt->window, ctx->orig_y - 2, X_OFST);
}
}
/* Updates own nick in prompt statusbar */
void prompt_update_nick(ToxWindow *prompt, uint8_t *nick, uint16_t len)
{
@ -142,14 +123,26 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
ChatContext *ctx = self->chatwin;
int x, y, y2, x2;
getyx(self->window, y, x);
getmaxyx(self->window, y2, x2);
getyx(ctx->history, y, x);
getmaxyx(ctx->history, y2, x2);
/* this is buggy */
//if (key == T_KEY_ESC) { /* ESC key: Toggle history scroll mode */
// bool scroll = ctx->hst->scroll_mode ? false : true;
// line_info_toggle_scroll(self, scroll);
//}
/* If we're in scroll mode ignore rest of function */
if (ctx->hst->scroll_mode) {
line_info_onKey(self, key);
return;
}
/* BACKSPACE key: Remove one character from line */
if (key == 0x107 || key == 0x8 || key == 0x7f) {
if (ctx->pos > 0) {
del_char_buf_bck(ctx->line, &ctx->pos, &ctx->len);
wmove(self->window, y, x-1); /* not necessary but fixes a display glitch */
wmove(ctx->history, y, x-1); /* not necessary but fixes a display glitch */
ctx->scroll = false;
} else {
beep();
@ -167,8 +160,8 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
else if (key == T_KEY_DISCARD) { /* CTRL-U: Delete entire line behind pos */
if (ctx->pos > 0) {
wmove(self->window, ctx->orig_y, X_OFST);
wclrtobot(self->window);
wmove(ctx->history, ctx->orig_y, X_OFST);
wclrtobot(ctx->history);
discard_buf(ctx->line, &ctx->pos, &ctx->len);
} else {
beep();
@ -207,7 +200,7 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
}
else if (key == KEY_UP) { /* fetches previous item in history */
wmove(self->window, ctx->orig_y, X_OFST);
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);
@ -222,14 +215,14 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
int k = ctx->orig_y + ((ctx->len + p_ofst) / px2);
if (k >= y2) {
wprintw(self->window, "\n");
wprintw(ctx->history, "\n");
--ctx->orig_y;
}
}
}
else if (key == KEY_DOWN) { /* fetches next item in history */
wmove(self->window, ctx->orig_y, X_OFST);
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);
}
@ -258,8 +251,8 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
}
/* RETURN key: execute command */
else if (key == '\n') {
wprintw(self->window, "\n");
uint8_t line[MAX_STR_SIZE];
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));
@ -267,7 +260,8 @@ static void prompt_onKey(ToxWindow *self, Tox *m, wint_t key)
if (!string_is_empty(line))
add_line_to_hist(ctx->line, ctx->len, ctx->ln_history, &ctx->hst_tot, &ctx->hst_pos);
execute(self->window, self, m, line, GLOBAL_COMMAND_MODE);
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);
}
}
@ -277,9 +271,8 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
ChatContext *ctx = self->chatwin;
int x, y, x2, y2;
getyx(self->window, y, x);
getmaxyx(self->window, y2, x2);
wclrtobot(self->window);
getyx(ctx->history, y, x);
getmaxyx(ctx->history, y2, x2);
line_info_print(self);
/* if len is >= screen width offset max x by X_OFST to account for prompt char */
@ -297,7 +290,7 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1)
reset_buf(ctx->line, &ctx->pos, &ctx->len);
else
mvwprintw(self->window, ctx->orig_y, X_OFST, line);
mvwprintw(ctx->history, ctx->orig_y, X_OFST, line);
int k = ctx->orig_y + ((ctx->len + p_ofst) / px2);
@ -315,9 +308,9 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
ctx->orig_y = y;
}
wattron(self->window, COLOR_PAIR(GREEN));
mvwprintw(self->window, ctx->orig_y, 0, "$ ");
wattroff(self->window, COLOR_PAIR(GREEN));
wattron(ctx->history, COLOR_PAIR(GREEN));
mvwprintw(ctx->history, ctx->orig_y, 0, "$ ");
wattroff(ctx->history, COLOR_PAIR(GREEN));
StatusBar *statusbar = self->stb;
werase(statusbar->topline);
@ -363,43 +356,18 @@ static void prompt_onDraw(ToxWindow *self, Tox *m)
if (statusbar->statusmsg[0])
wprintw(statusbar->topline, " - %s", statusbar->statusmsg);
wprintw(statusbar->topline, "\n");
/* put cursor back in correct spot */
int y_m = ctx->orig_y + ((ctx->pos + p_ofst) / px2);
int x_m = (ctx->pos + X_OFST) % x2;
wmove(self->window, y_m, x_m);
}
static void prompt_onInit(ToxWindow *self, Tox *m)
{
curs_set(1);
scrollok(self->window, true);
ChatContext *ctx = self->chatwin;
ctx->log = malloc(sizeof(struct chatlog));
ctx->hst = malloc(sizeof(struct history));
if (ctx->log == NULL || ctx->hst == NULL) {
endwin();
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(ctx->log, 0, sizeof(struct chatlog));
memset(ctx->hst, 0, sizeof(struct history));
execute(self->window, self, m, "/help", GLOBAL_COMMAND_MODE);
wclrtoeol(self->window);
}
static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum , uint8_t status)
{
if (friendnum < 0)
return;
ChatContext *ctx = self->chatwin;
prep_prompt_win();
uint8_t nick[TOX_MAX_NAME_LENGTH] = {'\0'};
@ -409,31 +377,18 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum
if (!nick[0])
snprintf(nick, sizeof(nick), "%s", UNKNOWN_NAME);
wprintw(self->window, "\n");
print_time(self->window);
const uint8_t *msg;
uint8_t timefrmt[TIME_STR_SIZE];
get_time_str(timefrmt);
uint8_t *msg;
if (status == 1) {
msg = "has come online";
wattron(self->window, COLOR_PAIR(GREEN));
wattron(self->window, A_BOLD);
wprintw(self->window, "* %s ", nick);
wattroff(self->window, A_BOLD);
wprintw(self->window, "%s\n", msg);
wattroff(self->window, COLOR_PAIR(GREEN));
line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, GREEN);
write_to_log(msg, nick, ctx->log, true);
alert_window(self, WINDOW_ALERT_2, false);
} else {
msg = "has gone offline";
wattron(self->window, COLOR_PAIR(RED));
wattron(self->window, A_BOLD);
wprintw(self->window, "* %s ", nick);
wattroff(self->window, A_BOLD);
wprintw(self->window, "%s\n", msg);
wattroff(self->window, COLOR_PAIR(RED));
line_info_add(self, timefrmt, nick, NULL, msg, CONNECTION, 0, RED);
write_to_log(msg, nick, ctx->log, true);
}
}
@ -443,33 +398,32 @@ static void prompt_onFriendRequest(ToxWindow *self, Tox *m, uint8_t *key, uint8_
/* make sure message data is null-terminated */
data[length - 1] = 0;
ChatContext *ctx = self->chatwin;
prep_prompt_win();
wprintw(self->window, "\n");
print_time(self->window);
wprintw(ctx->history, "\n");
print_time(ctx->history);
uint8_t msg[MAX_STR_SIZE];
snprintf(msg, sizeof(msg), "Friend request with the message '%s'\n", data);
wprintw(self->window, "%s", msg);
wprintw(ctx->history, "%s", msg);
write_to_log(msg, "", ctx->log, true);
int n = add_friend_request(key);
if (n == -1) {
const uint8_t *errmsg = "Friend request queue is full. Discarding request.\n";
wprintw(self->window, "%s", errmsg);
wprintw(ctx->history, "%s", errmsg);
write_to_log(errmsg, "", ctx->log, true);
return;
}
wprintw(self->window, "Type \"/accept %d\" to accept it.\n", n);
wprintw(ctx->history, "Type \"/accept %d\" to accept it.\n", n);
alert_window(self, WINDOW_ALERT_1, true);
}
void prompt_init_statusbar(ToxWindow *self, Tox *m)
{
int x, y;
getmaxyx(self->window, y, x);
int x2, y2;
getmaxyx(self->window, y2, x2);
/* Init statusbar info */
StatusBar *statusbar = self->stb;
@ -499,7 +453,36 @@ void prompt_init_statusbar(ToxWindow *self, Tox *m)
prompt_update_status(prompt, status);
/* Init statusbar subwindow */
statusbar->topline = subwin(self->window, 2, x, 0, 0);
statusbar->topline = subwin(self->window, 2, x2, 0, 0);
}
static void prompt_onInit(ToxWindow *self, Tox *m)
{
ChatContext *ctx = self->chatwin;
curs_set(1);
int y2, x2;
getmaxyx(self->window, y2, x2);
ctx->history = subwin(self->window, y2, x2, 0, 0);
scrollok(ctx->history, 1);
ctx->log = malloc(sizeof(struct chatlog));
ctx->hst = malloc(sizeof(struct history));
if (ctx->log == NULL || ctx->hst == NULL) {
endwin();
fprintf(stderr, "malloc() failed. Aborting...\n");
exit(EXIT_FAILURE);
}
memset(ctx->log, 0, sizeof(struct chatlog));
memset(ctx->hst, 0, sizeof(struct history));
line_info_init(ctx->hst);
execute(ctx->history, self, m, "/help", GLOBAL_COMMAND_MODE);
wmove(ctx->history, y2-1, 2);
}
ToxWindow new_prompt(void)