tty messge history restore (trunk only)
This commit is contained in:
@@ -48,6 +48,7 @@ struct WinDesc {
|
|||||||
/* window flags */
|
/* window flags */
|
||||||
#define WIN_CANCELLED 1
|
#define WIN_CANCELLED 1
|
||||||
#define WIN_STOP 1 /* for NHW_MESSAGE; stops output */
|
#define WIN_STOP 1 /* for NHW_MESSAGE; stops output */
|
||||||
|
#define WIN_LOCKHISTORY 2 /* for NHW_MESSAGE; suppress history updates */
|
||||||
|
|
||||||
/* descriptor for tty-based displays -- all the per-display data */
|
/* descriptor for tty-based displays -- all the per-display data */
|
||||||
struct DisplayDesc {
|
struct DisplayDesc {
|
||||||
|
|||||||
@@ -1155,6 +1155,7 @@ register int fd;
|
|||||||
putmsghistory(msg);
|
putmsghistory(msg);
|
||||||
++msgcount;
|
++msgcount;
|
||||||
}
|
}
|
||||||
|
if (msgcount) putmsghistory((char *)0);
|
||||||
#ifdef DEBUG_MSGCOUNT
|
#ifdef DEBUG_MSGCOUNT
|
||||||
pline("Read %d messages from savefile.", msgcount);
|
pline("Read %d messages from savefile.", msgcount);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+144
-62
@@ -18,6 +18,8 @@ STATIC_DCL void FDECL(redotoplin, (const nhwchar*));
|
|||||||
STATIC_DCL void FDECL(topl_putsym, (NHWCHAR_P));
|
STATIC_DCL void FDECL(topl_putsym, (NHWCHAR_P));
|
||||||
STATIC_DCL void NDECL(remember_topl);
|
STATIC_DCL void NDECL(remember_topl);
|
||||||
STATIC_DCL void FDECL(removetopl, (int));
|
STATIC_DCL void FDECL(removetopl, (int));
|
||||||
|
STATIC_DCL void FDECL(msghistory_snapshot, (BOOLEAN_P));
|
||||||
|
STATIC_DCL void FDECL(free_msghistory_snapshot, (BOOLEAN_P));
|
||||||
|
|
||||||
extern nhwchar emptysym[];
|
extern nhwchar emptysym[];
|
||||||
|
|
||||||
@@ -185,12 +187,15 @@ remember_topl()
|
|||||||
{
|
{
|
||||||
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
||||||
int idx = cw->maxrow;
|
int idx = cw->maxrow;
|
||||||
#ifdef UNICODE_WIDEWINPORT
|
unsigned len;
|
||||||
unsigned len = nhwlen(toplines) + 1;
|
|
||||||
#else
|
|
||||||
unsigned len = strlen(toplines) + 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
if ((cw->flags & WIN_LOCKHISTORY) || !*toplines) return;
|
||||||
|
|
||||||
|
#ifdef UNICODE_WIDEWINPORT
|
||||||
|
len = nhwlen(toplines) + 1;
|
||||||
|
#else
|
||||||
|
len = strlen(toplines) + 1;
|
||||||
|
#endif
|
||||||
if (len > (unsigned)cw->datlen[idx]) {
|
if (len > (unsigned)cw->datlen[idx]) {
|
||||||
if (cw->data[idx]) free(cw->data[idx]);
|
if (cw->data[idx]) free(cw->data[idx]);
|
||||||
len += (8 - (len & 7)); /* pad up to next multiple of 8 */
|
len += (8 - (len & 7)); /* pad up to next multiple of 8 */
|
||||||
@@ -202,6 +207,7 @@ remember_topl()
|
|||||||
#else
|
#else
|
||||||
Strcpy(cw->data[idx], toplines);
|
Strcpy(cw->data[idx], toplines);
|
||||||
#endif
|
#endif
|
||||||
|
*toplines = '\0';
|
||||||
cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
|
cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,63 +581,113 @@ char def;
|
|||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* shared by tty_getmsghistory() and tty_putmsghistory() */
|
||||||
|
static nhwchar **snapshot_mesgs = 0;
|
||||||
|
|
||||||
|
/* collect currently available message history data into a sequential array;
|
||||||
|
optionally, purge that data from the active circular buffer set as we go */
|
||||||
|
STATIC_OVL void
|
||||||
|
msghistory_snapshot(purge)
|
||||||
|
boolean purge; /* clear message history buffer as we copy it */
|
||||||
|
{
|
||||||
|
nhwchar *mesg;
|
||||||
|
unsigned ln;
|
||||||
|
int i, inidx, outidx;
|
||||||
|
struct WinDesc *cw;
|
||||||
|
|
||||||
|
/* paranoia (too early or too late panic save attempt?) */
|
||||||
|
if (WIN_MESSAGE == WIN_ERR || !wins[WIN_MESSAGE]) return;
|
||||||
|
cw = wins[WIN_MESSAGE];
|
||||||
|
|
||||||
|
/* flush toplines[], moving most recent message to history */
|
||||||
|
remember_topl();
|
||||||
|
|
||||||
|
/* for a passive snapshot, we just copy pointers, so can't allow further
|
||||||
|
history updating to take place because that could clobber them */
|
||||||
|
if (!purge) cw->flags |= WIN_LOCKHISTORY;
|
||||||
|
|
||||||
|
snapshot_mesgs = (nhwchar **)alloc((cw->rows + 1) * sizeof (nhwchar *));
|
||||||
|
outidx = 0;
|
||||||
|
inidx = cw->maxrow;
|
||||||
|
for (i = 0; i < cw->rows; ++i) {
|
||||||
|
snapshot_mesgs[i] = (nhwchar *)0;
|
||||||
|
mesg = cw->data[inidx];
|
||||||
|
if (mesg && *mesg) {
|
||||||
|
snapshot_mesgs[outidx++] = mesg;
|
||||||
|
if (purge) {
|
||||||
|
/* we're taking this pointer away; subsequest history
|
||||||
|
updates will eventually allocate a new one to replace it */
|
||||||
|
cw->data[inidx] = (nhwchar *)0;
|
||||||
|
cw->datlen[inidx] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inidx = (inidx + 1) % cw->rows;
|
||||||
|
}
|
||||||
|
snapshot_mesgs[cw->rows] = (nhwchar *)0; /* sentinel */
|
||||||
|
|
||||||
|
/* for a destructive snapshot, history is now completely empty */
|
||||||
|
if (purge) cw->maxcol = cw->maxrow = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release memory allocated to message history snapshot */
|
||||||
|
STATIC_OVL void
|
||||||
|
free_msghistory_snapshot(purged)
|
||||||
|
boolean purged; /* True: took history's pointers, False: just cloned them */
|
||||||
|
{
|
||||||
|
if (snapshot_mesgs) {
|
||||||
|
/* snapshot pointers are no longer in use */
|
||||||
|
if (purged) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; snapshot_mesgs[i]; ++i)
|
||||||
|
free((genericptr_t)snapshot_mesgs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
free((genericptr_t)snapshot_mesgs), snapshot_mesgs = (nhwchar **)0;
|
||||||
|
|
||||||
|
/* history can resume being updated at will now... */
|
||||||
|
if (!purged) wins[WIN_MESSAGE]->flags &= ~WIN_LOCKHISTORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called by the core save routines.
|
* This is called by the core save routines.
|
||||||
* Each time we are called, we return one string from the
|
* Each time we are called, we return one string from the
|
||||||
* message history starting with the oldest message first. each time
|
* message history starting with the oldest message first.
|
||||||
* we are called. Each time after that, we return a more recent message,
|
* When none are left, we return a final null string.
|
||||||
* until there are no more messages to return. Then we return a final
|
*
|
||||||
* null string.
|
* History is collected at the time of the first call.
|
||||||
|
* Any new messages issued after that point will not be
|
||||||
|
* included among the output of the subsequent calls.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
tty_getmsghistory(init)
|
tty_getmsghistory(init)
|
||||||
boolean init;
|
boolean init;
|
||||||
{
|
{
|
||||||
static int idx = 0, state = 0;
|
static int nxtidx;
|
||||||
static boolean doneinit = FALSE;
|
nhwchar *nextmesg;
|
||||||
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
char *result = 0;
|
||||||
char *retstr = (char *)0;
|
|
||||||
#ifdef UNICODE_WIDEWINPORT
|
|
||||||
static char buf[BUFSZ];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!cw) return (char *)0; /* bail */
|
if (init) {
|
||||||
/*
|
msghistory_snapshot(FALSE);
|
||||||
* state 0 = normal return with string from msg history.
|
nxtidx = 0;
|
||||||
* 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];
|
|
||||||
|
|
||||||
|
if (snapshot_mesgs) {
|
||||||
|
nextmesg = snapshot_mesgs[nxtidx++];
|
||||||
|
if (nextmesg) {
|
||||||
|
#ifdef UNICODE_WIDEWINPORT
|
||||||
|
static char histbuf[BUFSZ];
|
||||||
|
|
||||||
|
result = strnhwcpy(histbuf, nextmesg);
|
||||||
|
#else
|
||||||
|
result = (char *)nextmesg;
|
||||||
#endif
|
#endif
|
||||||
idx = (idx + 1) % cw->rows;
|
} else {
|
||||||
} while (idx != cw->maxrow && !retstr);
|
free_msghistory_snapshot(FALSE);
|
||||||
if (idx == cw->maxrow) ++state;
|
|
||||||
}
|
}
|
||||||
return retstr;
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -640,28 +696,54 @@ boolean init;
|
|||||||
* history recall buffer. The core will send the oldest message
|
* history recall buffer. The core will send the oldest message
|
||||||
* first (actually it sends them in the order they exist in the
|
* first (actually it sends them in the order they exist in the
|
||||||
* save file, but that is supposed to be the oldest first).
|
* save file, but that is supposed to be the oldest first).
|
||||||
|
* These messages get pushed behind any which have been issued
|
||||||
|
* since this session with the program has been started, since
|
||||||
|
* they come from a previous session and logically precede
|
||||||
|
* anything (like "Restoring save file...") that's happened now.
|
||||||
|
*
|
||||||
|
* Called with a null pointer to finish up.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
tty_putmsghistory(msg)
|
tty_putmsghistory(msg)
|
||||||
const char *msg;
|
const char *msg;
|
||||||
{
|
{
|
||||||
register struct WinDesc *cw = wins[WIN_MESSAGE];
|
static boolean initd = FALSE;
|
||||||
int idx = cw->maxrow;
|
int idx;
|
||||||
unsigned len = strlen(msg) + 1;
|
|
||||||
|
|
||||||
if (len > (unsigned)cw->datlen[idx]) {
|
if (!initd) {
|
||||||
if (cw->data[idx]) free(cw->data[idx]);
|
/* we're restoring history from the previous session, but new
|
||||||
len += (8 - (len & 7)); /* pad up to next multiple of 8 */
|
messages have already been issued this session ("Restoring...",
|
||||||
cw->data[idx] = (nhwchar *)alloc(sizeof(nhwchar) * len);
|
for instance); collect current history (ie, those new messages),
|
||||||
cw->datlen[idx] = (short)len;
|
and also clear it out so that nothing will be present when the
|
||||||
}
|
restored ones are being put into place */
|
||||||
|
msghistory_snapshot(TRUE);
|
||||||
|
initd = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg) {
|
||||||
|
/* move most recent message to history, make this become most recent */
|
||||||
|
remember_topl();
|
||||||
#ifdef UNICODE_WIDEWINPORT
|
#ifdef UNICODE_WIDEWINPORT
|
||||||
(void)nhwstrcpy(cw->data[idx], msg);
|
(void)nhwstrcpy(toplines, msg);
|
||||||
#else
|
#else
|
||||||
Strcpy(cw->data[idx], msg);
|
Strcpy(toplines, msg);
|
||||||
#endif
|
#endif
|
||||||
cw->maxcol = cw->maxrow = (idx + 1) % cw->rows;
|
} else if (snapshot_mesgs) {
|
||||||
|
/* done putting arbitrary messages in; put the snapshot ones back */
|
||||||
|
for (idx = 0; snapshot_mesgs[idx]; ++idx) {
|
||||||
|
remember_topl();
|
||||||
|
#ifdef UNICODE_WIDEWINPORT
|
||||||
|
(void)nhwcpy(toplines, snapshot_mesgs[idx]);
|
||||||
|
#else
|
||||||
|
Strcpy(toplines, snapshot_mesgs[idx]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* now release the snapshot */
|
||||||
|
free_msghistory_snapshot(TRUE);
|
||||||
|
initd = FALSE; /* reset */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* TTY_GRAPHICS */
|
#endif /* TTY_GRAPHICS */
|
||||||
|
|
||||||
/*topl.c*/
|
/*topl.c*/
|
||||||
|
|||||||
Reference in New Issue
Block a user