/* wutil.c
*
* Copyright (c) 1993-2005 Mike Gleason, NcFTP Software.
* All rights reserved.
*
*/
#include "syshdrs.h"
#ifdef PRAGMA_HDRSTOP
# pragma hdrstop
#endif
#include "../ncftp/util.h"
#include "wutil.h"
int gWinInit = 0;
int gScreenWidth = 0;
int gScreenHeight = 0;
void
EndWin(void)
{
if (gWinInit) {
gWinInit = 0;
/* Ideally we would save the whole screen of data before
* starting, and restore it here.
*/
wclear(stdscr);
refresh();
endwin();
}
} /* EndWin */
void
Exit(int exitStatus)
{
EndWin();
exit(exitStatus);
} /* Exit */
#ifdef NOT_USED_YET
void
SaveScreen(void)
{
if (gWinInit) {
/* Clearing the screen is necessary
* because ncurses doesn't move the
* cursor to the bottom left.
*
* This also causes the restore
* operation to require that we paint
* all our windows by hand, because we
* have just left the screen blank so
* when refresh gets called in the
* restore it just returns the screen
* to blank.
*
* If it weren't for this screen clear,
* we would be able to get away with
* just doing an endwin(), the shell,
* and then a refresh() without us
* re-drawing any windows manually.
*/
wclear(stdscr);
refresh();
endwin();
fflush(stdout);
fflush(stderr);
}
} /* SaveScreen */
void
TTYWaitForReturn(void)
{
int tty;
int junk;
tty = open("/dev/tty", O_RDWR);
if (tty != -1) {
write(tty, "[Hit return]", 12);
read(tty, &junk, 1);
close(tty);
}
} /* TTYWaitForReturn */
void
RestoreScreen(int pressKey)
{
if (gWinInit) {
if (pressKey) {
# if !defined(CURSES_SHELL_BUG) || (CURSES_SHELL_BUG == 0)
TTYWaitForReturn();
# else
sleep(2);
# endif
}
refresh();
/* UpdateScreen(1); */
}
} /* RestoreScreen */
void
Beep(int on)
{
static time_t lastBeepTime = 0;
time_t now;
time(&now);
/* Don't flood the user with beeps. Once per two seconds is reasonable. */
if ((on > 0) && ((int) (now - lastBeepTime) > 1)) {
if (gWinInit)
BEEP(1);
else
{
fprintf(stderr, "\007"); /* ^G */
fflush(stderr);
}
}
lastBeepTime = now;
} /* Beep */
#endif /* NOT_USED_YET */
#if !defined(HAVE_GETCURX) && defined(HAVE_GETYX)
static int
getcurx(WINDOW *const w)
{
int cx, cy;
NCFTP_USE_VAR(cy);
getyx(w, cy, cx);
return (cx);
} /* getcurx */
#endif
/* Sometimes ncurses' wclrtoeol() gets confused when reverse text was on.
* This forces is to use space characters to blank out the line instead
* of the tty's clear-to-end-of-line built-in, if present.
*/
void
swclrtoeol(WINDOW *w)
{
int maxx;
int curx;
maxx = getmaxx(w);
curx = getcurx(w);
for ( ; curx < maxx; curx++)
waddch(w, ' ');
} /* swclrtoeol */
/* Many old curses libraries don't support wattron() and its attributes.
* They should support wstandout() though. This routine is an attempt
* to use the best substitute available, depending on what the curses
* library has.
*/
void
WAttr(WINDOW *w, int attr, int on)
{
/* Define PLAIN_TEXT_ONLY if you have the attributes, but don't want
* to use them.
*/
#ifndef PLAIN_TEXT_ONLY
#ifdef A_REVERSE
if (attr & kReverse) {
if (on)
wattron(w, A_REVERSE);
else
wattroff(w, A_REVERSE);
}
#else
if (attr & kReverse) {
if (on)
wstandout(w);
else
wstandend(w);
/* Nothing else will be done anyway, so just return now. */
return;
}
#endif /* A_REVERSE */
#ifdef A_BOLD
if (attr & kBold) {
if (on)
wattron(w, A_BOLD);
else
wattroff(w, A_BOLD);
}
#else
/* Do nothing. Plain is best substitute. */
#endif /* A_BOLD */
#ifdef A_UNDERLINE
if (attr & kUnderline) {
if (on)
wattron(w, A_UNDERLINE);
else
wattroff(w, A_UNDERLINE);
}
#else
/* Try using standout mode in place of underline. */
if (attr & kUnderline) {
if (on)
wstandout(w);
else
wstandend(w);
/* Nothing else will be done anyway, so just return now. */
return;
}
#endif /* A_UNDERLINE */
#ifdef A_DIM
if (attr & kDim) {
if (on)
wattron(w, A_DIM);
else
wattroff(w, A_DIM);
}
#else
/* Do nothing. Plain is best substitute. */
#endif /* A_DIM */
#ifdef A_NORMAL
if (attr == kNormal) {
wattrset(w, A_NORMAL);
return;
}
#else
/* At least make sure standout mode is off. */
if (attr == kNormal) {
wstandend(w);
return;
}
#endif /* A_NORMAL */
#endif /* PLAIN_TEXT_ONLY */
} /* WAttr */
void DrawStrAt(WINDOW *const win, int y, int x, const char *const str)
{
#if defined(WADDSTR_TYPE_ARG1_CONST) && !defined(FREEBSD)
mvwaddstr(win, y, x, str);
#else
/* Ugly hack for systems whose mvwaddstr takes a (char *) rather than
* a (const char *).
*/
char *cp = strdup(str);
if (cp == NULL)
return;
mvwaddstr(win, y, x, cp);
free(cp);
#endif
} /* DrawStrAt */
/* Draws a string centered in a window. */
void WAddCenteredStr(WINDOW *const w, int y, const char *const str)
{
int x;
int maxx;
maxx = getmaxx(w);
x = (maxx - (int) strlen(str)) / 2;
if (x < 0)
x = 0;
DrawStrAt(w, y, x, str);
} /* WAddCenteredStr */
static void
SigTerm(int UNUSED(sig))
{
LIBNCFTP_USE_VAR(sig);
Exit(1);
} /* SigTerm */
#ifndef NCURSES_VERSION
#ifdef SIGTSTP
static void
SigTstp(int UNUSED(sig))
{
LIBNCFTP_USE_VAR(sig);
/* TO-DO */
/* Ncurses is smart enough to handle this for us,
* but for those other curses libs, we should really
* suspend gracefully instead of exiting.
*/
Exit(1);
} /* SigTstp */
#endif
#endif
int
InitWindows(void)
{
int maxx = 0, maxy = 0;
gWinInit = 0;
initscr();
if (stdscr == NULL)
return (-1);
gWinInit = 1;
NcSignal(SIGTERM, SigTerm);
nl();
noecho(); /* Leave this off until we need it. */
getmaxyx(stdscr, maxy, maxx);
gScreenWidth = maxx;
gScreenHeight = maxy;
#ifndef NCURSES_VERSION
#ifdef SIGTSTP
if (NcSignal(SIGTSTP, (FTPSigProc) SIG_IGN) != (FTPSigProc) SIG_IGN) {
NcSignal(SIGTSTP, SigTstp);
NcSignal(SIGCONT, SigTstp);
}
#endif
#endif
return (0);
} /* InitWindows */
int
PrintDimensions(int shortMode)
{
int maxy = 0, maxx = 0;
char buf[128];
initscr();
if (stdscr == NULL)
return (-1);
getmaxyx(stdscr, maxy, maxx);
endwin();
if ((maxx > 0) && (maxy > 0)) {
memset(buf, 0, sizeof(buf));
#ifdef HAVE_SNPRINTF
(void) snprintf(
buf,
sizeof(buf) - 1,
#else
(void) sprintf(
buf,
#endif
(shortMode != 0) ? "%d %d\n" : "COLUMNS=%d\nLINES=%d\nexport COLUMNS\nexport LINES\n",
maxx,
maxy
);
(void) write(1, buf, strlen(buf));
return (0);
}
return (-1);
} /* PrintDimensions */
syntax highlighted by Code2HTML, v. 0.9.1