/*
 * A "dumb console" session manager.  This is intended for use when stdin/out
 * aren't ttys.  But stdin must still be usable for input.
 */

#include "global.h"
#ifdef SM_DUMB
#include <termios.h>
#include "hardware.h"
#include "proc.h"
#include "tty.h"
#include "sessmgr.h"

#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: dumbcons.c,v 1.20 1997/06/28 16:46:13 root Exp $";
#endif


extern int Keyboard;
extern int Numrows, Numcols;


static struct termios old_tty, new_tty;
static int Suspense = 0, ttyed;

static int
dumb_init(const struct sessmgr_sw *sm OPTIONAL)
{
    ttyed = (tcgetattr(0, &old_tty) != -1);
    if (ttyed)	{
	new_tty = old_tty;
	new_tty.c_lflag &= ~(ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHONL);
	new_tty.c_cc[VMIN] = 1;
	new_tty.c_cc[VTIME] = 0;
	(void) tcsetattr(0, TCSADRAIN, &new_tty);
    }
    /* suppress flow control */
    Numrows = 0;
    Numcols = 0;
    return 1;
}

static void
dumb_end(const struct sessmgr_sw *sm OPTIONAL)
{
    if (ttyed && !Suspense)
	(void) tcsetattr(0, TCSADRAIN, &old_tty);
}

static void
dumb_suspend(const struct sessmgr_sw *sm OPTIONAL)
{
    if (!Suspense++)
    {
	(void) fflush(stdout);
	if (ttyed)
	    (void) tcsetattr(0, TCSADRAIN, &old_tty);
    }
}

static void
dumb_resume(const struct sessmgr_sw *sm OPTIONAL)
{
    if (!--Suspense)
    {
	if (ttyed)
	    (void) tcsetattr(0, TCSADRAIN, &new_tty);
	Numrows = 0;
	Numcols = 0;
    }
}

static int
dumb_swap(const struct sessmgr_sw *sm OPTIONAL, void *old, void *new)
{
    int c;

    if (old && new)
    {
	c = (int) new - 1;
	printf("\n>>> switching to session %d", c);
	if (Sessions[c].name && *Sessions[c].name)
	    printf(": %s", Sessions[c].name);
	else if (Sessions[c].proc->name && *Sessions[c].proc->name)
	    printf(" [%s]", Sessions[c].proc->name);
	printf(" (%s)\n", Sestypes[Sessions[c].type]);
    }
    return 0;			/* only the current session can do output */
}

static void
dumb_putch(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c)
{
    putchar(c);		/*lint !e415 !e534 */
}

static void
dumb_clreol(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
}

static void
dumb_rflush(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
}

static void
dumb_flush(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
    if (!Suspense)
	(void) fflush(stdout);
}

static void *
dumb_create(const struct sessmgr_sw *sm OPTIONAL, struct session *sp)
{
    return (void *) (sp - Sessions + 1);
}

static void
dumb_destroy(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
}

static void
dumb_clrscr(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
}

static int
dumb_wherex(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
    return -1;
}

static int
dumb_wherey(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
    return -1;
}

static void
dumb_window(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL,
	int x1 OPTIONAL, int y1 OPTIONAL, int x2 OPTIONAL, int y2 OPTIONAL)
{
}

static void
dumb_gotoxy(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL,
	int x OPTIONAL, int y OPTIONAL)
{
}

static void
dumb_high(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
}

static void
dumb_norm(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
}

static void
dumb_bground(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c OPTIONAL)
{
}

static void
dumb_fground(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c OPTIONAL)
{
}

static void
dumb_txtattr(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c OPTIONAL)
{
}

static void
dumb_refresh (const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
}

static void
dumb_cursor(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL, int c OPTIONAL)
{
}

/*
 * We define two special characters:  ^C is F10, ^T is F9.  Everything else is
 * passed literally.
 */

static int
dumb_kbread(const struct sessmgr_sw *sm OPTIONAL, void *dp OPTIONAL)
{
    unsigned char ch;
    int i;

    do
    {
	kwait(&Keyboard);
    }
    while ((i = read(0, &ch, 1)) == 0 || (i == -1 && errno == EWOULDBLOCK));
    if (i < 0)
    {
	tputs("NOS PANIC: Lost keyboard\n");
	where_outta_here(1, "dumb_kbread");
    }
    if ((i = ch) == 3)
	i = -2;
    else if (i == 20)
	i = -11;
    else if (i == 127)		/* for when the backspace key sends DEL */
	i = 8;
    return i;
}

struct sessmgr_sw dumb_sessmgr =
{
    "dumb",
    SM_STDIO,
    dumb_init,
    (char *(*)(const struct sessmgr_sw *, char *)) 0,
    dumb_create,
    (char *(*)(const struct sessmgr_sw *, void *, const char *)) 0,
    dumb_swap,
    dumb_putch,
    dumb_clreol,
    dumb_clrscr,
    dumb_wherex,
    dumb_wherey,
    dumb_window,
    dumb_gotoxy,
    dumb_high,
    dumb_norm,
    dumb_bground,
    dumb_fground,
    dumb_txtattr,
    dumb_refresh,
    dumb_cursor,
    dumb_kbread,
    dumb_destroy,
    0,
    dumb_rflush,
    dumb_flush,
    dumb_suspend,
    dumb_resume,
    dumb_end,
    0
};

#endif
