⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmh.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/* wmh.c - window front-end to mh */#ifndef	lintstatic char ident[] = "@(#)$Id: wmh.c,v 1.2 90/11/25 19:06:20 sharpe Exp $";#endif	lint/* TODO:	Pass signals to client during execution	Figure out a way for the user to say how big the Scan/Display	windows should be, and where all the windows should be. */#include <stdio.h>#include "../h/mh.h"#include "../h/vmhsbr.h"#include <ctype.h>#include <errno.h>#include <setjmp.h>#include <signal.h>#ifndef	sigmask#define	sigmask(s)	(1 << ((s) - 1))#endif	not sigmask#include <sys/types.h>#include <sys/uio.h>#include <vt.h>#include <bitmap.h>#include <tools.h>#define	ALARM	((unsigned int) 10)#define	PAUSE	((unsigned int) 2)#define	abs(a)	((a) > 0 ? (a) : -(a))#define	SZ(a)	(sizeof a / sizeof a[0])/*  */static struct swit switches[] = {#define	PRMPTSW	0    "prompt string", 6,#define	PROGSW	1    "vmhproc program", 7,#define	NPROGSW	2    "novmhproc", 9,#define	HELPSW	3    "help", 4,    NULL, NULL};/*  */					/* PEERS */static int  PEERpid = NOTOK;static  jmp_buf PEERctx;					/* WINDOWS */static int dfd = NOTOK;static int twd = NOTOK;static char *myprompt = "(%s) ";struct line {    int     l_no;    char   *l_buf;    struct line *l_prev;    struct line *l_next;};typedef struct {    int	    w_fd;    int	    w_flags;#define	W_NULL	0x00#define	W_CMND	0x01#define	W_FAKE	0x02#define	W_EBAR	0x04    int	    w_wd;    struct wstate w_ws;    char   *w_eb;    int	    w_ebloc;    int	    w_ebsize;    int	    w_cbase;    int	    w_height;    int	    w_cheight;    int	    w_width;    int	    w_cwidth;    struct line *w_head;    struct line *w_top;    struct line *w_bottom;    struct line *w_tail;    char   w_buffer[BUFSIZ];    int	   w_bufpos;}	WINDOW;static  WINDOW *Scan;static  WINDOW *Status;static  WINDOW *Display;static  WINDOW *Command;#define	NWIN	4static	int numwins;WINDOW *windows[NWIN + 1];WINDOW *WINnew ();					/* SIGNALS */#define	ERASE	sg.sg_erase#define	KILL	sg.sg_killstatic struct sgttyb    sg;#define	EOFC	tc.t_eofc#define	INTR	tc.t_intrcstatic struct tchars    tc;#define	WERASC	ltc.t_werascstatic struct ltchars ltc;int     ALRMser (), PIPEser (), SIGser ();int	ADJser (), REFser ();					/* MISCELLANY */extern int  errno;extern int  sys_nerr;extern char *sys_errlist[];void	adorn ();/*  *//* ARGSUSED */main (argc, argv)int     argc;char   *argv[];{    int     vecp = 1,	    nprog = 0;    char   *cp,            buffer[BUFSIZ],          **ap,          **argp,           *arguments[MAXARGS],           *vec[MAXARGS];    invo_name = r1bindex (argv[0], '/');    if ((cp = m_find (invo_name)) != NULL) {	ap = brkstring (cp = getcpy (cp), " ", "\n");	ap = copyip (ap, arguments);    }    else	ap = arguments;    (void) copyip (argv + 1, ap);    argp = arguments;/*  */    while (cp = *argp++)	if (*cp == '-')	    switch (smatch (++cp, switches)) {		case AMBIGSW: 		    ambigsw (cp, switches);		    done (1);		case UNKWNSW: 		    vec[vecp++] = --cp;		    continue;		case HELPSW: 		    (void) sprintf (buffer, "%s [switches for vmhproc]",			    invo_name);		    help (buffer, switches);		    done (1);		case PRMPTSW:		    if (!(myprompt = *argp++) || *myprompt == '-')			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case PROGSW: 		    if (!(vmhproc = *argp++) || *vmhproc == '-')			adios (NULLCP, "missing argument to %s", argp[-2]);		    continue;		case NPROGSW:		    nprog++;		    continue;	    }	else	    vec[vecp++] = cp;/*  */    (void) SIGinit ();    if (WINinit (nprog) == NOTOK) {	vec[vecp] = NULL;	vec[0] = r1bindex (vmhproc, '/');	execvp (vmhproc, vec);	adios (vmhproc, "unable to exec");    }    (void) PEERinit (vecp, vec);    vmh ();    done (0);}/*  */static  vmh () {    char    buffer[BUFSIZ],            prompt[BUFSIZ];    for (;;) {	(void) pLOOP (RC_QRY, NULLCP);	(void) sprintf (prompt, myprompt, invo_name);	switch (WINgetstr (Command, prompt, buffer)) {	    case NOTOK: 		break;	    case OK: 		done (0);	/* NOTREACHED */	    default: 		if (*buffer)		    (void) pLOOP (RC_CMD, buffer);		break;	}    }}/*    PEERS */static int  PEERinit (vecp, vec)int	vecp;char   *vec[];{    int	    pfd0[2],            pfd1[2];    char    buf1[BUFSIZ],            buf2[BUFSIZ];    register WINDOW **w;    (void) signal (SIGPIPE, PIPEser);    if (pipe (pfd0) == NOTOK || pipe (pfd1) == NOTOK)	adios ("pipe", "unable to");    switch (PEERpid = vfork ()) {	case NOTOK: 	    adios ("vfork", "unable to");/* NOTREACHED */	case OK: 	    for (w = windows; *w; w++)		if ((*w) -> w_fd != NOTOK)		    (void) close ((*w) -> w_fd);	    (void) close (pfd0[0]);	    (void) close (pfd1[1]);	    vec[vecp++] = "-vmhread";	    (void) sprintf (buf1, "%d", pfd1[0]);	    vec[vecp++] = buf1;	    vec[vecp++] = "-vmhwrite";	    (void) sprintf (buf2, "%d", pfd0[1]);	    vec[vecp++] = buf2;	    vec[vecp] = NULL;	    (void) signal (SIGINT, SIG_DFL);	    (void) signal (SIGQUIT, SIG_DFL);	    (void) signal (SIGTERM, SIG_DFL);	    vec[0] = r1bindex (vmhproc, '/');	    execvp (vmhproc, vec);	    perror (vmhproc);	    _exit (-1);		/* NOTREACHED */	default: 	    (void) close (pfd0[1]);	    (void) close (pfd1[0]);	    (void) rcinit (pfd0[0], pfd1[1]);	    return pINI ();    }}/*  */static int  pINI () {    register char  *bp;    char    buffer[BUFSIZ];    struct record   rcs;    register struct record *rc = &rcs;    register WINDOW **w;    initrc (rc);    bp = buffer;    (void) sprintf (bp, "%d %d", RC_VRSN, numwins);    bp += strlen (bp);    for (w = windows; *w; w++) {	(void) sprintf (bp, " %d", (*w) -> w_height);	bp += strlen (bp);    }    switch (str2rc (RC_INI, buffer, rc)) {	case RC_ACK: 	    return OK;	case RC_ERR: 	    if (rc -> rc_len)		adios (NULLCP, "%s", rc -> rc_data);	    else		adios (NULLCP, "pINI peer error");	case RC_XXX: 	    adios (NULLCP, "%s", rc -> rc_data);	default:	    adios (NULLCP, "pINI protocol screw-up");    }/* NOTREACHED */}/*  */static int  pLOOP (code, str)char	code,       *str;{    int	    i;    struct record   rcs;    register struct record *rc = &rcs;    WINDOW *w;    initrc (rc);    (void) str2peer (code, str);    for (;;)	switch (peer2rc (rc)) {	    case RC_TTY:		if (pTTY () == NOTOK)		    return NOTOK;		break;	    case RC_WIN:		if (sscanf (rc -> rc_data, "%d", &i) != 1			|| i <= 0			|| i > numwins) {		    (void) fmt2peer (RC_ERR, "no such window \"%s\"",				rc -> rc_data);		    return NOTOK;		}		if ((w = windows[i - 1]) -> w_flags & W_CMND) {		    (void) fmt2peer (RC_ERR, "not a display window \"%s\"",				rc -> rc_data);		    return NOTOK;		}		if (pWIN (w) == NOTOK)		    return NOTOK;		break;	    case RC_EOF:		return OK;	    case RC_ERR:		if (rc -> rc_len)		    adorn (NULLCP, "%s", rc -> rc_data);		else		    adorn (NULLCP, "pLOOP(%s) peer error",			    code == RC_QRY ? "QRY" : "CMD");		return NOTOK;	    case RC_FIN:		if (rc -> rc_len)		    adorn (NULLCP, "%s", rc -> rc_data);		(void) rcdone ();		i = pidwait (PEERpid, OK);		PEERpid = NOTOK;		done (i);	    case RC_XXX: 		adios (NULLCP, "%s", rc -> rc_data);	    default:		adios (NULLCP, "pLOOP(%s) protocol screw-up",			code == RC_QRY ? "QRY" : "CMD");	}}/*  */static int  pTTY () {    TYPESIG     (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();    struct record   rcs;    register struct record *rc = &rcs;    initrc (rc);    if (ChangeWindowDepth (dfd, twd, 0) == NOTOK)	adios ("failed", "ChangeWindowDepth");    hstat = signal (SIGHUP, SIG_IGN);    istat = signal (SIGINT, SIG_IGN);    qstat = signal (SIGQUIT, SIG_IGN);    tstat = signal (SIGTERM, SIG_IGN);    (void) rc2rc (RC_ACK, 0, NULLCP, rc);    (void) signal (SIGHUP, hstat);    (void) signal (SIGINT, istat);    (void) signal (SIGQUIT, qstat);    (void) signal (SIGTERM, tstat);    switch (rc -> rc_type) {	case RC_EOF: 	    (void) rc2peer (RC_ACK, 0, NULLCP);	    return OK;	case RC_ERR: 	    if (rc -> rc_len)		adorn (NULLCP, "%s", rc -> rc_data);	    else		adorn (NULLCP, "pTTY peer error");	    return NOTOK;	case RC_XXX: 	    adios (NULLCP, "%s", rc -> rc_data);	default:	    adios (NULLCP, "pTTY protocol screw-up");    }/* NOTREACHED */}/*  */static int  pWIN (w)register WINDOW *w;{    int     i;    if ((i = pWINaux (w)) == OK)	WINless (w);    return i;}/*  */static int  pWINaux (w)register WINDOW *w;{    register int    n;    register char  *bp;    register struct line   *lp,                           *mp;    struct record   rcs;    register struct record *rc = &rcs;    initrc (rc);    for (lp = w -> w_head; lp; lp = mp) {	mp = lp -> l_next;	free (lp -> l_buf);	free ((char *) lp);    }    w -> w_head = w -> w_top = w -> w_bottom = w -> w_tail = NULL;    w -> w_bufpos = 0;    for (;;)	switch (rc2rc (RC_ACK, 0, NULLCP, rc)) {	    case RC_DATA: 		for (bp = rc -> rc_data, n = rc -> rc_len; n-- > 0; )		    (void) WINputc (w, *bp++);		break;	    case RC_EOF: 		(void) rc2peer (RC_ACK, 0, NULLCP);		if (w -> w_bufpos)		    (void) WINputc (w, '\n');		return OK;	    case RC_ERR: 		if (rc -> rc_len)		    adorn (NULLCP, "%s", rc -> rc_data);		else		    adorn (NULLCP, "pWIN peer error");		return NOTOK;	    case RC_XXX: 		adios (NULLCP, "%s", rc -> rc_data);	    default:		adios (NULLCP, "pWIN protocol screw-up");	}/* NOTREACHED */}/*  */static int  pFIN () {    int     status;    if (PEERpid <= OK)	return OK;    (void) rc2peer (RC_FIN, 0, NULLCP);    (void) rcdone ();    switch (setjmp (PEERctx)) {	case OK: 	    (void) signal (SIGALRM, ALRMser);	    (void) alarm (ALARM);	    status = pidwait (PEERpid, OK);	    (void) alarm (0);	    break;	default: 	    (void) kill (PEERpid, SIGKILL);	    status = NOTOK;	    break;    }    PEERpid = NOTOK;    return status;}/*    WINDOWS *//* should dynamically determine all this stuff from gconfig... */#define	MyX	20		/* anchored hpos */#define	MyY	40		/*   .. vpos */#define	MyW	800		/*   .. width */#define	MyH	500		/*   .. height */#define	MyS	30		/*   .. height for Status, about one line */#define	MySlop	45		/* slop */#define	EWIDTH	25		/* Width of vertical EBAR */#define	ESLOP	5		/*   .. slop */static int  WINinit (nprog) {    short   wx,            wy,            wh,	    sy;    struct gconfig   gc;    if (GetGraphicsConfig (fileno (stderr), &gc) == NOTOK)	if (nprog)	    return NOTOK;	else	    adios (NULLCP, "not a window");    if ((dfd = open ("/dev/ttyw0", 2)) == NOTOK)	adios ("/dev/ttyw0", "unable to open");    if ((twd = GetTopWindow (dfd)) == NOTOK)	adios ("failed", "GetTopWindow");    (void) BlockRefreshAdjust (1);    numwins = 0;    wx = gc.w - (MyX + MyW + EWIDTH + ESLOP);    Scan = WINnew (wx, wy = MyY, MyW, wh = MyH * 2 / 3, "Scan", W_EBAR);    wy += wh + MySlop;    Status = WINnew (wx, sy = wy, MyW, wh = MyS, "Status", W_FAKE);    wy += wh + MySlop;    Display = WINnew (wx, wy, MyW, MyH, "Display", W_EBAR);    Command = WINnew (wx, sy, MyW, MyS, invo_name, W_CMND);    windows[numwins] = NULL;    return OK;}/*  */WINDOW *WINnew (wx, wy, ww, wh, name, flags)short	wx,	wy,	ww,	wh;char   *name;int	flags;{    register WINDOW *w;    if ((w = (WINDOW *) calloc (1, sizeof *w)) == NULL)	adios (NULLCP, "unable to allocate window");    if ((w -> w_flags = flags) & W_FAKE) {	w -> w_fd = NOTOK;	w -> w_height = 1;	goto out;    }    if (w -> w_flags & W_EBAR)	ww += EWIDTH + ESLOP;    else	wx += EWIDTH + ESLOP;    if ((w -> w_fd = OpenWindow (wx, wy, ww, wh, name)) == NOTOK)	adios ("failed", "OpenWindow");    if ((w -> w_wd = GetTopWindow (dfd)) == NOTOK)	adios ("failed", "GetTopWindow");    if (GetWindowState (w -> w_fd, &w -> w_ws) == NOTOK)	adios ("failed", "GetWindowState");    if (SetLineDisc (w -> w_fd, TWSDISC) == NOTOK)	adios ("failed", "SetLineDisc");    SetBuf (w -> w_fd, 1024);    (void) SetAdjust (w -> w_fd, numwins, ADJser);    (void) SetRefresh (w -> w_fd, numwins, REFser);    SetAddressing (w -> w_fd, VT_ABSOLUTE);    if (w -> w_flags & W_EBAR) {	w -> w_eb = CreateElevatorBar (w -> w_fd, 0, 0, EWIDTH,			w -> w_ws.height, VT_Gray50, 1, EB_VERTICAL,			EB_ARROWS, w -> w_ebloc = 0, w -> w_ebsize = EB_MAX,			VT_White);	if (w -> w_eb == NULL)	    adios (NULLCP, "CreateElevatorBar failed");	RefreshElevatorBar (w -> w_eb);    }    if ((w -> w_cbase = CharacterBaseline (w -> w_ws.font)) <= 0)	w -> w_cbase = 14;    if ((w -> w_cheight = CharacterHeight (w -> w_ws.font)) <= 0)	w -> w_cheight = 20;    w -> w_height = w -> w_ws.height / w -> w_cheight;    if (w -> w_height < 1)	w -> w_height = 1;						/* 1 em */    if ((w -> w_cwidth = CharacterWidth (w -> w_ws.font, 'm')) <= 0)	w -> w_cwidth = 10;    w -> w_width = (w -> w_ws.width - (w -> w_eb ? (EWIDTH + ESLOP) : 0))		    / w -> w_cwidth;    if (w -> w_width < 1)	w -> w_width = 1;out: ;    windows[numwins++] = w;    return w;}/*  */static int  WINgetstr (w, prompt, buffer)register WINDOW *w;char   *prompt,       *buffer;{    register int    c;    register char  *bp,                   *ip;    char    image[BUFSIZ];    struct vtseq    vts;    register struct vtseq  *vt = &vts;    if (w -> w_eb != NULL)	adios (NULLCP, "internal error--elevator bar found");    if (w -> w_head == NULL	    && (w -> w_head = (struct line *) calloc (1, sizeof *w -> w_head))		== NULL)	adios (NULLCP, "unable to allocate line storage");    w -> w_head -> l_buf = image;    w -> w_top = w -> w_bottom = w -> w_tail = w -> w_head;    if (ChangeWindowDepth (dfd, w -> w_wd, 0) == NOTOK)	adios ("failed", "ChangeWindowDepth");    (void) strcpy (image, prompt);    bp = ip = image + strlen (image);    Redisplay (w, 0);    for (;;)	switch (getvtseq (w -> w_fd, vt)) {	    case VT_HARDKEY: 		DisplayStatus (w -> w_fd, "no hardkeys, please");		break;	    case VT_ASCII: 		switch (c = toascii (vt -> u.ascii)) {		    case '\f': 	/* refresh? */			break;		    case '\r': 		    case '\n': 			(void) strcpy (buffer, ip);			return DONE;		    default: 			if (c == INTR) {			    adorn (NULLCP, "Interrupt");			    return NOTOK;			}			if (c == EOFC) {			    if (bp <= ip)				return OK;			    break;			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -