-// This file contains functions which implement parts of the
-// text-mode user interface.
+// This file contains functions which implement parts of the text-mode user interface.
//
-// Copyright (c) 1987-2022 by the citadel.org team
+// Copyright (c) 1987-2024 by the citadel.org team
//
-// This program is open source software. Use, duplication, and/or
-// disclosure are subject to the GNU General Purpose License version 3.
-//
-// This program 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.
+// This program is open source software. Use, duplication, or disclosure is subject to the GNU General Public License version 3.
#include "textclient.h"
-
// The help "files" are now just an embedded set of Very Long Strings. helpnames[] is
// an array of "file names" and helptexts[] is the "content".
" G Goto next room which has UNREAD messages.\n"
" H Help. Same as '?'\n"
" I Reads the Information file for this room.\n"
+ " J Jump to any named room (same as <.G>oto)\n"
" K List of Known rooms.\n"
" L Reads the last five messages in the room.\n"
+ " M Go to your private Mail room\n"
" N Reads all new messages in the room.\n"
" O Reads all old messages, backwards.\n"
" P Page another user (send an instant message)\n"
+ " Q Quiet mode on/off (disables receiving instant messages)\n"
" R Reads all messages in the room, in reverse order.\n"
" S Skips current room without making its messages old.\n"
" T Terminate (logout)\n"
" In addition, there are dot commands. You hit the . (dot), then press the\n"
"first letter of each word of the command. As you hit the letters, the words\n"
"pop onto your screen. Exceptions: after you hit .Help or .Goto, the remainder\n"
- "of the command is a help file name or room name.\n"
- " \n"
- " *** USE .<H>elp ? for additional help *** \n",
+ "of the command is a help file name or room name.\n" " \n" " *** USE .<H>elp ? for additional help *** \n",
// <.H>elp ADMIN
"The following commands are available only to Admins. A subset of these\n"
" you can specify a partial match\n"
"\n"
" <.> <R>ead <T>extfile formatted File 'download' commands.\n"
- " <.> <R>ead file using <X>modem \n"
- " <.> <R>ead file using <Y>modem \n"
- " <.> <R>ead file using <Z>modem \n"
" <.> <R>ead <F>ile unformatted \n"
" <.> <R>ead <D>irectory \n"
"\n"
int rc_force_mail_prompts;
int rc_remember_passwords;
int rc_ansi_color;
+int rc_sixel;
int rc_color_use_bg;
int rc_prompt_control = 0;
time_t rc_idle_threshold = (time_t) 900;
char sender[64];
char node[64];
char *listing = NULL;
- int r; // IPC result code
+ int r; // IPC result code
if (instant_msgs == 0) {
return;
// Function to read a line of text from the terminal.
//
-// string Pointer to string buffer
-// lim Maximum length
-// noshow Echo asterisks instead of keystrokes?
-// bs Allow backspacing out of the prompt? (returns -1 if this happens)
+// string Pointer to string buffer
+// lim Maximum length
+// noshow Echo asterisks instead of keystrokes?
+// bs Allow backspacing out of the prompt? (returns -1 if this happens)
//
// returns: string length
int ctdl_getline(char *string, int lim, int noshow, int bs) {
while (num_stars--) {
scr_putc('*');
}
- } else {
+ }
+ else {
scr_printf("%s", string);
}
}
}
- else if (ch == 10) { // return
+ else if (ch == 10) { // return
string[pos] = 0;
scr_printf("\n");
return (pos);
int lkey(void) {
int a;
a = inkey();
- if (isupper(a))
+ if (isupper(a)) {
a = tolower(a);
+ }
return (a);
}
rc_display_message_numbers = 0;
rc_force_mail_prompts = 0;
rc_ansi_color = 0;
+ rc_sixel = 0;
rc_color_use_bg = 0;
strcpy(rc_url_cmd, "");
strcpy(rc_open_cmd, "");
#ifdef HAVE_OPENSSL
else if (!strcasecmp(&buf[8], "no")) {
rc_encrypt = RC_NO;
- } else if (!strcasecmp(&buf[8], "default")) {
+ }
+ else if (!strcasecmp(&buf[8], "default")) {
rc_encrypt = RC_DEFAULT;
}
#endif
if (!strncasecmp(&buf[11], "on", 2))
rc_ansi_color = 1;
if (!strncasecmp(&buf[11], "auto", 4))
- rc_ansi_color = 2; // autodetect
+ rc_ansi_color = 2; // autodetect
if (!strncasecmp(&buf[11], "user", 4))
- rc_ansi_color = 3; // user config
+ rc_ansi_color = 3; // user config
}
if (!strncasecmp(buf, "status_line=", 12)) {
if (!strncasecmp(&buf[12], "on", 2))
enable_status_line = 1;
}
+ if (!strncasecmp(buf, "use_sixel=", 10)) {
+ if (!strncasecmp(&buf[10], "on", 2))
+ rc_sixel = 1;
+ }
if (!strncasecmp(buf, "use_background=", 15)) {
if (!strncasecmp(&buf[15], "on", 2))
rc_color_use_bg = 9;
if (!strncasecmp(&buf[15], "on", 2))
rc_prompt_control = 1;
if (!strncasecmp(&buf[15], "user", 4))
- rc_prompt_control = 3; // user config
+ rc_prompt_control = 3; // user config
}
if (!strncasecmp(buf, "username=", 9))
strcpy(rc_username, &buf[9]);
// Switch color support on or off if we're in user mode
if (rc_ansi_color == 3) {
- if (userflags & US_COLOR)
+ if (userflags & US_COLOR) {
enable_color = 1;
- else
+ }
+ else {
enable_color = 0;
+ }
}
// if we're running in idiot mode, display a cute little menu
}
return (cptr->c_cmdnum);
-
}
}
// set tty modes. commands are:
//
// 01- set to Citadel mode
-// 2 - save current settings for later restoral
+// 2 - save current settings for later restore
// 3 - restore saved settings
void stty_ctdl(int cmd) {
struct termios live;
FILE * fpin, // file to read from, or NULL to format given text
char *text, // text to be formatted (when fpin is NULL
FILE * fpout, // file to write to, or NULL to write to screen
- int subst) { // nonzero if we should use hypertext mode
+ int subst // nonzero if we should use hypertext mode
+) {
char *buffer = NULL; // The current message
char *word = NULL; // What we are about to actually print
char *e; // Pointer to position in text
char old = 0; // The previous character
int column = 0; // Current column
size_t i; // Generic counter
+ int in_quote = 0;
// Space for a single word, which can be at most screenwidth
word = (char *) calloc(1, width);
// Run the message body
while (*e) {
+
// Catch characters that shouldn't be there at all
if (*e == '\r') {
e++;
continue;
}
- if (*e == '\n') { // newline?
+
+ if ((in_quote) && (*e == '\n') && (enable_color)) {
+ in_quote = 0;
+ scr_printf("\033[22m\033[22m");
+ }
+
+ if (*e == '\n') { // newline?
e++;
- if (*e == ' ') { // paragraph?
+ if (*e == ' ') { // paragraph?
if (fpout) {
fprintf(fpout, "\n");
- } else {
+ }
+ else {
scr_printf("\n");
}
column = 0;
}
- else if (old != ' ') { // Don't print two spaces
+ else if (old != ' ') { // Don't print two spaces
if (fpout) {
fprintf(fpout, " ");
}
continue;
}
+ if ((*e == '>') && (column <= 1) && (!fpout) && (enable_color)) {
+ in_quote = 1;
+ scr_printf("\033[2m\033[2m");
+ }
+
// Or are we looking at a space?
if (*e == ' ') {
e++;
// terminals. - Changed to ORIGINAL_PAIR as this actually
// wound up looking horrible on black-on-white terminals, not
// to mention transparent terminals.
- if (colornum == ORIGINAL_PAIR)
+ if (colornum == ORIGINAL_PAIR) {
printf("\033[0;39;49m");
- else
+ }
+ else {
printf("\033[%d;3%d;4%dm", (colornum & 8) ? 1 : 0, (colornum & 7), rc_color_use_bg);
-
+ }
}
}
}
+// Turn ANSI color (etc.) support on, or off, or auto-detect support, depending on the configuration
void look_for_ansi(void) {
fd_set rfds;
struct timeval tv;
time_t now;
int a, rv;
- if (rc_ansi_color == 0) {
+ if (rc_ansi_color == 0) { // Configured to never use color
enable_color = 0;
}
- else if (rc_ansi_color == 1) {
+ else if (rc_ansi_color == 1) { // Configured to always use color
enable_color = 1;
}
- else if (rc_ansi_color == 2) {
-
- /* otherwise, do the auto-detect */
+ else if (rc_ansi_color == 2) { // Configured to auto-detect ANSI color support
strcpy(abuf, "");
-
time(&now);
- if ((now - AnsiDetect) < 2)
+ if ((now - AnsiDetect) < 2) {
sleep(1);
+ }
do {
FD_ZERO(&rfds);
} while (FD_ISSET(0, &rfds));
for (a = 0; !IsEmptyStr(&abuf[a]); ++a) {
- if ((abuf[a] == 27) && (abuf[a + 1] == '[')
- && (abuf[a + 2] == '?')) {
+ if ( (abuf[a] == 27)
+ && (abuf[a + 1] == '[')
+ && (abuf[a + 2] == '?')
+ ) { // ANSI support was detected!
enable_color = 1;
}
}
if (buf[i] == '<') {
scr_printf("%c", buf[i]);
color(BRIGHT_MAGENTA);
- } else {
+ }
+ else {
if (buf[i] == '>' && buf[i + 1] != '>') {
color(DIM_WHITE);
}