This patch attempts to add some levels of unicode support to NetHack. The master on/off switch for any Unicode support is defining UNICODE_SUPPORT in config.h. Currently there is code support for two subsets of unicode support: UNICODE_DRAWING If UNICODE_DRAWING is defined, then the data structures used to house drawing symbols are expanded to the size of wchar_t, big enough to hold unicode characters. A typdef called `nhsym' is involved and if UNICODE_DRAWING is defined, it is wchar_t, otherwise it is uchar. UNICODE_WIDEWINPORT If UNICODE_WIDEWINPORT is defined, then the data structures inside the window port are expanded to the size of wchar_t, big enough to hold unicode characters. Both map symbols and text within the window port are expanded, in order for potential support for displaying multinational characters some day, but this patch only provides viewing of map symbols. A typdef called `nhwchar' is involved and if UNICODE_WIDEWINPORT is defined, it is wchar_t, otherwise it is char. The only window port with code support for UNICODE_WIDEWINPORT currently is the TTY port. Don't enable UNICODE_WIDEWINPORT unless: - it is a TTY port - the underlying platform specific routines can handle the larger data structures. Don't enable UNICODE_SUPPORT unless: - your compiler can handle wchar_t. - your compiler can accept L'a' characters. - your compiler can accept L"wide" strings. Note that if your compiler can handle the above, you could enable the larger data structures (currently if TTY) even if your platform can't actually display unicode or UTF-8, by messing with u_putch() in win/tty/wintty.c to only deal regular chars. That should be the only function that actually pushes wide characters out to the display. If you enable UNICODE_SUPPORT, and your platform is capable you will need to turn on the unicode run-time option to be able to load unicode character sets from the symbol file, to be able to push unicode characters to the display. You'll also want to load a unicode symbol set once the unicode option is toggled on. In a config file you would do that via these two lines: OPTIONS=unicode OPTIONS=symset:Unicode_non_US The repository was stamped with NETHACK_PRE_UNICODE prior to applying this patch, and stamped with NETHACK_POST_UNICODE afterwards. The code differences between those two tagged versions are this patch.
661 lines
17 KiB
C
661 lines
17 KiB
C
/* SCCS Id: @(#)topl.c 3.5 2003/10/05 */
|
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
|
/* NetHack may be freely redistributed. See license for details. */
|
|
|
|
#include "hack.h"
|
|
|
|
#ifdef TTY_GRAPHICS
|
|
|
|
#include "tcap.h"
|
|
#include "wintty.h"
|
|
#include <ctype.h>
|
|
|
|
#ifndef C /* this matches src/cmd.c */
|
|
#define C(c) (0x1f & (c))
|
|
#endif
|
|
|
|
STATIC_DCL void FDECL(redotoplin, (const nhwchar*));
|
|
STATIC_DCL void FDECL(topl_putsym, (NHWCHAR_P));
|
|
STATIC_DCL void NDECL(remember_topl);
|
|
STATIC_DCL void FDECL(removetopl, (int));
|
|
|
|
extern nhwchar emptysym[];
|
|
|
|
int
|
|
tty_doprev_message()
|
|
{
|
|
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
|
|
winid prevmsg_win;
|
|
int i;
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
char buf[BUFSZ];
|
|
#endif
|
|
if ((iflags.prevmsg_window != 's') && !ttyDisplay->inread) { /* not single */
|
|
if(iflags.prevmsg_window == 'f') { /* full */
|
|
prevmsg_win = create_nhwindow(NHW_MENU);
|
|
putstr(prevmsg_win, 0, "Message History");
|
|
putstr(prevmsg_win, 0, "");
|
|
cw->maxcol = cw->maxrow;
|
|
i = cw->maxcol;
|
|
do {
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
if(cw->data[i] && nhwstrcmp(cw->data[i], "") ) {
|
|
strnhwcpy(buf, cw->data[i]);
|
|
putstr(prevmsg_win, 0, buf);
|
|
#else
|
|
if(cw->data[i] && strcmp(cw->data[i], "") ) {
|
|
putstr(prevmsg_win, 0, cw->data[i]);
|
|
#endif
|
|
}
|
|
i = (i + 1) % cw->rows;
|
|
} while (i != cw->maxcol);
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
strnhwcpy(buf, toplines);
|
|
putstr(prevmsg_win, 0, buf);
|
|
#else
|
|
putstr(prevmsg_win, 0, toplines);
|
|
#endif
|
|
display_nhwindow(prevmsg_win, TRUE);
|
|
destroy_nhwindow(prevmsg_win);
|
|
} else if (iflags.prevmsg_window == 'c') { /* combination */
|
|
do {
|
|
morc = 0;
|
|
if (cw->maxcol == cw->maxrow) {
|
|
ttyDisplay->dismiss_more = C('p'); /* <ctrl/P> allowed at --More-- */
|
|
redotoplin(toplines);
|
|
cw->maxcol--;
|
|
if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
|
|
if (!cw->data[cw->maxcol])
|
|
cw->maxcol = cw->maxrow;
|
|
} else if (cw->maxcol == (cw->maxrow - 1)){
|
|
ttyDisplay->dismiss_more = C('p'); /* <ctrl/P> allowed at --More-- */
|
|
redotoplin(cw->data[cw->maxcol]);
|
|
cw->maxcol--;
|
|
if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
|
|
if (!cw->data[cw->maxcol])
|
|
cw->maxcol = cw->maxrow;
|
|
} else {
|
|
prevmsg_win = create_nhwindow(NHW_MENU);
|
|
putstr(prevmsg_win, 0, "Message History");
|
|
putstr(prevmsg_win, 0, "");
|
|
cw->maxcol = cw->maxrow;
|
|
i = cw->maxcol;
|
|
do {
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
if(cw->data[i] && nhwstrcmp(cw->data[i], "") ) {
|
|
strnhwcpy(buf, cw->data[i]);
|
|
putstr(prevmsg_win, 0, buf);
|
|
#else
|
|
if(cw->data[i] && strcmp(cw->data[i], "") ) {
|
|
putstr(prevmsg_win, 0, cw->data[i]);
|
|
#endif
|
|
}
|
|
i = (i + 1) % cw->rows;
|
|
} while (i != cw->maxcol);
|
|
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
strnhwcpy(buf, toplines);
|
|
putstr(prevmsg_win, 0, buf);
|
|
#else
|
|
putstr(prevmsg_win, 0, toplines);
|
|
#endif
|
|
display_nhwindow(prevmsg_win, TRUE);
|
|
destroy_nhwindow(prevmsg_win);
|
|
}
|
|
|
|
} while (morc == C('p'));
|
|
ttyDisplay->dismiss_more = 0;
|
|
} else { /* reversed */
|
|
morc = 0;
|
|
prevmsg_win = create_nhwindow(NHW_MENU);
|
|
putstr(prevmsg_win, 0, "Message History");
|
|
putstr(prevmsg_win, 0, "");
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
strnhwcpy(buf, toplines);
|
|
putstr(prevmsg_win, 0, buf);
|
|
#else
|
|
putstr(prevmsg_win, 0, toplines);
|
|
#endif
|
|
cw->maxcol=cw->maxrow-1;
|
|
if(cw->maxcol < 0) cw->maxcol = cw->rows-1;
|
|
do {
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
strnhwcpy(buf, cw->data[cw->maxcol]);
|
|
putstr(prevmsg_win, 0, buf);
|
|
#else
|
|
putstr(prevmsg_win, 0, cw->data[cw->maxcol]);
|
|
|
|
#endif
|
|
cw->maxcol--;
|
|
if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
|
|
if (!cw->data[cw->maxcol])
|
|
cw->maxcol = cw->maxrow;
|
|
} while (cw->maxcol != cw->maxrow);
|
|
|
|
display_nhwindow(prevmsg_win, TRUE);
|
|
destroy_nhwindow(prevmsg_win);
|
|
cw->maxcol = cw->maxrow;
|
|
ttyDisplay->dismiss_more = 0;
|
|
}
|
|
} else if(iflags.prevmsg_window == 's') { /* single */
|
|
ttyDisplay->dismiss_more = C('p'); /* <ctrl/P> allowed at --More-- */
|
|
do {
|
|
morc = 0;
|
|
if (cw->maxcol == cw->maxrow)
|
|
redotoplin(toplines);
|
|
else if (cw->data[cw->maxcol])
|
|
redotoplin(cw->data[cw->maxcol]);
|
|
cw->maxcol--;
|
|
if (cw->maxcol < 0) cw->maxcol = cw->rows-1;
|
|
if (!cw->data[cw->maxcol])
|
|
cw->maxcol = cw->maxrow;
|
|
} while (morc == C('p'));
|
|
ttyDisplay->dismiss_more = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
STATIC_OVL void
|
|
redotoplin(symstr)
|
|
const nhwchar *symstr;
|
|
{
|
|
int otoplin = ttyDisplay->toplin;
|
|
home();
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
if(*symstr >= 0x80) {
|
|
#else
|
|
if(*symstr & 0x80) {
|
|
#endif
|
|
/* kludge for the / command, the only time we ever want a */
|
|
/* graphics character on the top line */
|
|
g_putch((int)*symstr++);
|
|
ttyDisplay->curx++;
|
|
}
|
|
end_glyphout(); /* in case message printed during graphics output */
|
|
putsyms(symstr);
|
|
cl_end();
|
|
ttyDisplay->toplin = 1;
|
|
if(ttyDisplay->cury && otoplin != 3)
|
|
more();
|
|
}
|
|
|
|
STATIC_OVL void
|
|
remember_topl()
|
|
{
|
|
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
int idx = cw->maxrow;
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
unsigned len = nhwlen(toplines) + 1;
|
|
#else
|
|
unsigned len = strlen(toplines) + 1;
|
|
#endif
|
|
|
|
if (len > (unsigned)cw->datlen[idx]) {
|
|
if (cw->data[idx]) free(cw->data[idx]);
|
|
len += (8 - (len & 7)); /* pad up to next multiple of 8 */
|
|
cw->data[idx] = (nhwchar *)alloc(sizeof(nhwchar) * len);
|
|
cw->datlen[idx] = (short)len;
|
|
}
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
(void)nhwcpy(cw->data[idx], toplines);
|
|
#else
|
|
Strcpy(cw->data[idx], toplines);
|
|
#endif
|
|
cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
|
|
}
|
|
|
|
void
|
|
addtopl(s)
|
|
const nhwchar *s;
|
|
{
|
|
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
|
|
tty_curs(BASE_WINDOW,cw->curx+1,cw->cury);
|
|
putsyms(s);
|
|
cl_end();
|
|
ttyDisplay->toplin = 1;
|
|
}
|
|
|
|
void
|
|
more()
|
|
{
|
|
struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
|
|
/* avoid recursion -- only happens from interrupts */
|
|
if(ttyDisplay->inmore++)
|
|
return;
|
|
|
|
if(ttyDisplay->toplin) {
|
|
tty_curs(BASE_WINDOW, cw->curx+1, cw->cury);
|
|
if(cw->curx >= CO - 8)
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
topl_putsym(L'\n');
|
|
#else
|
|
topl_putsym('\n');
|
|
#endif
|
|
}
|
|
|
|
if(flags.standout)
|
|
standoutbeg();
|
|
putsyms(defmorestr);
|
|
if(flags.standout)
|
|
standoutend();
|
|
|
|
xwaitforspace("\033 ");
|
|
|
|
if(morc == '\033')
|
|
cw->flags |= WIN_STOP;
|
|
|
|
if(ttyDisplay->toplin && cw->cury) {
|
|
docorner(1, cw->cury+1);
|
|
cw->curx = cw->cury = 0;
|
|
home();
|
|
} else if(morc == '\033') {
|
|
cw->curx = cw->cury = 0;
|
|
home();
|
|
cl_end();
|
|
}
|
|
ttyDisplay->toplin = 0;
|
|
ttyDisplay->inmore = 0;
|
|
}
|
|
|
|
void
|
|
update_topl(bp)
|
|
register const nhwchar *bp;
|
|
{
|
|
register nhwchar *tl, *otl;
|
|
register int n0;
|
|
int notdied = 1;
|
|
struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
|
|
/* If there is room on the line, print message on same line */
|
|
/* But messages like "You die..." deserve their own line */
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
n0 = nhwlen(bp);
|
|
#else
|
|
n0 = strlen(bp);
|
|
#endif
|
|
if ((ttyDisplay->toplin == 1 || (cw->flags & WIN_STOP)) &&
|
|
cw->cury == 0 &&
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
n0 + (int)nhwlen(toplines) + 3 < CO-8 && /* room for --More-- */
|
|
(notdied = nhwncmp(bp, L"You die", 7))) {
|
|
(void)nhwcat(toplines, L" ");
|
|
(void)nhwcat(toplines, bp);
|
|
#else
|
|
n0 + (int)strlen(toplines) + 3 < CO-8 && /* room for --More-- */
|
|
(notdied = strncmp(bp, "You die", 7))) {
|
|
Strcat(toplines, " ");
|
|
Strcat(toplines, bp);
|
|
#endif
|
|
cw->curx += 2;
|
|
if(!(cw->flags & WIN_STOP))
|
|
addtopl(bp);
|
|
return;
|
|
} else if (!(cw->flags & WIN_STOP)) {
|
|
if(ttyDisplay->toplin == 1) more();
|
|
else if(cw->cury) { /* for when flags.toplin == 2 && cury > 1 */
|
|
docorner(1, cw->cury+1); /* reset cury = 0 if redraw screen */
|
|
cw->curx = cw->cury = 0;/* from home--cls() & docorner(1,n) */
|
|
}
|
|
}
|
|
remember_topl();
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
(void) nhwncpy(toplines, bp, TBUFSZ);
|
|
#else
|
|
(void) strncpy(toplines, bp, TBUFSZ);
|
|
#endif
|
|
toplines[TBUFSZ - 1] = 0;
|
|
|
|
for(tl = toplines; n0 >= CO; ){
|
|
otl = tl;
|
|
for(tl+=CO-1; tl != otl && !isspace(*tl); --tl) ;
|
|
if(tl == otl) {
|
|
/* Eek! A huge token. Try splitting after it. */
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
tl = nhwindex(otl, ' ');
|
|
#else
|
|
tl = index(otl, ' ');
|
|
#endif
|
|
if (!tl) break; /* No choice but to spit it out whole. */
|
|
}
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
*tl++ = (nhwchar)'\n';
|
|
n0 = nhwlen(tl);
|
|
#else
|
|
*tl++ = '\n';
|
|
n0 = strlen(tl);
|
|
#endif
|
|
}
|
|
if(!notdied) cw->flags &= ~WIN_STOP;
|
|
if(!(cw->flags & WIN_STOP)) redotoplin(toplines);
|
|
}
|
|
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
#define T(x) L##x
|
|
#else
|
|
#define T(x) x
|
|
#endif
|
|
|
|
STATIC_OVL
|
|
void
|
|
topl_putsym(c)
|
|
nhwchar c;
|
|
{
|
|
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
|
|
if(cw == (struct WinDesc *) 0) panic("Putsym window MESSAGE nonexistant");
|
|
|
|
switch(c) {
|
|
case T('\b'):
|
|
if(ttyDisplay->curx == 0 && ttyDisplay->cury > 0)
|
|
tty_curs(BASE_WINDOW, CO, (int)ttyDisplay->cury-1);
|
|
backsp();
|
|
ttyDisplay->curx--;
|
|
cw->curx = ttyDisplay->curx;
|
|
return;
|
|
case T('\n'):
|
|
cl_end();
|
|
ttyDisplay->curx = 0;
|
|
ttyDisplay->cury++;
|
|
cw->cury = ttyDisplay->cury;
|
|
#ifdef WIN32CON
|
|
(void) putchar(c);
|
|
#endif
|
|
break;
|
|
default:
|
|
if(ttyDisplay->curx == CO-1)
|
|
topl_putsym(T('\n')); /* 1 <= curx <= CO; avoid CO */
|
|
#ifdef WIN32CON
|
|
(void) putchar(c);
|
|
#endif
|
|
ttyDisplay->curx++;
|
|
}
|
|
cw->curx = ttyDisplay->curx;
|
|
if(cw->curx == 0) cl_end();
|
|
#ifndef WIN32CON
|
|
(void) putchar(c);
|
|
#endif
|
|
}
|
|
|
|
#undef T
|
|
|
|
void
|
|
putsyms(symstr)
|
|
const nhwchar *symstr;
|
|
{
|
|
while(*symstr)
|
|
topl_putsym(*symstr++);
|
|
}
|
|
|
|
STATIC_OVL void
|
|
removetopl(n)
|
|
register int n;
|
|
{
|
|
/* assume addtopl() has been done, so ttyDisplay->toplin is already set */
|
|
while (n-- > 0)
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
putsyms(L"\b \b");
|
|
#else
|
|
putsyms("\b \b");
|
|
#endif
|
|
}
|
|
|
|
extern char erase_char; /* from xxxtty.c; don't need kill_char */
|
|
|
|
char
|
|
tty_yn_function(query,resp, def)
|
|
const char *query,*resp;
|
|
char def;
|
|
/*
|
|
* Generic yes/no function. 'def' is the default (returned by space or
|
|
* return; 'esc' returns 'q', or 'n', or the default, depending on
|
|
* what's in the string. The 'query' string is printed before the user
|
|
* is asked about the string.
|
|
* If resp is NULL, any single character is accepted and returned.
|
|
* If not-NULL, only characters in it are allowed (exceptions: the
|
|
* quitchars are always allowed, and if it contains '#' then digits
|
|
* are allowed); if it includes an <esc>, anything beyond that won't
|
|
* be shown in the prompt to the user but will be acceptable as input.
|
|
*/
|
|
{
|
|
register char q;
|
|
char rtmp[40];
|
|
boolean digit_ok, allow_num;
|
|
struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
boolean doprev = 0;
|
|
char prompt[QBUFSZ];
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
nhwchar wprompt[QBUFSZ];
|
|
#endif
|
|
|
|
if(ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) more();
|
|
cw->flags &= ~WIN_STOP;
|
|
ttyDisplay->toplin = 3; /* special prompt state */
|
|
ttyDisplay->inread++;
|
|
if (resp) {
|
|
char *rb, respbuf[QBUFSZ];
|
|
|
|
allow_num = (index(resp, '#') != 0);
|
|
Strcpy(respbuf, resp);
|
|
/* any acceptable responses that follow <esc> aren't displayed */
|
|
if ((rb = index(respbuf, '\033')) != 0) *rb = '\0';
|
|
Sprintf(prompt, "%s [%s] ", query, respbuf);
|
|
if (def) Sprintf(eos(prompt), "(%c) ", def);
|
|
pline("%s", prompt);
|
|
} else {
|
|
pline("%s ", query);
|
|
q = readchar();
|
|
goto clean_up;
|
|
}
|
|
|
|
do { /* loop until we get valid input */
|
|
q = lowc(readchar());
|
|
if (q == '\020') { /* ctrl-P */
|
|
if (iflags.prevmsg_window != 's') {
|
|
int sav = ttyDisplay->inread;
|
|
ttyDisplay->inread = 0;
|
|
(void) tty_doprev_message();
|
|
ttyDisplay->inread = sav;
|
|
tty_clear_nhwindow(WIN_MESSAGE);
|
|
cw->maxcol = cw->maxrow;
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
nhwstrcpy(wprompt, prompt);
|
|
addtopl(wprompt);
|
|
#else
|
|
addtopl(prompt);
|
|
#endif
|
|
} else {
|
|
if(!doprev)
|
|
(void) tty_doprev_message(); /* need two initially */
|
|
(void) tty_doprev_message();
|
|
doprev = 1;
|
|
}
|
|
q = '\0'; /* force another loop iteration */
|
|
continue;
|
|
} else if (doprev) {
|
|
/* BUG[?]: this probably ought to check whether the
|
|
character which has just been read is an acceptable
|
|
response; if so, skip the reprompt and use it. */
|
|
tty_clear_nhwindow(WIN_MESSAGE);
|
|
cw->maxcol = cw->maxrow;
|
|
doprev = 0;
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
nhwstrcpy(wprompt, prompt);
|
|
addtopl(wprompt);
|
|
#else
|
|
addtopl(prompt);
|
|
#endif
|
|
q = '\0'; /* force another loop iteration */
|
|
continue;
|
|
}
|
|
digit_ok = allow_num && digit(q);
|
|
if (q == '\033') {
|
|
if (index(resp, 'q'))
|
|
q = 'q';
|
|
else if (index(resp, 'n'))
|
|
q = 'n';
|
|
else
|
|
q = def;
|
|
break;
|
|
} else if (index(quitchars, q)) {
|
|
q = def;
|
|
break;
|
|
}
|
|
if (!index(resp, q) && !digit_ok) {
|
|
tty_nhbell();
|
|
q = (char)0;
|
|
} else if (q == '#' || digit_ok) {
|
|
char z;
|
|
nhwchar digit_string[2];
|
|
int n_len = 0;
|
|
long value = 0;
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
addtopl(L"#"), n_len++;
|
|
#else
|
|
addtopl("#"), n_len++;
|
|
#endif
|
|
digit_string[1] = (nhwchar)0;
|
|
if (q != '#') {
|
|
digit_string[0] = (nhwchar)q;
|
|
addtopl(digit_string), n_len++;
|
|
value = q - '0';
|
|
q = '#';
|
|
}
|
|
do { /* loop until we get a non-digit */
|
|
z = lowc(readchar());
|
|
if (digit(z)) {
|
|
value = (10 * value) + (z - '0');
|
|
if (value < 0) break; /* overflow: try again */
|
|
digit_string[0] = (nhwchar)z;
|
|
addtopl(digit_string), n_len++;
|
|
} else if (z == 'y' || index(quitchars, z)) {
|
|
if (z == '\033') value = -1; /* abort */
|
|
z = '\n'; /* break */
|
|
} else if (z == erase_char || z == '\b') {
|
|
if (n_len <= 1) { value = -1; break; }
|
|
else { value /= 10; removetopl(1), n_len--; }
|
|
} else {
|
|
value = -1; /* abort */
|
|
tty_nhbell();
|
|
break;
|
|
}
|
|
} while (z != '\n');
|
|
if (value > 0) yn_number = value;
|
|
else if (value == 0) q = 'n'; /* 0 => "no" */
|
|
else { /* remove number from top line, then try again */
|
|
removetopl(n_len), n_len = 0;
|
|
q = '\0';
|
|
}
|
|
}
|
|
} while(!q);
|
|
|
|
if (q != '#') {
|
|
Sprintf(rtmp, "%c", q);
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
nhwstrcpy(wprompt, rtmp); /* rtmp[40] -> wprompt[128] ok */
|
|
addtopl(wprompt);
|
|
#else
|
|
addtopl(rtmp);
|
|
#endif
|
|
}
|
|
clean_up:
|
|
ttyDisplay->inread--;
|
|
ttyDisplay->toplin = 2;
|
|
if (ttyDisplay->intr) ttyDisplay->intr--;
|
|
if(wins[WIN_MESSAGE]->cury)
|
|
tty_clear_nhwindow(WIN_MESSAGE);
|
|
|
|
return q;
|
|
}
|
|
|
|
/*
|
|
* This is called by the core save routines.
|
|
* Each time we are called, we return one string from the
|
|
* message history starting with the oldest message first. each time
|
|
* we are called. Each time after that, we return a more recent message,
|
|
* until there are no more messages to return. Then we return a final
|
|
* null string.
|
|
*/
|
|
char *
|
|
tty_getmsghistory(init)
|
|
boolean init;
|
|
{
|
|
static int idx = 0, state = 0;
|
|
static boolean doneinit = FALSE;
|
|
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
char *retstr = (char *)0;
|
|
static char buf[BUFSZ];
|
|
|
|
if (!cw) return (char *)0; /* bail */
|
|
/*
|
|
* state 0 = normal return with string from msg history.
|
|
* state 1 = finished with recall data, return toplines.
|
|
* state 2 = completely finished, return null string.
|
|
*/
|
|
if (init) {
|
|
doneinit = TRUE;
|
|
state = 0;
|
|
idx = cw->maxrow;
|
|
}
|
|
if (doneinit && state < 2) {
|
|
if (state == 1) {
|
|
++state;
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
strnhwcpy(buf,toplines);
|
|
return buf;
|
|
#else
|
|
return toplines;
|
|
#endif
|
|
}
|
|
do {
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
if(cw->data[idx] && nhwcmp(cw->data[idx], emptysym) ) {
|
|
strnhwcpy(buf, cw->data[idx]);
|
|
retstr = buf;
|
|
}
|
|
#else
|
|
if(cw->data[idx] && strcmp(cw->data[idx], "") )
|
|
retstr = cw->data[idx];
|
|
|
|
#endif
|
|
idx = (idx + 1) % cw->rows;
|
|
} while (idx != cw->maxrow && !retstr);
|
|
if (idx == cw->maxrow) ++state;
|
|
}
|
|
return retstr;
|
|
}
|
|
|
|
/*
|
|
* This is called by the core savefile restore routines.
|
|
* Each time we are called, we stuff the string into our message
|
|
* history recall buffer. The core will send the oldest message
|
|
* first (actually it sends them in the order they exist in the
|
|
* save file, but that is supposed to be the oldest first).
|
|
*/
|
|
void
|
|
tty_putmsghistory(msg)
|
|
const char *msg;
|
|
{
|
|
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
|
int idx = cw->maxrow;
|
|
unsigned len = strlen(msg) + 1;
|
|
|
|
if (len > (unsigned)cw->datlen[idx]) {
|
|
if (cw->data[idx]) free(cw->data[idx]);
|
|
len += (8 - (len & 7)); /* pad up to next multiple of 8 */
|
|
cw->data[idx] = (nhwchar *)alloc(sizeof(nhwchar) * len);
|
|
cw->datlen[idx] = (short)len;
|
|
}
|
|
#ifdef UNICODE_WIDEWINPORT
|
|
(void)nhwstrcpy(cw->data[idx], msg);
|
|
#else
|
|
Strcpy(cw->data[idx], msg);
|
|
#endif
|
|
cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
|
|
}
|
|
#endif /* TTY_GRAPHICS */
|
|
|
|
/*topl.c*/
|