* This file contains functions which implement parts of the
* text-mode user interface.
*
- * Copyright (c) 1987-2009 by the citadel.org team
+ * Copyright (c) 1987-2012 by the citadel.org team
*
- * This program 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.
+ * This program is open source software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 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.
*/
#include "sysdep.h"
#include "rooms.h"
#include "client_chat.h"
#include "citadel_dirs.h"
+#include "tuiconfig.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
char rc_open_cmd[SIZ];
char rc_gotmail_cmd[SIZ];
-char *gl_string;
int next_lazy_cmd = 5;
-int lines_printed = 0; /* line count for paginator */
extern int screenwidth, screenheight;
extern int termn8;
extern CtdlIPC *ipc_for_signal_handlers; /* KLUDGE cover your eyes */
* in the middle of a data transfer from the server, in which case
* sending a NOOP would throw the client protocol out of sync.
*/
- if (FD_ISSET(0, &rfds)) {
+ if ((retval > 0) && FD_ISSET(0, &rfds)) {
set_keepalives(KA_NO);
the_character = inkey();
set_keepalives(KA_YES);
-/*
- * Check to see if we need to pause at the end of a screen.
- * If we do, we have to switch to half keepalives during the pause because
- * we are probably in the middle of a server operation and the NOOP command
- * would confuse everything.
- */
-int checkpagin(int lp, unsigned int pagin, unsigned int height)
-{
- int thekey;
-
- if (sigcaught) return(lp);
- thekey = was_a_key_pressed();
- if (thekey == 'q' || thekey == 'Q' || thekey == 's' || thekey == 'S')
- thekey = STOP_KEY;
- if (thekey == 'n' || thekey == 'N')
- thekey = NEXT_KEY;
- if ( (thekey == NEXT_KEY) || (thekey == STOP_KEY)) sigcaught = thekey;
- if (sigcaught) return(lp);
-
- if (!pagin) return(0);
- if (lp>=(height-1)) {
- set_keepalives(KA_HALF);
- hit_any_key(ipc_for_signal_handlers); /* Cheating -IO */
- set_keepalives(KA_YES);
- return(0);
- }
- return(lp);
-}
-
-
-
-
-/*
- * pprintf() ... paginated version of printf()
- */
-void pprintf(const char *format, ...) {
- va_list arg_ptr;
- static char buf[4096]; /* static for performance, change if needed */
- int i;
-
- /* If sigcaught is nonzero, a keypress has interrupted this and we
- * should just drain output.
- */
- if (sigcaught) return;
-
- /* Otherwise, start spewing... */
- va_start(arg_ptr, format);
- vsnprintf(buf, sizeof(buf), format, arg_ptr);
- va_end(arg_ptr);
-
- for (i=0; !IsEmptyStr(&buf[i]); ++i) {
- scr_putc(buf[i]);
- if (buf[i]==10) {
- ++lines_printed;
- lines_printed = checkpagin(lines_printed,
- (userflags & US_PAGINATOR),
- screenheight);
- }
- }
-}
-
-
-
/*
* print_instant() - print instant messages if there are any
*/
}
/* fall back to built-in instant message display */
scr_printf("\n");
- lines_printed++;
/* Header derived from flags */
if (flags & 2)
scr_printf(" @%s", node);
scr_printf(":\n");
- lines_printed++;
- fmout(screenwidth, NULL, listing, NULL, 1, screenheight, -1, 0);
+ fmout(screenwidth, NULL, listing, NULL, 0);
free(listing);
- /* when running in curses mode, the scroll bar in most
- xterm-style programs becomes useless, so it makes sense to
- pause after a screenful of pages if the user has been idle
- for a while. However, this is annoying to some of the users
- who aren't in curses mode and tend to leave their clients
- idle. keepalives become disabled, resulting in getting booted
- when coming back to the idle session. but they probably have
- a working scrollback in their terminal, so disable it in this
- case:
- */
- if (!is_curses_enabled())
- lines_printed = 0;
}
scr_printf("\n---\n");
color(BRIGHT_WHITE);
static time_t idlet = 0;
static void really_do_keepalive(void) {
- int r; /* IPC response code */
time(&idlet);
* wait for a response.
*/
if (keepalives_enabled == KA_YES) {
- r = CtdlIPCNoop(ipc_for_signal_handlers);
+ CtdlIPCNoop(ipc_for_signal_handlers);
if (instant_msgs > 0) {
if (ok_to_interrupt == 1) {
scr_printf("\r%64s\r", "");
time_t start_time;
scr_flush();
- lines_printed = 0;
time(&start_time);
do {
* necessary and then waits again.
*/
do {
- scr_set_windowsize(ipc_for_signal_handlers);
do_keepalive();
- scr_set_windowsize(ipc_for_signal_handlers);
FD_ZERO(&rfds);
FD_SET(0, &rfds);
if (a == 13) {
a = 10;
}
-/* not so fast there dude, we have to handle UTF-8 and ISO-8859-1...
- if (a > 126) {
- a = 0;
- }
- if (((a != 23) && (a != 4) && (a != 10) && (a != 8) && (a != NEXT_KEY) && (a != STOP_KEY))
- && ((a < 32) || (a > 126))) {
- a = 0;
- }
- */
-
-#ifndef DISABLE_CURSES
-#if defined(HAVE_CURSES_H) || defined(HAVE_NCURSES_H)
- if (a == ERR) {
- logoff(NULL, 3);
- }
-#endif
-#endif
-
} while (a == 0);
return (a);
}
-/* Gets a line from the terminal */
-/* string == Pointer to string buffer */
-/* lim == Maximum length - if negative, no-show */
-void ctdl_getline(char *string, int lim)
+/*
+ * 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: string length
+ */
+int ctdl_getline(char *string, int lim, int noshow, int bs)
{
int a, b;
- char flag = 0;
- if (lim < 0) {
- lim = (0 - lim);
- flag = 1;
- }
strcpy(string, "");
- gl_string = string;
async_ka_start();
GLA: a = inkey();
- /* a = (a & 127); ** commented out because it isn't just an ASCII world anymore */
if ((a == 8 || a == 23) && (IsEmptyStr(string)))
goto GLA;
if ((a != 10) && (a != 8) && (strlen(string) == lim))
if ((a == 10)) {
scr_putc(10);
async_ka_end();
- return;
+ return(strlen(string));
}
- if (a < 32)
+ if (a < 32) {
a = '.';
+ }
b = strlen(string);
string[b] = a;
string[b + 1] = 0;
- if (flag == 0)
- scr_putc(a);
- if (flag == 1)
+ if (noshow) {
scr_putc('*');
+ }
+ else {
+ scr_putc(a);
+ }
goto GLA;
}
-/*
- * strprompt() - prompt for a string, print the existing value and
- * allow the user to press return to keep it...
+/*
+ * newprompt() prompt for a string, print the existing value, and
+ * allow the user to press return to keep it...
+ * If len is negative, pass the "noshow" flag to ctdl_getline()
*/
void strprompt(char *prompt, char *str, int len)
{
color(DIM_WHITE);
scr_printf(": ");
color(BRIGHT_CYAN);
- ctdl_getline(buf, len);
- if (buf[0] != 0)
+ ctdl_getline(buf, abs(len), (len<0), 0);
+ if (buf[0] != 0) {
strcpy(str, buf);
+ }
color(DIM_WHITE);
}
}
/*
- * newprompt() - prompt for a string with no existing value
- * (clears out string buffer first)
+ * newprompt() prompt for a string with no existing value
+ * (clears out string buffer first)
+ * If len is negative, pass the "noshow" flag to ctdl_getline()
*/
void newprompt(char *prompt, char *str, int len)
{
+ str[0] = 0;
color(BRIGHT_MAGENTA);
scr_printf("%s", prompt);
color(DIM_MAGENTA);
- ctdl_getline(str, len);
+ ctdl_getline(str, abs(len), (len<0), 0);
color(DIM_WHITE);
}
{
FILE *ccfile;
char buf[1024];
- char editor_key[100];
struct citcmd *cptr;
struct citcmd *lastcmd = NULL;
int a, d;
int b = 0;
- int i;
-
/* first, set up some defaults for non-required variables */
- for (i = 0; i < MAX_EDITORS; i++)
- strcpy(editor_paths[i], "");
+ strcpy(editor_path, "");
strcpy(printcmd, "");
strcpy(imagecmd, "");
strcpy(rc_username, "");
#ifdef HAVE_OPENSSL
rc_encrypt = RC_DEFAULT;
#endif
-#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
- rc_screen = RC_DEFAULT;
-#endif
- rc_alt_semantics = 0;
/* now try to open the citadel.rc file */
#endif
}
-#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
- if (!strncasecmp(buf, "fullscreen=", 11)) {
- if (!strcasecmp(&buf[11], "yes"))
- rc_screen = RC_YES;
- else if (!strcasecmp(&buf[11], "no"))
- rc_screen = RC_NO;
- }
-#endif
-
- if (!strncasecmp(buf, "editor=", 7))
- strcpy(editor_paths[0], &buf[7]);
-
- for (i = 0; i < MAX_EDITORS; i++)
- {
- sprintf(editor_key, "editor%d=", i);
- if (!strncasecmp(buf, editor_key, strlen(editor_key)))
- strcpy(editor_paths[i], &buf[strlen(editor_key)]);
+ if (!strncasecmp(buf, "editor=", 7)) {
+ strcpy(editor_path, &buf[7]);
}
if (!strncasecmp(buf, "printcmd=", 9))
if (!strncasecmp(buf, "expcmd=", 7))
strcpy(rc_exp_cmd, &buf[7]);
- if (!strncasecmp(buf, "local_screen_dimensions=", 24))
- have_xterm = (char) atoi(&buf[24]);
-
if (!strncasecmp(buf, "use_floors=", 11)) {
if (!strcasecmp(&buf[11], "yes"))
rc_floor_mode = RC_YES;
if (!strncasecmp(&buf[11], "user", 4))
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_background=", 15)) {
if (!strncasecmp(&buf[15], "on", 2))
rc_color_use_bg = 9;
if (!strncasecmp(buf, "gotmailcmd=", 11))
strcpy(rc_gotmail_cmd, &buf[11]);
- if (!strncasecmp(buf, "alternate_semantics=", 20)) {
- if (!strncasecmp(&buf[20], "yes", 3)) {
- rc_alt_semantics = 1;
- }
- else {
- rc_alt_semantics = 0;
- }
- }
-
if (!strncasecmp(buf, "cmd=", 4)) {
strcpy(buf, &buf[4]);
scr_printf("\n%s", room_name);
color(DIM_WHITE);
scr_printf("%c ", room_prompt(room_flags));
- scr_flush();
while (1) {
ch = inkey();
if (cmdmatch(cmdbuf, cptr, 5)) {
/* We've found our command. */
if (requires_string(cptr, cmdpos)) {
- ctdl_getline(argbuf, 64);
+ argbuf[0] = 0;
+ ctdl_getline(argbuf, 64, 0, 0);
} else {
scr_printf("\n");
}
}
if (ch == '?') {
- pprintf("\rOne of ... \n");
+ scr_printf("\rOne of ... \n");
for (cptr = cmdlist; cptr != NULL; cptr = cptr->next) {
if (cmdmatch(cmdbuf, cptr, cmdpos)) {
for (a = 0; a < 5; ++a) {
keyopt(cmd_expand(cptr->c_keys[a], 1));
- pprintf(" ");
+ scr_printf(" ");
}
- pprintf("\n");
+ scr_printf("\n");
}
}
sigcaught = 0;
- pprintf("\n%s%c ", room_name, room_prompt(room_flags));
+ scr_printf("\n%s%c ", room_name, room_prompt(room_flags));
got = 0;
for (cptr = cmdlist; cptr != NULL; cptr = cptr->next) {
if ((got == 0) && (cmdmatch(cmdbuf, cptr, cmdpos))) {
for (a = 0; a < cmdpos; ++a) {
- pprintf("%s ",
+ scr_printf("%s ",
cmd_expand(cptr->c_keys[a], 0));
}
got = 1;
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 */
- char pagin, /* nonzero if we should use the paginator */
- int height, /* screen height to use */
- int starting_lp,/* starting value for lines_printed, -1 for global */
int subst) /* nonzero if we should use hypertext mode */
{
char *buffer = NULL; /* The current message */
/* Space for a single word, which can be at most screenwidth */
word = (char *)calloc(1, width);
if (!word) {
- err_printf("Can't alloc memory to print message: %s!\n",
+ scr_printf("Can't alloc memory to print message: %s!\n",
strerror(errno));
logoff(NULL, 3);
}
if (fpin) {
buffer = load_message_from_file(fpin);
if (!buffer) {
- err_printf("Can't print message: %s!\n",
+ scr_printf("Can't print message: %s!\n",
strerror(errno));
logoff(NULL, 3);
}
}
e = buffer;
- if (starting_lp >= 0)
- lines_printed = starting_lp;
-
/* Run the message body */
while (*e) {
/* Catch characters that shouldn't be there at all */
fprintf(fpout, "\n");
} else {
scr_printf("\n");
- ++lines_printed;
- lines_printed = checkpagin(lines_printed, pagin, height);
}
column = 0;
} else if (old != ' ') {/* Don't print two spaces */
fprintf(fpout, "\n");
} else {
scr_printf("\n");
- ++lines_printed;
- lines_printed = checkpagin(lines_printed, pagin, height);
}
column = 0;
} else if (!(column == 0 && old == ' ')) {
fprintf(fpout, "\n");
} else {
scr_printf("\n");
- ++lines_printed;
- lines_printed = checkpagin(lines_printed, pagin, height);
}
column = 0;
}
fprintf(fpout, "\n");
} else {
scr_printf("\n");
- ++lines_printed;
- lines_printed = checkpagin(lines_printed, pagin, height);
}
return sigcaught;
current_color = colornum;
if (enable_color) {
-#if defined(HAVE_CURSES_H) && !defined(DISABLE_CURSES)
- if (scr_color(colornum))
- return;
-#endif
/* When switching to dim white, actually output an 'original
* pair' sequence -- this looks better on black-on-white
* terminals. - Changed to ORIGINAL_PAIR as this actually
(colornum & 7),
rc_color_use_bg);
- scr_flush();
}
}
if (enable_color) {
printf("\033[4%dm\033[2J\033[H\033[0m",
colornum ? colornum : rc_color_use_bg);
- scr_flush();
}
}
if (FD_ISSET(0, &rfds)) {
abuf[strlen(abuf) + 1] = 0;
rv = read(0, &abuf[strlen(abuf)], 1);
+ if (rv < 0) {
+ scr_printf("failed to read after select: %s",
+ strerror(errno));
+ break;
+ }
}
} while (FD_ISSET(0, &rfds));
color(DIM_WHITE);
for (i=0; !IsEmptyStr(&buf[i]); ++i) {
if (buf[i]=='<') {
- pprintf("%c", buf[i]);
+ scr_printf("%c", buf[i]);
color(BRIGHT_MAGENTA);
} else {
if (buf[i]=='>'&& buf[i+1] != '>') {
color(DIM_WHITE);
}
- pprintf("%c", buf[i]);
+ scr_printf("%c", buf[i]);
}
}
color(DIM_WHITE);