X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=textclient%2Fcommands.c;h=bdd2dc4e55041b96317734b3bf477ba720732b4c;hb=HEAD;hp=0c0cb99ba2d2ea211be7edb7348cf5f0b7217faa;hpb=a43fe9b2c8e3795898bf41e4c2ed4d3d8aaf8874;p=citadel.git diff --git a/textclient/commands.c b/textclient/commands.c index 0c0cb99ba..dfc3f0601 100644 --- a/textclient/commands.c +++ b/textclient/commands.c @@ -1,19 +1,11 @@ -// 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". @@ -42,11 +34,14 @@ char *helptexts[] = { " 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" @@ -60,9 +55,7 @@ char *helptexts[] = { " 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 .elp ? for additional help *** \n", + "of the command is a help file name or room name.\n" " \n" " *** USE .elp ? for additional help *** \n", // <.H>elp ADMIN "The following commands are available only to Admins. A subset of these\n" @@ -344,9 +337,6 @@ char *helptexts[] = { " you can specify a partial match\n" "\n" " <.> ead extfile formatted File 'download' commands.\n" - " <.> ead file using modem \n" - " <.> ead file using modem \n" - " <.> ead file using modem \n" " <.> ead ile unformatted \n" " <.> ead irectory \n" "\n" @@ -433,6 +423,7 @@ int rc_display_message_numbers; 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; @@ -493,7 +484,7 @@ void display_instant_messages(void) { char sender[64]; char node[64]; char *listing = NULL; - int r; // IPC result code + int r; // IPC result code if (instant_msgs == 0) { return; @@ -732,10 +723,10 @@ int yesno_d(int d) { // 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) { @@ -747,7 +738,8 @@ int ctdl_getline(char *string, int lim, int noshow, int bs) { while (num_stars--) { scr_putc('*'); } - } else { + } + else { scr_printf("%s", string); } @@ -780,7 +772,7 @@ int ctdl_getline(char *string, int lim, int noshow, int bs) { } } - else if (ch == 10) { // return + else if (ch == 10) { // return string[pos] = 0; scr_printf("\n"); return (pos); @@ -869,8 +861,9 @@ void newprompt(char *prompt, char *str, int len) { int lkey(void) { int a; a = inkey(); - if (isupper(a)) + if (isupper(a)) { a = tolower(a); + } return (a); } @@ -898,6 +891,7 @@ void load_command_set(void) { 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, ""); @@ -948,7 +942,8 @@ void load_command_set(void) { #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 @@ -997,14 +992,18 @@ void load_command_set(void) { 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; @@ -1013,7 +1012,7 @@ void load_command_set(void) { 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]); @@ -1185,10 +1184,12 @@ int getcmd(CtdlIPC * ipc, char *argbuf) { // 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 @@ -1294,7 +1295,6 @@ int getcmd(CtdlIPC * ipc, char *argbuf) { } return (cptr->c_cmdnum); - } } @@ -1330,7 +1330,7 @@ int getcmd(CtdlIPC * ipc, char *argbuf) { // 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; @@ -1346,15 +1346,15 @@ void stty_ctdl(int cmd) { if ((cmd == 0) || (cmd == 1)) { tcgetattr(0, &live); + + // Character-by-character input instead of line mode live.c_iflag = ISTRIP | IXON | IXANY; live.c_oflag = OPOST | ONLCR; live.c_lflag = ISIG | NOFLSH; + // Key bindings live.c_cc[VINTR] = 0; live.c_cc[VQUIT] = 0; - - // do we even need this stuff anymore? - // live.c_line=0; live.c_cc[VERASE] = 8; live.c_cc[VKILL] = 24; live.c_cc[VEOF] = 1; @@ -1363,9 +1363,11 @@ void stty_ctdl(int cmd) { live.c_cc[VSTART] = 0; tcsetattr(0, TCSADRAIN, &live); } + if (cmd == 2) { tcgetattr(0, &saved_settings); } + if (cmd == 3) { tcsetattr(0, TCSADRAIN, &saved_settings); } @@ -1397,13 +1399,15 @@ int fmout(int width, // screen width to use 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); @@ -1427,22 +1431,30 @@ int fmout(int width, // screen width to use // 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, " "); } @@ -1455,6 +1467,11 @@ int fmout(int width, // screen width to use 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++; @@ -1566,11 +1583,12 @@ void color(int colornum) { // 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); - + } } } @@ -1593,6 +1611,7 @@ void send_ansi_detect(void) { } +// 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; @@ -1600,21 +1619,19 @@ void look_for_ansi(void) { 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); @@ -1634,8 +1651,10 @@ void look_for_ansi(void) { } 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; } } @@ -1652,7 +1671,8 @@ void keyopt(char *buf) { if (buf[i] == '<') { scr_printf("%c", buf[i]); color(BRIGHT_MAGENTA); - } else { + } + else { if (buf[i] == '>' && buf[i + 1] != '>') { color(DIM_WHITE); }