1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-15 11:03:03 +01:00
toxic/src/prompt.c

729 lines
21 KiB
C
Raw Normal View History

2014-02-25 08:28:24 +01:00
/* prompt.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/>.
*
2013-09-02 19:19:25 +02:00
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* needed for wcswidth() */
#endif
#include <stdlib.h>
#include <string.h>
2014-06-22 03:41:38 +02:00
#include <wchar.h>
2020-04-18 02:00:00 +02:00
#include "autocomplete.h"
2013-11-10 03:43:56 +01:00
#include "execute.h"
2020-04-18 02:00:00 +02:00
#include "friendlist.h"
#include "help.h"
2020-04-18 02:00:00 +02:00
#include "input.h"
#include "line_info.h"
#include "log.h"
#include "misc_tools.h"
2014-07-21 01:12:13 +02:00
#include "notify.h"
2020-04-18 02:00:00 +02:00
#include "prompt.h"
#include "settings.h"
#include "toxic.h"
#include "toxic_strings.h"
#include "windows.h"
extern ToxWindow *prompt;
extern struct user_settings *user_settings;
extern struct Winthread Winthread;
2014-04-07 10:42:10 +02:00
extern FriendsList Friends;
2014-09-28 23:49:48 +02:00
FriendRequests FrndRequests;
2014-11-15 02:13:08 +01:00
/* Array of global command names used for tab completion. */
static const char *glob_cmd_list[] = {
"/accept",
"/add",
"/avatar",
"/clear",
"/connect",
"/decline",
"/exit",
2020-11-13 03:30:48 +01:00
"/group",
"/conference",
2021-04-22 23:05:04 +02:00
#ifdef GAMES
2020-12-11 07:46:01 +01:00
"/game",
#endif
"/help",
2020-11-13 03:30:48 +01:00
"/join",
"/log",
"/myid",
2018-06-16 05:07:16 +02:00
#ifdef QRCODE
"/myqr",
2018-06-16 05:07:16 +02:00
#endif /* QRCODE */
"/nick",
"/note",
"/nospam",
"/quit",
"/requests",
"/status",
#ifdef AUDIO
"/lsdev",
"/sdev",
#endif /* AUDIO */
#ifdef VIDEO
"/lsvdev",
"/svdev",
2015-11-04 05:04:05 +01:00
#endif /* VIDEO */
2015-11-04 05:04:05 +01:00
#ifdef PYTHON
"/run",
#endif /* PYTHON */
};
void kill_prompt_window(ToxWindow *self)
{
ChatContext *ctx = self->chatwin;
StatusBar *statusbar = self->stb;
log_disable(ctx->log);
line_info_cleanup(ctx->hst);
delwin(ctx->linewin);
delwin(ctx->history);
delwin(statusbar->topline);
free(ctx->log);
free(ctx);
free(self->help);
free(statusbar);
del_window(self);
}
/* callback: Updates own connection status in prompt statusbar */
void on_self_connection_status(Tox *m, Tox_Connection connection_status, void *userdata)
{
UNUSED_VAR(m);
UNUSED_VAR(userdata);
StatusBar *statusbar = prompt->stb;
statusbar->connection = connection_status;
flag_interface_refresh();
}
/* Updates own nick in prompt statusbar */
void prompt_update_nick(ToxWindow *prompt, const char *nick)
{
StatusBar *statusbar = prompt->stb;
snprintf(statusbar->nick, sizeof(statusbar->nick), "%s", nick);
statusbar->nick_len = strlen(statusbar->nick);
}
2014-08-12 09:01:18 +02:00
/* Updates own statusmessage */
void prompt_update_statusmessage(ToxWindow *prompt, Tox *m, const char *statusmsg)
{
StatusBar *statusbar = prompt->stb;
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
2015-03-26 03:56:45 +01:00
size_t len = strlen(statusbar->statusmsg);
2014-08-12 09:01:18 +02:00
statusbar->statusmsg_len = len;
2015-03-26 03:56:45 +01:00
Tox_Err_Set_Info err;
tox_self_set_status_message(m, (const uint8_t *) statusmsg, len, &err);
2015-03-26 03:56:45 +01:00
if (err != TOX_ERR_SET_INFO_OK) {
line_info_add(prompt, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to set note (error %d)\n", err);
}
}
/* Updates own status in prompt statusbar */
void prompt_update_status(ToxWindow *prompt, Tox_User_Status status)
{
StatusBar *statusbar = prompt->stb;
statusbar->status = status;
}
/* Returns our own connection status */
Tox_Connection prompt_selfConnectionStatus(void)
{
StatusBar *statusbar = prompt->stb;
return statusbar->connection;
}
/* Adds friend request to pending friend requests.
Returns request number on success, -1 if queue is full. */
static int add_friend_request(const char *public_key, const char *data)
{
if (FrndRequests.max_idx >= MAX_FRIEND_REQUESTS) {
2013-12-01 23:08:57 +01:00
return -1;
}
2013-12-01 22:57:05 +01:00
for (int i = 0; i <= FrndRequests.max_idx; ++i) {
2014-09-28 23:49:48 +02:00
if (!FrndRequests.request[i].active) {
FrndRequests.request[i].active = true;
2015-02-01 21:09:48 +01:00
memcpy(FrndRequests.request[i].key, public_key, TOX_PUBLIC_KEY_SIZE);
2014-09-28 23:49:48 +02:00
snprintf(FrndRequests.request[i].msg, sizeof(FrndRequests.request[i].msg), "%s", data);
2013-10-16 23:59:56 +02:00
if (i == FrndRequests.max_idx) {
2014-09-28 23:49:48 +02:00
++FrndRequests.max_idx;
}
2014-09-28 23:49:48 +02:00
++FrndRequests.num_requests;
2013-10-16 23:59:56 +02:00
2013-12-01 22:57:05 +01:00
return i;
2013-10-16 23:59:56 +02:00
}
2013-09-16 06:28:28 +02:00
}
return -1;
}
/*
* Return true if input is recognized by handler
*/
static bool prompt_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr)
2013-08-07 00:27:51 +02:00
{
ChatContext *ctx = self->chatwin;
2013-12-04 09:57:03 +01:00
2013-10-23 09:24:08 +02:00
int x, y, y2, x2;
getyx(self->window, y, x);
getmaxyx(self->window, y2, x2);
2014-03-30 22:40:13 +02:00
UNUSED_VAR(y);
if (x2 <= 0 || y2 <= 0) {
return false;
}
2014-03-30 22:40:13 +02:00
if (ctx->pastemode && key == '\r') {
key = '\n';
}
/* ignore non-menu related input if active */
if (self->help->active) {
help_onKey(self, key);
return true;
}
if (ltr || key == '\n') { /* char is printable */
input_new_char(self, key, x, x2);
return true;
}
2014-03-30 22:40:13 +02:00
if (line_info_onKey(self, key)) {
return true;
}
2013-12-09 00:14:57 +01:00
if (input_handle(self, key, x, x2)) {
return true;
}
int input_ret = false;
2013-12-11 06:10:09 +01:00
if (key == '\t') { /* TAB key: auto-completes command */
input_ret = true;
if (ctx->len > 1 && ctx->line[0] == '/') {
int diff = -1;
if (wcsncmp(ctx->line, L"/avatar ", wcslen(L"/avatar ")) == 0) {
diff = dir_match(self, m, ctx->line, L"/avatar");
}
#ifdef PYTHON
else if (wcsncmp(ctx->line, L"/run ", wcslen(L"/run ")) == 0) {
diff = dir_match(self, m, ctx->line, L"/run");
}
#endif
else if (wcsncmp(ctx->line, L"/status ", wcslen(L"/status ")) == 0) {
const char *status_cmd_list[] = {
"online",
"away",
"busy",
};
diff = complete_line(self, status_cmd_list, sizeof(status_cmd_list) / sizeof(char *));
} else {
diff = complete_line(self, glob_cmd_list, sizeof(glob_cmd_list) / sizeof(char *));
}
2014-06-29 22:54:27 +02:00
if (diff != -1) {
if (x + diff > x2 - 1) {
int wlen = MAX(0, wcswidth(ctx->line, sizeof(ctx->line) / sizeof(wchar_t)));
ctx->start = wlen < x2 ? 0 : wlen - x2 + 1;
2014-06-29 22:54:27 +02:00
}
} else {
2015-03-26 03:56:45 +01:00
sound_notify(self, notif_error, 0, NULL);
2014-06-29 22:54:27 +02:00
}
} else {
2015-03-26 03:56:45 +01:00
sound_notify(self, notif_error, 0, NULL);
2013-12-16 02:52:10 +01:00
}
} else if (key == '\r') {
input_ret = true;
rm_trailing_spaces_buf(ctx);
2013-12-09 00:14:57 +01:00
if (!wstring_is_empty(ctx->line)) {
add_line_to_hist(ctx);
wstrsubst(ctx->line, L'', L'\n');
2014-06-04 02:35:00 +02:00
char line[MAX_STR_SIZE];
if (wcs_to_mbs_buf(line, ctx->line, MAX_STR_SIZE) == -1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED, " * Failed to parse message.");
} else {
if (strcmp(line, "/clear") != 0) {
line_info_add(self, false, NULL, NULL, PROMPT, 0, 0, "%s", line);
}
execute(ctx->history, self, m, line, GLOBAL_COMMAND_MODE);
}
}
2013-12-11 06:10:09 +01:00
wclear(ctx->linewin);
wmove(self->window, y2, 0);
reset_buf(ctx);
}
return input_ret;
}
2013-08-23 23:03:44 +02:00
static void prompt_onDraw(ToxWindow *self, Tox *m)
2013-08-07 00:27:51 +02:00
{
int x2;
int y2;
getmaxyx(self->window, y2, x2);
if (y2 <= 0 || x2 <= 0) {
return;
}
ChatContext *ctx = self->chatwin;
pthread_mutex_lock(&Winthread.lock);
line_info_print(self);
pthread_mutex_unlock(&Winthread.lock);
wclear(ctx->linewin);
2013-08-16 19:11:09 +02:00
if (ctx->len > 0) {
mvwprintw(ctx->linewin, 0, 0, "%ls", &ctx->line[ctx->start]);
}
2013-12-06 04:55:14 +01:00
curs_set(1);
StatusBar *statusbar = self->stb;
2015-08-28 03:29:34 +02:00
2013-09-28 01:55:11 +02:00
wmove(statusbar->topline, 0, 0);
2015-08-28 03:29:34 +02:00
pthread_mutex_lock(&Winthread.lock);
Tox_Connection connection = statusbar->connection;
Tox_User_Status status = statusbar->status;
2015-08-28 03:29:34 +02:00
pthread_mutex_unlock(&Winthread.lock);
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, " [");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
switch (connection) {
case TOX_CONNECTION_TCP:
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(STATUS_ONLINE));
wprintw(statusbar->topline, "TCP");
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(STATUS_ONLINE));
break;
case TOX_CONNECTION_UDP:
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(STATUS_ONLINE));
wprintw(statusbar->topline, "UDP");
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(STATUS_ONLINE));
break;
default:
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
wprintw(statusbar->topline, "Offline");
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
break;
}
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "]");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
if (status != TOX_USER_STATUS_NONE) {
2015-03-26 03:56:45 +01:00
int colour = MAGENTA;
const char *status_text = "ERROR";
2015-08-28 03:29:34 +02:00
switch (status) {
2015-03-26 03:56:45 +01:00
case TOX_USER_STATUS_AWAY:
colour = STATUS_AWAY;
status_text = "Away";
break;
2015-03-26 03:56:45 +01:00
case TOX_USER_STATUS_BUSY:
colour = STATUS_BUSY;
status_text = "Busy";
break;
default:
break;
}
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, " [");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, A_BOLD | COLOR_PAIR(colour));
wprintw(statusbar->topline, "%s", status_text);
wattroff(statusbar->topline, A_BOLD | COLOR_PAIR(colour));
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, "]");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
2015-08-28 03:29:34 +02:00
pthread_mutex_lock(&Winthread.lock);
wprintw(statusbar->topline, " %s", statusbar->nick);
2015-08-28 03:29:34 +02:00
pthread_mutex_unlock(&Winthread.lock);
} else {
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
2015-08-28 03:29:34 +02:00
pthread_mutex_lock(&Winthread.lock);
2014-09-25 10:31:45 +02:00
wprintw(statusbar->topline, " %s", statusbar->nick);
2015-08-28 03:29:34 +02:00
pthread_mutex_unlock(&Winthread.lock);
}
int s_y;
int s_x;
getyx(statusbar->topline, s_y, s_x);
mvwhline(statusbar->topline, s_y, s_x, ' ', x2 - s_x);
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
/* Reset statusbar->statusmsg on window resize */
if (x2 != self->x) {
2015-03-26 03:56:45 +01:00
char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];
pthread_mutex_lock(&Winthread.lock);
2021-11-26 14:51:38 +01:00
2015-04-10 06:16:01 +02:00
size_t slen = tox_self_get_status_message_size(m);
tox_self_get_status_message(m, (uint8_t *) statusmsg);
2021-11-26 14:51:38 +01:00
2015-04-10 06:16:01 +02:00
statusmsg[slen] = '\0';
snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg);
statusbar->statusmsg_len = strlen(statusbar->statusmsg);
2021-11-26 14:51:38 +01:00
2015-08-28 03:29:34 +02:00
pthread_mutex_unlock(&Winthread.lock);
}
self->x = x2;
/* Truncate note if it doesn't fit in statusbar */
uint16_t maxlen = x2 - getcurx(statusbar->topline) - 3;
2015-08-28 03:29:34 +02:00
pthread_mutex_lock(&Winthread.lock);
2021-11-26 14:51:38 +01:00
size_t statusmsg_len = statusbar->statusmsg_len;
pthread_mutex_unlock(&Winthread.lock);
2015-08-28 03:29:34 +02:00
2021-11-26 14:51:38 +01:00
if (statusmsg_len > maxlen) {
pthread_mutex_lock(&Winthread.lock);
statusbar->statusmsg[maxlen - 3] = 0;
strcat(statusbar->statusmsg, "...");
statusbar->statusmsg_len = maxlen;
2021-11-26 14:51:38 +01:00
pthread_mutex_unlock(&Winthread.lock);
}
2021-11-26 14:51:38 +01:00
if (statusmsg_len) {
wattron(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wprintw(statusbar->topline, " | ");
wattroff(statusbar->topline, COLOR_PAIR(BAR_ACCENT));
wattron(statusbar->topline, COLOR_PAIR(BAR_TEXT));
2021-11-26 14:51:38 +01:00
pthread_mutex_lock(&Winthread.lock);
wprintw(statusbar->topline, "%s", statusbar->statusmsg);
2021-11-26 14:51:38 +01:00
pthread_mutex_unlock(&Winthread.lock);
wattroff(statusbar->topline, COLOR_PAIR(BAR_TEXT));
}
int y;
int x;
2014-07-01 05:56:47 +02:00
getyx(self->window, y, x);
UNUSED_VAR(x);
int new_x = ctx->start ? x2 - 1 : MAX(0, wcswidth(ctx->line, ctx->pos));
wmove(self->window, y, new_x);
draw_window_bar(self);
2016-07-27 02:07:31 +02:00
wnoutrefresh(self->window);
if (self->help->active) {
help_onDraw(self);
}
}
static void prompt_onConnectionChange(ToxWindow *self, Tox *m, uint32_t friendnum, Tox_Connection connection_status)
2013-09-23 07:22:21 +02:00
{
ChatContext *ctx = self->chatwin;
char nick[TOX_MAX_NAME_LENGTH] = {0}; /* stop removing this initiation */
get_nick_truncate(m, nick, friendnum);
2014-04-01 08:48:37 +02:00
if (!nick[0]) {
2013-09-23 07:22:21 +02:00
snprintf(nick, sizeof(nick), "%s", UNKNOWN_NAME);
}
2013-09-23 07:22:21 +02:00
2014-07-27 01:16:07 +02:00
const char *msg;
2014-03-02 00:06:35 +01:00
if (user_settings->show_connection_msg == SHOW_WELCOME_MSG_OFF) {
return;
}
if (connection_status != TOX_CONNECTION_NONE && Friends.list[friendnum].connection_status == TOX_CONNECTION_NONE) {
msg = "has come online";
line_info_add(self, true, nick, NULL, CONNECTION, 0, GREEN, msg);
write_to_log(msg, nick, ctx->log, true);
2014-07-22 20:38:32 +02:00
if (self->active_box != -1) {
box_notify2(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box,
"%s has come online", nick);
} else {
2014-08-02 00:37:02 +02:00
box_notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box,
"Toxic", "%s has come online", nick);
}
} else if (connection_status == TOX_CONNECTION_NONE) {
msg = "has gone offline";
line_info_add(self, true, nick, NULL, DISCONNECTION, 0, RED, msg);
write_to_log(msg, nick, ctx->log, true);
2014-07-22 20:38:32 +02:00
if (self->active_box != -1) {
box_notify2(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box,
"%s has gone offline", nick);
} else {
2014-08-02 00:37:02 +02:00
box_notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box,
"Toxic", "%s has gone offline", nick);
}
2013-09-23 07:22:21 +02:00
}
}
/**
* Return true is the first 3 bytes of `key` are identical to any other contact in the contact list.
*/
static bool key_is_similar(const char *key)
{
for (size_t i = 0; i < Friends.max_idx; ++i) {
const ToxicFriend *friend = &Friends.list[i];
if (!friend->active) {
continue;
}
if (memcmp(friend->pub_key, key, KEY_IDENT_BYTES / 2) == 0) {
return true;
}
}
return false;
}
2015-03-26 03:56:45 +01:00
static void prompt_onFriendRequest(ToxWindow *self, Tox *m, const char *key, const char *data, size_t length)
2013-09-15 22:38:38 +02:00
{
UNUSED_VAR(m);
UNUSED_VAR(length);
ChatContext *ctx = self->chatwin;
2014-03-02 00:06:35 +01:00
line_info_add(self, true, NULL, NULL, SYS_MSG, 0, 0, "Friend request with the message '%s'", data);
write_to_log("Friend request with the message '%s'", "", ctx->log, true);
2013-09-15 22:38:38 +02:00
if (key_is_similar(key)) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"WARNING: This contact's public key is suspiciously similar to that of another contact ");
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, RED,
"in your list. This may be an impersonation attempt, or it may have occurred by chance.");
}
int n = add_friend_request(key, data);
2013-09-15 22:38:38 +02:00
2013-09-22 10:32:51 +02:00
if (n == -1) {
const char *errmsg = "Friend request queue is full. Discarding request.";
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, errmsg);
2013-09-22 10:32:51 +02:00
return;
}
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Type \"/accept %d\" or \"/decline %d\"", n, n);
2014-08-02 00:37:02 +02:00
sound_notify(self, generic_message, NT_WNDALERT_1 | NT_NOTIFWND, NULL);
2013-09-15 22:38:38 +02:00
}
2018-10-04 18:43:43 +02:00
void prompt_init_statusbar(ToxWindow *self, Tox *m, bool first_time_run)
{
2014-03-25 08:17:22 +01:00
int x2, y2;
getmaxyx(self->window, y2, x2);
if (y2 <= 0 || x2 <= 0) {
exit_toxic_err("failed in prompt_init_statusbar", FATALERR_CURSES);
}
UNUSED_VAR(y2);
/* Init statusbar info */
StatusBar *statusbar = self->stb;
2015-03-26 03:56:45 +01:00
statusbar->status = TOX_USER_STATUS_NONE;
statusbar->connection = TOX_CONNECTION_NONE;
char nick[TOX_MAX_NAME_LENGTH];
char statusmsg[TOX_MAX_STATUS_MESSAGE_LENGTH];
2015-03-26 03:56:45 +01:00
size_t n_len = tox_self_get_name_size(m);
tox_self_get_name(m, (uint8_t *) nick);
size_t s_len = tox_self_get_status_message_size(m);
tox_self_get_status_message(m, (uint8_t *) statusmsg);
Tox_User_Status status = tox_self_get_status(m);
nick[n_len] = '\0';
statusmsg[s_len] = '\0';
2018-10-04 18:43:43 +02:00
if (first_time_run) {
snprintf(statusmsg, sizeof(statusmsg), "Toxing on Toxic");
s_len = strlen(statusmsg);
statusmsg[s_len] = '\0';
}
2014-08-12 09:01:18 +02:00
prompt_update_statusmessage(prompt, m, statusmsg);
prompt_update_status(prompt, status);
prompt_update_nick(prompt, nick);
/* Init statusbar subwindow */
statusbar->topline = subwin(self->window, TOP_BAR_HEIGHT, x2, 0, 0);
2014-03-25 08:17:22 +01:00
}
static void print_welcome_msg(ToxWindow *self)
{
line_info_add(self, false, NULL, NULL, SYS_MSG, 1, BLUE, " _____ _____ _____ ____ ");
line_info_add(self, false, NULL, NULL, SYS_MSG, 1, BLUE, " |_ _/ _ \\ \\/ /_ _/ ___|");
line_info_add(self, false, NULL, NULL, SYS_MSG, 1, BLUE, " | || | | \\ / | | | ");
line_info_add(self, false, NULL, NULL, SYS_MSG, 1, BLUE, " | || |_| / \\ | | |___ ");
line_info_add(self, false, NULL, NULL, SYS_MSG, 1, BLUE, " |_| \\___/_/\\_\\___\\____| v." TOXICVER);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "");
2020-02-10 23:16:56 +01:00
const char *msg = "Welcome to Toxic, a free, open source Tox-based instant messaging client.";
line_info_add(self, false, NULL, NULL, SYS_MSG, 1, CYAN, msg);
msg = "Type \"/help\" for assistance. Further help may be found via the man page.";
line_info_add(self, false, NULL, NULL, SYS_MSG, 1, CYAN, msg);
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "");
}
static void prompt_init_log(ToxWindow *self, Tox *m, const char *self_name)
{
ChatContext *ctx = self->chatwin;
char myid[TOX_ADDRESS_SIZE];
tox_self_get_address(m, (uint8_t *) myid);
if (log_init(ctx->log, self->name, myid, NULL, LOG_TYPE_PROMPT) != 0) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Warning: Log failed to initialize.");
return;
}
if (user_settings->autolog == AUTOLOG_ON) {
if (log_enable(ctx->log) == -1) {
line_info_add(self, false, NULL, NULL, SYS_MSG, 0, 0, "Warning: Failed to enable log.");
}
}
}
2014-03-25 08:17:22 +01:00
static void prompt_onInit(ToxWindow *self, Tox *m)
{
curs_set(1);
int y2;
int x2;
2014-03-25 08:17:22 +01:00
getmaxyx(self->window, y2, x2);
if (y2 <= 0 || x2 <= 0) {
exit_toxic_err("failed in prompt_onInit", FATALERR_CURSES);
}
ChatContext *ctx = self->chatwin;
ctx->history = subwin(self->window, y2 - CHATBOX_HEIGHT - WINDOW_BAR_HEIGHT, x2, 0, 0);
self->window_bar = subwin(self->window, WINDOW_BAR_HEIGHT, x2, y2 - (CHATBOX_HEIGHT + WINDOW_BAR_HEIGHT), 0);
ctx->linewin = subwin(self->window, CHATBOX_HEIGHT, x2, y2 - WINDOW_BAR_HEIGHT, 0);
2014-03-25 08:17:22 +01:00
2014-07-04 19:24:18 +02:00
ctx->log = calloc(1, sizeof(struct chatlog));
ctx->hst = calloc(1, sizeof(struct history));
2014-03-25 08:17:22 +01:00
if (ctx->log == NULL || ctx->hst == NULL) {
exit_toxic_err("failed in prompt_onInit", FATALERR_MEMORY);
}
2014-03-25 08:17:22 +01:00
line_info_init(ctx->hst);
2014-04-07 10:42:10 +02:00
prompt_init_log(self, m, self->name);
2014-04-07 10:42:10 +02:00
scrollok(ctx->history, 0);
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
if (user_settings->show_welcome_msg == SHOW_WELCOME_MSG_ON) {
2014-09-19 07:06:18 +02:00
print_welcome_msg(self);
}
}
ToxWindow *new_prompt(void)
2013-08-07 00:27:51 +02:00
{
ToxWindow *ret = calloc(1, sizeof(ToxWindow));
2013-09-15 22:38:38 +02:00
if (ret == NULL) {
exit_toxic_err("failed in new_prompt", FATALERR_MEMORY);
}
ret->num = -1;
ret->type = WINDOW_TYPE_PROMPT;
ret->onKey = &prompt_onKey;
ret->onDraw = &prompt_onDraw;
ret->onInit = &prompt_onInit;
ret->onConnectionChange = &prompt_onConnectionChange;
ret->onFriendRequest = &prompt_onFriendRequest;
2013-09-15 22:38:38 +02:00
strcpy(ret->name, "Home");
ChatContext *chatwin = calloc(1, sizeof(ChatContext));
StatusBar *stb = calloc(1, sizeof(StatusBar));
Help *help = calloc(1, sizeof(Help));
2013-09-12 00:07:26 +02:00
if (stb == NULL || chatwin == NULL || help == NULL) {
exit_toxic_err("failed in new_prompt", FATALERR_MEMORY);
}
2014-06-18 21:54:05 +02:00
ret->chatwin = chatwin;
ret->stb = stb;
ret->help = help;
ret->active_box = -1;
2013-08-16 19:11:09 +02:00
return ret;
2013-12-01 22:59:46 +01:00
}