[comp.sources.unix] v17i031: MGR, Bellcore window manager, Part30/61

rsalz@uunet.uu.net (Rich Salz) (01/26/89)

Submitted-by: Stephen A. Uhler <sau@bellcore.com>
Posting-number: Volume 17, Issue 31
Archive-name: mgr/part30




#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 30 (of 61)."
# Contents:  demo/icon/browse.c demo/icon/iconmail.c lib/window.h
#   src/do_button.c src/do_menu.c
# Wrapped by rsalz@papaya.bbn.com on Thu Nov 17 21:05:37 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'demo/icon/browse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'demo/icon/browse.c'\"
else
echo shar: Extracting \"'demo/icon/browse.c'\" \(9077 characters\)
sed "s/^X//" >'demo/icon/browse.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: browse.c,v 4.2 88/07/19 14:12:58 sau Exp $
X	$Source: /tmp/mgrsrc/demo/icon/RCS/browse.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/demo/icon/RCS/browse.c,v $$Revision: 4.2 $";
X
X/* display bitmap files on window */
X
X#include "term.h"
X#include <signal.h>
X
X#define GAP		3		/* space between icons */
X#define MAXICONS	500		/* max number of icons */
X#define SAVE		2		/* temp bitmap # */
X
X#define dprintf		if(debug)fprintf
X
Xstruct icon_pos {
X   int x,y;				/* position on window */
X   int w,h;				/* size of icon */
X   char *name;				/* name of icon */
X   };
X
Xstruct icon_pos icons[MAXICONS];
Xchar line[MAXLINE];		/* input buffer */
Xchar cwd[MAXLINE];
Xint win_x, win_y;		/* window position */
Xint win_high, win_wide;		/* window size */
Xint f_wide, f_high;		/* font size */
Xint debug;
Xchar **first;			/* pntr to first icon */
Xint invert = 0;
X
Xstruct menu_entry menu1[] = {
X   "reread","r\r","next","n\r", "prev","p\r", "quit","q\r",
X   };
X
Xstruct menu_entry menu2[] = {
X   "reread","r\r","next","n\r",    "quit","q\r"
X   };
X
Xstruct menu_entry menu3[] = {
X   "reread","r\r","prev","p\r",    "quit","q\r"
X   };
X
Xstruct menu_entry menu4[] = {
X   "reread","r\r","quit","q\r"
X   };
X
Xmain(argc,argv)
Xchar **argv;
X   {
X   int page = 1;			/* current page number */
X   int count;				/* number of icons on page */
X   int x,y;				/* mouse position */
X   int n = -1;				/* current icon */
X   int clean();
X   char *getenv();
X   FILE *popen(), *fd = popen("/bin/pwd","r");
X
X   ckmgrterm( *argv );
X
X   debug = (int) getenv("DEBUG");
X
X   if (fd) {
X      fgets(cwd,sizeof(cwd),fd);
X      *(cwd + strlen(cwd) - 1) = '\0';	/* blah */
X      dprintf(stderr,"Got cwd: [%s]\n",cwd);
X      pclose(fd);
X      }
X   else {
X      fprintf(stderr,"%s: can't get current directory\n",*argv);
X      exit(2);
X      }
X
X   if (argc <2 || argc > MAXICONS) {
X      fprintf(stderr,"usage: %s icons... (up to %d)\n",*argv,MAXICONS);
X      exit(1);
X      }
X
X   if (strcmp(argv[1],"-r")==0) {
X      invert++;
X      argv++;
X      argc--;
X      }
X
X   first = ++argv;
X   argc--;
X
X   m_setup(M_FLUSH);
X   m_push(P_BITMAP|P_MENU|P_EVENT|P_FLAGS);
X   m_ttyset();
X
X   menu_load(1,4,menu1);
X   menu_load(2,3,menu2);
X   menu_load(3,3,menu3);
X   menu_load(4,2,menu4);
X
X   signal(SIGINT,clean);
X   signal(SIGTERM,clean);
X
X   m_setmode(M_ABS);
X   m_setmode(M_NOWRAP);
X   get_size(&win_x,&win_y,&win_wide, &win_high);
X   get_font(&f_wide, &f_high);
X
X   m_setevent(BUTTON_1,"^%p\r");
X   m_setevent(BUTTON_1U,"$\r");
X   m_setevent(MOVE,"M\r");
X   m_setevent(RESHAPED,"R\r");
X   m_setevent(REDRAW,"r\r");
X
X   count = fill_page(first,icons);
X
X   if (count == 0) {
X      fprintf(stderr,"%s: no files in icon format\n",*--argv);
X      clean(3);
X      }
X
X   set_menu(first-argv,argc-count-(first-argv)-1);
X
X   dprintf(stderr,"Got %d,%d %dx%d [%dx%d]\n",
X           win_x, win_y, win_wide, win_high, f_wide, f_high);
X
X   while(m_gets(line) != NULL) {
X      dprintf(stderr,"Got [%s]\n",line);
X      switch(*line) {
X	 case 'q':
X	    clean(0);
X	    break;
X         case ':':		/* got a message - send current icon back */
X            sscanf(line+1,"%d",&x);
X            if (n >= 0) {
X               m_sendto(x,icons[n].name);
X               dprintf(stderr,"sent [%s] to %d\n",
X                       icons[n].name,x);
X               }
X            break;
X         case '^':		/* button down */
X            sscanf(line+1,"%d %d",&x,&y);
X            n = find_icon(icons,x,y);
X            if (n >= 0) {
X               border(icons[n],B_SET);
X               sprintf(line,"%s/%s",cwd,icons[n].name);
X               m_setevent(NOTIFY,line);
X               sprintf(line,"%s (%d x %d)", icons[n].name,
X			icons[n].w, icons[n].h);
X               pop_text(line, icons[n].x+icons[n].w/2,
X                                      icons[n].y+icons[n].h + GAP);
X               border(icons[n],B_CLEAR);
X               }
X            break;
X         case 'n':		/* next icons */
X               if ((first-argv) + count >= argc)
X                  break;
X               first += 2*count/3 + 1;
X               count = fill_page(first,icons);
X               set_menu(first-argv,argc-count-(first-argv)-1);
X               break;
X         case 'p':		/* previous icons */
X               if (first == argv)
X                   break;
X               first -= 2*count/3 + 1 ;
X               if (first < argv)
X                  first = argv;
X               count = fill_page(first,icons);
X               set_menu(first-argv,argc-count-(first-argv)-1);
X               break;
X         case 'M':		/* window moved */
X               get_size(&win_x,&win_y,&win_wide, &win_high);
X               break;
X         case 'r':		/* window  redrawn  */
X               count = fill_page(first,icons);
X               set_menu(first-argv,argc-count-(first-argv)-1);
X            break;
X         case 'R':		/* window shaped*/
X               dprintf(stderr,"Got %d,%d %dx%d [%dx%d]\n",
X                       win_x, win_y, win_wide, win_high, f_wide, f_high);
X               x = win_wide;
X               y = win_high;
X               get_size(&win_x,&win_y,&win_wide, &win_high);
X               if (y != win_high || x>win_wide) {
X                  count = fill_page(first,icons);
X                  set_menu(first-argv,argc-count-(first-argv)-1);
X                  }
X            break;
X         default:		/* button up (let go of button too fast) */
X            break;
X         }
X      }
X   clean(0);
X   }
X
Xint
Xfill_page(names,icon)
Xchar **names;
Xstruct icon_pos *icon;
X   {
X   register int count = 0;
X   int x=GAP, y=GAP;			/* current icon position */
X   int w,h;				/* current icon size */
X   int maxh = 0;			/* max y extent of icons */
X
X   if (invert)
X      m_func(B_COPYINVERTED);
X   else
X      m_func(B_COPY);
X   m_clear();
X   for(;*names;names++) {
X      if (**names == '/')
X         m_bitfile(1,*names, &w, &h);
X      else {
X         m_bitfile(1,sprintf(line,"%s/%s",cwd,*names), &w, &h);
X         }
X      dprintf(stderr,"getting %s -> %s",*names,line);
X      if (w==0 || h == 0)
X         continue;
X
X      if (w + x + 2*GAP > win_wide) {
X         x = GAP;
X         y += maxh + GAP;
X         maxh = 0;
X         }
X
X      if (y + h + GAP > win_high) {
X         dprintf(stderr,"%s won't fit\n",*names);
X         break;
X         }
X
X      m_movecursor(x,y);
X      m_bitcopyto(x,y,w,h,0,0,0,1);
X      count++;
X      icon->x = x;
X      icon->y = y;
X      icon->w = w;
X      icon->h = h;
X      icon->name = *names;
X
X      icon++;
X      x += w + GAP;
X      maxh = h>maxh ? h : maxh;
X      }
X   icon->x = -1;
X   m_movecursor(0,win_high-f_high-GAP);
X   return(count);
X   }
X
Xclean(code)
Xint code;
X   {
X	m_bitdestroy(1);
X   m_pop();
X   m_ttyreset();
X   exit(code);
X   }
X
X/* border an icon */
X
Xborder(icon,how)
Xstruct icon_pos icon;
Xint how;
X   {
X   int x=icon.x, y=icon.y, w=icon.w, h=icon.h;
X   dprintf(stderr,"border: %d,%d %dx%d\n",x,y,w,h);
X
X   m_func(how);
X   m_bitwrite(x-GAP,y-GAP,w+2*GAP,GAP);
X   m_bitwrite(x-GAP,y+h,w+2*GAP,GAP);
X   m_bitwrite(x-GAP,y,GAP,h);
X   m_bitwrite(x+w,y,GAP,h);
X   }
X   
X/* find an icon */
X
Xint
Xfind_icon(icon,x,y)
Xregister struct icon_pos *icon;
Xregister int x,y;
X   {
X   register int i = 0;
X
X   dprintf(stderr,"Looking for: %d %d [%d]\n",x,y);
X
X   for(;icon->x != -1;i++,icon++)  {
X      if (y>icon->y && x>icon->x &&
X                       y < icon->y + icon->h &&
X                       x < icon->x + icon->w) {
X         dprintf(stderr,"found %d\n",i);
X         return(i);
X         }
X      }
X   return(-1);
X   }
X   
Xpop_text(s,x,y)
Xchar *s;		/* text to display */
Xint x,y;		/* center of window */
X   {
X   int wide = (strlen(s)<5?5:strlen(s)) * f_wide + 10;
X   int high = f_high + 4*GAP;
X   int x0 = x - wide/2;
X   int y0 = y + f_high;
X
X   if (x0<0)
X      x0 = GAP;
X   if (x0+wide > win_wide)
X      x0 = win_wide-wide-GAP;
X   if (y0+high > win_high - f_wide)
X      y0 = GAP;
X
X   if (x0 < 0 || y0 + high > win_high - f_wide-GAP < 0) {
X      m_gets(line);
X      return(1);
X      }
X
X   /* save current window text */
X
X   m_func(B_SRC);
X   m_bitcopyto(0,0,wide,high,x0,y0,SAVE,0);
X
X   /* draw border */
X
X   m_func(B_SET);
X   m_bitwrite(x0,y0,wide,high);
X   m_func(B_CLEAR);
X   m_bitwrite(x0+GAP,y0+GAP,wide-2*GAP,high-2*GAP);
X   m_moveprint(x0+2*GAP,y0+(high-f_high)/2+GAP+f_high,s);
X   m_movecursor(win_wide,y);
X
X   m_gets(line);
X
X   /* restore data */
X
X   m_func(B_SRC);
X   m_bitcopyto(x0,y0,wide,high,0,0,0,SAVE);
X   m_bitdestroy(SAVE);
X   }
X
Xint
Xset_menu(front,back)
Xint front;
Xint back;
X   {
X   register int i;
X   if (front>0 && back>0)
X      i = 1;
X   else if (front > 0)
X      i = 3;
X   else if (back > 0)
X      i = 2;
X   else
X      i = 4;
X
X   m_selectmenu(i);
X   dprintf(stderr,"set menu %d (%d,%d)\n",i,front,back);
X   return(i);
X   }
END_OF_FILE
# end of 'demo/icon/browse.c'
fi
if test -f 'demo/icon/iconmail.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'demo/icon/iconmail.c'\"
else
echo shar: Extracting \"'demo/icon/iconmail.c'\" \(8565 characters\)
sed "s/^X//" >'demo/icon/iconmail.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: iconmail.c,v 4.2 88/06/30 16:21:42 bianchi Exp $
X	$Source: /tmp/mgrsrc/demo/icon/RCS/iconmail.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/demo/icon/RCS/iconmail.c,v $$Revision: 4.2 $";
X
X/* check for new mail  (icon version) */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/time.h>		/* for fsleep */
X#include <signal.h>
X#include <sgtty.h>
X#include <stdio.h>
X
X#include <term.h>
X#include "mail_icons.h"
X
X#define MSG_READING	"\freading mail ...\r"
X#define MSG_CHECKING	"\rChecking for new mail..."
X
X#define MAILF		"/usr/spool/mail"	/* spool file */
X#define MAIL		"mail"			/* name of mail command */
X#define POLL		60			/* polling interval */
X#define XPOS		240			/* x start of mail window */
X#define YPOS		190			/* y start of mail window */
X#define W_WIDE		80			/* width of mail window */
X#define W_HIGH		24			/* height of mail window */
X#define MAX_ICON	64			/* max icon size */
X
X#define PROCESSED	2			/* new mail already processed */
X
X#define S(x)			statb.x
X#define Isflag(arg,flag)	(!strncmp(arg,flag,strlen(flag)))
X#define Max(x,y)		((x)>(y)?(x):(y))
X#define dprintf			if(debug) fprintf
X
X#define fsleep() \
X   { \
X   struct timeval time; \
X   time.tv_sec = 0; \
X   time.tv_usec = 330000; \
X   select(0,0,0,0,&time); \
X   }
X
X#define MENU_COUNT		(sizeof(menu)/sizeof(struct menu_entry))
X
Xstruct menu_entry menu[] = {
X	"print","t\r",
X	"delete","dt\r",
X	"next","n\r",
X	"quit","q\r",
X	"help","?\r",
X	"headers","h *\r",
X	"abort","x\r",
X};
X
Xstatic struct	stat statb;	/* spool file status */
Xstatic char	mail[255];	/* spool file path name */
Xstatic long	omtime=0l;	/* previous file mod. time */
Xstatic int	state = 0;	/* mail & window state */
Xstatic int	poll = POLL;	/* poll interval */
Xstatic int	debug=0;	/* for mgrmail -d >& /dev/tty?? */
Xstatic int	x,y;		/* window position */
Xstatic int	w,h;		/* window size */
Xstatic int	border;		/* size of mgr border */
Xstatic int	local=0;	/* use local icon only */
Xstatic int	local_mode = -1;/* local mode bits for tty */
Xstatic int	cwide, chigh;	/* width and height of font characters */
Xstatic char	*termcap;
X
Xmain(argc,argv)
X	char **argv;
X{
X	register int i;
X	int xpos = XPOS;		/* screen position of mail subwindow */
X	int ypos = YPOS;
X	int font = -1;			/* font to use for mail subwindow */
X	int shape = 1;			/* initially reshape window */
X	char *command = MAIL;		/* name of readmail command */
X
X	char *getenv();
X	char *user = getenv("USER");
X	char line[MAXLINE];		/* event input buffer */
X
X	int clean(), update();
X
X	/* make sure environment is ok */
X
X	ckmgrterm( *argv );
X
X	if (user==NULL || *user=='\0') {
X		fprintf(stderr, "%s: No USER environment variable value.\n",
X			argv[0]);
X		exit(2);
X	}
X
X	/* process arguments */
X
X	for(i=1;i<argc;i++) {
X		if (Isflag(argv[i],"-s"))
X			shape = 0;
X		else if (Isflag(argv[i],"-d"))
X			debug = 1;
X		else if (Isflag(argv[i],"-l"))
X			local = 1;
X		else if (Isflag(argv[i],"-x"))
X			xpos = atoi(argv[i]+2);
X		else if (Isflag(argv[i],"-y"))
X			ypos = atoi(argv[i]+2);
X		else if (Isflag(argv[i],"-f"))
X			font = atoi(argv[i]+2);
X		else if (Isflag(argv[i],"-p"))
X			poll  = Max(atoi(argv[i]+2),10);
X		else if (Isflag(argv[i],"-M"))
X			command  = argv[i]+2;
X		else
X			usage(argv[0],argv[i]);
X	}
X	sprintf(mail,"%s/%s",MAILF,user);
X
X	/* set up window environment */
X
X	m_setup(M_FLUSH);
X	m_push(P_MENU|P_BITMAP|P_FONT|P_EVENT|P_FLAGS|P_POSITION);
X	if (font < 0)
X		font = 0;
X	m_font(font);
X	get_font( &cwide, &chigh );
X
X	signal(SIGHUP,clean);
X	signal(SIGTERM,clean);
X	signal(SIGINT,clean);
X	signal(SIGALRM,update);
X
X	dprintf(stderr,"pushing environment\n"); fflush(stderr);
X	m_ttyset();
X	m_setmode(M_NOWRAP);
X	m_setmode(M_ABS);
X	m_func(B_COPY);
X
X	download_icon(&mbox_closed,1);
X	download_icon(&mbox_full,2);
X	download_icon(&mbox_zip,5);
X	download_icon(&mbox_open,6);
X
X	get_size(&x,&y,&w,&h);
X        get_param(0,0,0,&border);
X	m_movecursor(x+30,0);
X
X	m_setmode(M_ACTIVATE);
X	if (shape) {
X		m_shapewindow(x,y,2*border+MAX_ICON, 2*border+MAX_ICON);
X                get_size(&x,&y,&w,&h);
X        }
X
X	m_setevent(ACTIVATE,"A\r");
X	m_setevent(REDRAW,"R\r");
X
X	m_clearmode(M_ACTIVATE);
X        set_icon(mbox_closed);
X
X	dprintf(stderr,"Starting state 0x%x\n",state); fflush(stderr);
X
X	update();
X
X	termcap = getenv("TERMCAP");
X	if( termcap )
X		*termcap = '\0';
X
X	/* wait for an event */
X
X	while(1) {
X		if( m_gets(line) == NULL ) {
X			clearerr( m_termin );
X			continue;
X		}
X		dprintf(stderr,"state 0x%x line : %c\n",state,*line);
X		fflush(stderr);
X		switch(*line) {
X		case 'A':	/* window is activated */
X			if (!stat(mail,&statb) && S(st_size))
X				do_mail(command,font,xpos,ypos);
X			else {
X				set_icon(mbox_open);
X				sleep(2);
X				m_clearmode(M_ACTIVATE);
X			}
X			state &= ~PROCESSED;
X			update();
X			break;
X		case 'R':	/* screen is redrawn */
X			state &= ~PROCESSED;
X			get_size(&x,&y,&w,&h);
X			m_movecursor(x+30,0);
X			update();
X			break;
X		}
X	}
X}
X
X/* run readmail in a subwindow */
X
Xdo_mail(command,font,xpos,ypos)
Xchar *command;
Xint font,xpos,ypos;
X	{
X	int code;
X	int n;
X
X	alarm(0);
X	m_push(P_EVENT | P_FONT);
X	dprintf(stderr,"doing mail\n"); fflush(stderr);
X	n = m_makewindow(xpos, ypos, W_WIDE*cwide + 2*border,
X		W_HIGH*chigh + 2*border);
X	if (n==0) {	/* can't make window */
X		m_printstr("\007\fCan't open mail window, sorry");
X		m_pop();
X		return(0);
X		}
X	/*
X	if( *termcap  &&  newtermcap[0] == '\0' ) {
X		strcpy( newtermcap, get_termcap() );
X		termcap = newtermcap;
X	}
X	*/
X  	set_icon(mbox_zip);
X	m_selectwin(n);
X	m_font(font);
X	menu_load(1,MENU_COUNT,menu);
X	m_selectmenu(1);
X	m_printstr(MSG_READING);
X	m_ttyreset();
X	code = system(command);
X	m_printstr(MSG_CHECKING);
X	sleep(1);	/* for "New mail arrived" message */
X	dprintf(stderr,"Readmail completed code %d\n",code); fflush(stderr);
X	m_ttyset();
X	m_selectwin(0);
X	m_destroywin(n);
X	m_pop();
X	m_clearmode(M_ACTIVATE);
X	dprintf(stderr,"window deactivated\n"); fflush(stderr);
X	}
X
X/* check the spool file for new mail and update message */
X
Xint
Xupdate()
X{
X	alarm(0);
X	dprintf(stderr,"checking mail state 0x%x\n",state); fflush(stderr);
X	if (!stat(mail,&statb) && S(st_mtime)>S(st_atime) && S(st_size)) {
X		state &= ~PROCESSED;
X		if (S(st_mtime) != omtime) {
X		dprintf(stderr,"	First time New mail\n"); fflush(stderr);
X                        m_printstr("\007");
X  			set_icon(mbox_full);
X			omtime = S(st_mtime);
X		}
X	}
X	else if (!(state&PROCESSED)) {
X		dprintf(stderr,"	Clearing new mail\n"); fflush(stderr);
X  		set_icon(mbox_closed);
X		state |= PROCESSED;
X	}
X	alarm(poll);
X}
X
X/*	Clean up and exit */
X
Xclean(n)
Xint	n;
X{
X	m_ttyreset();
X	m_selectwin(0);
X	m_popall();
X	exit(n);
X}
X
Xusage(name,error)
Xchar *name, *error;
X{
X	fprintf(stderr,"Invalid flag: %s\n",error);
X	fprintf(stderr,
X		"usage: %s -[s|x<pos>|y<pos>|f<font>|p<poll>|M<mail_program>]\n"
X		,name);
X	exit(1);
X}
X
X/* down load an icon */
X
Xdownload_icon(icon,where)
Xregister struct icon *icon;	/* name of icon to download */
Xint where;			/* bitmap to download icon to */
X   {
X
X   int size;
X   int w_in=0, h_in=0;
X
X   if (!local) {
X	   /* first try the local machine */
X      dprintf(stderr,"looking for %s\n",icon->name);
X      m_bitfile(where, icon->name, &w_in, &h_in );
X      }
X
X   if (h_in==0 || w_in==0) {	/* can't find icon */
X      dprintf(stderr,"Couldn't find %s, downloading\n",icon->name);
X      if (local_mode == -1)
X         ioctl(fileno(m_termout),TIOCLGET,&local_mode);
X      local_mode |= LLITOUT;
X      ioctl(fileno(m_termout),TIOCLSET,&local_mode);
X
X      size = icon->h * (((icon->w+15)&~15)>>3);
X      m_bitldto(icon->w,icon->h,0,0,where,size);
X      m_flush();
X      write(fileno(m_termout),icon->data,size);
X      local_mode &= ~LLITOUT;
X      ioctl(fileno(m_termout),TIOCLSET,&local_mode);
X      }
X   else {
X      dprintf(stderr,"Found %s (%d x %d) expected %d x %d\n",
X               icon->name,w_in,h_in,icon->w,icon->h);
X      icon->w = w_in;
X      icon->h = h_in;
X      }
X   icon->type = where;
X   } 
X
Xset_icon(name)
Xstruct icon name;		/* name of icon */
X   {
X   int x0 = (w-name.w)/2;
X   int y0 = (h-name.h)/2;
X
X   m_clear();
X   m_bitcopyto(x0,y0,name.w,name.h,0,0,0,name.type);
X   dprintf(stderr,"copy %s to %d,%d (%d x %d)from %d\n",
X           name.name,x0,y0,name.w,name.h,name.type);
X   m_flush();
X   }
END_OF_FILE
# end of 'demo/icon/iconmail.c'
fi
if test -f 'lib/window.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/window.h'\"
else
echo shar: Extracting \"'lib/window.h'\" \(8727 characters\)
sed "s/^X//" >'lib/window.h' <<'END_OF_FILE'
X/*                        Copyright (c) 1988 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: window.h,v 4.2 88/08/12 07:41:26 sau Exp $
X	$Source: /tmp/mgrsrc/lib/RCS/window.h,v $
X*/
Xstatic char	h_window_[] = "$Source: /tmp/mgrsrc/lib/RCS/window.h,v $$Revision: 4.2 $";
X
X/* defines for terminal emulator */
X
X/* text flags - for commands with text string arguments */
X
X#define T_INVALID	0	/* invalid command */
X#define T_FONT		1	/* down load a new font */
X#define T_MENU		2	/* down load a menu */
X#define T_EVENT		3	/* down load an event string */
X#define T_YANK		4	/* fill the yank bufffer */
X#define T_BITMAP	5	/* down load a bit map */
X#define T_COMMAND	6	/* start a new window & command in it */
X#define T_GIMME		7	/* send me stuff */
X#define T_SMAP		8	/* save a bitmap on a file */
X#define T_GMAP		9	/* read a bitmap from a file */
X#define T_SEND		10	/* send a message to another application */
X#define T_GRUNCH	11	/* fast-draw, short vector mode */
X#define T_STRING	12	/* write a text sting into an offscreen bitmap */
X
X/* option codes for GETMODE / SETMODE  */
X
X#define M_STANDOUT	0	/* window is in standout mode  */
X#define M_WOB		1	/* window is white on black  */
X#define M_AUTOEXPOSE	2	/* expose window upon shell output  */
X#define M_BACKGROUND	3	/* permit obscured window to update  */
X#define M_NOINPUT	4	/* don't accept keyboard input  */
X#define M_NOWRAP	5	/* don't auto wrap  */
X#define M_OVERSTRIKE	6	/* overstrike mode  */
X#define M_ABS		7	/* use absolute coordinates  */
X#define M_ACTIVATE	8	/* activate / hide window; not a mode */
X#define M_STACK		12	/* permit event stacking */
X#define M_DUPKEY	13	/* set keyboard escape key */
X#define M_NOBUCKEY	14	/* prevent mgr processing buckey keys,
X				   pass them through to the application */
X
X/* cut/paste options */
X
X#define M_SNARFLINES	9	/* only snarf entire lines */
X#define M_SNARFTABS	10	/* change spaces to tabs in snarf */
X#define M_SNARFHARD	11	/* snarf even if errors */
X
X/* option codes for GETINFO */
X
X#define G_MOUSE	 	0	/* mouse coordinates  */
X#define G_TERMCAP 	1	/* send back termcap entry  */
X#define G_WINSIZE 	2	/* cols, lines  */
X#define G_FONT	 	3	/* font wide, high, #  */
X#define G_COORDS 	4	/* window coords  */
X#define G_STATUS 	5	/* window status  */
X#define G_ALL	 	6	/* complete window status  */
X#define G_SYSTEM 	7	/* system status  */
X#define G_ALLFONT 	8	/* font information  */
X#define G_TEXT		9	/* text region size */
X#define G_ALLMINE  	10	/* window status for client windows */
X#define G_CURSOR	11	/* character/ graphics cursor position */
X#define G_MOUSE2	12	/* cooked mouse coordinates  */
X#define G_NOTIFY	13	/* gimme info re notify windows */
X#define G_ID		14	/* my client window number */
X#define G_FLAGS		15	/* current window flags */
X#define G_MAX		15	/* maximum GETINFO value */
X
X/* option codes for stacking window environment */
X
X#define P_MENU		0x001	/* push menus */
X#define P_EVENT		0x002	/* push events */
X#define P_FONT		0x004	/* push current font */
X#define P_CURSOR	0x008	/* push current cursor position  */
X#define P_BITMAP	0x010	/* push saved bitmaps */
X#define P_POSITION	0x020	/* push window location */
X#define P_WINDOW	0x040	/* push window contents */
X#define P_FLAGS		0x080	/* push window flags */
X#define P_MOUSE		0x100	/* push mouse position */
X#define P_TEXT		0x200	/* push text region */
X
X
X#define P_ALL		0x3ff	/* push everything */
X#define P_MAX		0x400	/* end of codes marker */
X#define P_DEFAULT	(P_MENU | P_EVENT | P_FONT | P_FLAGS | P_TEXT)
X#define P_CLEAR		0x400	/* clear new environment */
X
X/* menu_flags */
X
X#define MF_SNIP		8	/* don't send action for parent of s/o menu */
X#define MF_PAGE		4	/* auto-page for menus */
X#define MF_AUTO		2	/* auto-right exit for menus */
X#define MF_CLEAR	1	/* clear menu flags */
X
X/* Escape codes */
X
X#define ESC		'\033'	/* escape character */
X
X#define E_MINUS		'-'	/* set the munus flag */
X#define E_SEP1		','	/* primary field seperator */
X#define E_SEP2		';'	/* secondary field seperator */
X#define E_MOUSE		'?'	/* testing  -- move the mouse  */
X#define E_ADDLINE	'a'	/* add a new line  */
X#define E_ADDCHAR	'A'	/* add a character  */
X#define E_BITBLT	'b'	/* do a bit blit  */
X#define E_BITCRT	'B'	/* create a bit blit  */
X#define E_CLEAREOL	'c'	/* clear  */
X#define E_CLEAREOS	'C'	/* clear  */
X#define E_DELETELINE	'd'	/* delete a line */
X#define E_BITLOAD	'D'	/* download a bitmap  */
X#define E_EVENT		'e'	/* download events  */
X#define E_DELETECHAR	'E'	/* delete a char */
X#define E_DOWN		'f'	/* down 1 line */
X#define E_FONT		'F'	/* pick a new font  */
X#define E_GO		'g'	/* Go; move graphics pointer  */
X#define E_MOVE		'G'	/* move to x,y pixels  */
X#define E_SETCURSOR	'h'	/* select cursor style */
X#define E_BLEEP		'H'	/* blink a section of the screen */
X#define E_GETINFO	'I'	/* get info from mgr */
X#define E_STANDOUT	'i'	/* start standout mode */
X#define E_FCOLOR	'j'	/* set forground color */
X#define E_BCOLOR	'J'	/* set background color */
X#define E_LINE		'l'	/* Plot a line  */
X#define E_LINK		'L'	/* menu links */
X#define E_MENU		'm'	/* download menus */
X#define E_CUP		'M'	/* move to col, row (zero origin)  */
X#define E_STANDEND	'n'	/* end standout mode */
X#define E_CIRCLE	'o'	/* Plot a circle or an ellipse or an arc */
X#define E_PUSH		'P'	/* push window environment */
X#define E_POP		'p'	/* pop window environment */
X#define E_RUBBER	'R'	/* rubber band a line/rect (obsolete) */
X#define E_RIGHT		'r'	/* right 1 column  */
X#define E_CLEARMODE	's'	/* clear window mode */
X#define E_SETMODE	'S'	/* set a window mode */
X#define E_TEXTREGION	't'	/* set the text region */
X#define E_UPLINE	'u'	/* up 1 line  */
X#define E_BITGET	'U'	/* upload a bitmap  */
X#define E_SHAPE		'W'	/* reshape window, make it active  */
X#define E_SIZE		'w'	/* reshape window: cols,rows  */
X#define E_GIMME		'x'	/* send me data */
X#define E_PUTSNARF	'y'	/* put the snarf buffer  */
X#define E_SNARF		'Y'	/* snarf text into the snarf buffer  */
X#define E_VI		'V'	/* set vi mode */
X#define E_NOVI		'v'	/* turn off vi mode */
X#define E_HALFWIN	'z'	/* make a 1/2 window */
X#define E_MAKEWIN	'Z'	/* make/goto a new window */
X#define E_NULL		'$'	/* do nothing, force exit */
X#define E_SMAP		'>'	/* save a bitmap */
X#define E_GMAP		'<'	/* get a bitmap */
X#define E_SEND		'|'	/* send a message to another application */
X#define E_CURSOR	'%'	/* set mouse cursor */
X#define E_GRUNCH	':'	/* graphics crunch mode (experimental) */
X#define E_STRING	'.'	/* write characters in offscreen bitmap */
X#ifdef XMENU
X#define E_XMENU		'X'	/* extended menu operations */
X#endif
X
X
X/* misc */
X
X#define C_NOCHAR	'?'	/* for character not in font */
X#define C_EXPOSED	'e'	/* window is not obscured */
X#define C_ACTIVE	'a'	/* window has input focus */
X#define C_NOTACTIVE	'n'	/* window is obscured */
X#define C_OBSCURED	'o'	/* window is obscured */
X#define C_NAME		"px|mgr|mgr teminal emulator"
X
X#define C_NULL		'\000'	/* null */
X#define C_BS		'\b'	/* back space */
X#define C_FF		'\f'	/* form feed */
X#define C_BELL		'\007'	/* bell */
X#define C_TAB		'\t'	/* tab */
X#define C_RETURN	'\r'	/* return */
X#define C_NL		'\n'	/* line feed */
X
X/* cursor styles */
X#define CS_BLOCK		0		/* standard block cursor */
X#define CS_LEFT		1		/* left vertical bar */
X#define CS_RIGHT		2		/* right vertical bar */
X#define CS_BOX			3		/* outline */
X#define CS_UNDER		4		/* underline */
X
X/* some raster op functions  (for bit_copy) */
X
X#ifndef BIT_NOT
X#define BIT_NOT(x)	(~(x))		/* from bitmap.h */
X#endif
X#define B_SRC		(0xc)
X#define B_DST		(0xa)
X#define B_OR		(B_SRC|B_DST)
X#define B_COPY		(B_SRC)
X#define B_COPYINVERTED	((BIT_NOT(B_SRC))&0xf)
X#define B_XOR		(B_SRC^B_DST)
X#define B_AND		(B_SRC&B_DST)
X
X/* raster op functions  (for bit_write and bit_line) */
X
X#define B_SET		(0xf)
X#define B_CLEAR		(0x0)
X#define B_INVERT	((BIT_NOT(B_DST))&0xf)
X
X/* where to find icon directory */
X
X#ifndef ICONDIR
X#  define ICONDIR		"/usr/mgr/icon"	/* readable by all icons */
X#endif
X
X/* other macros */
X
X#define Scalex(x) \
X	(W(flags)&W_ABSCOORDS ?  (x) :  (x) * (int)BIT_WIDE(W(window))/GMAX)
X#define Scaley(y) \
X	(W(flags)&W_ABSCOORDS ?  (y) :  (y) * (int)BIT_HIGH(W(window))/GMAX)
X#define Scalexy(y) \
X	(W(flags)&W_ABSCOORDS ?  (y) : \
X	 (y) * (int)(BIT_HIGH(W(window))+BIT_WIDE(W(window)))/(2*GMAX))
X
X#define FSIZE(c)	((int) (W(font)->head.c))
X#define WIDE	        BIT_WIDE(window)
X#define HIGH	        BIT_HIGH(window)
X#define T_WIDE	        BIT_WIDE(text)
X#define T_HIGH	        BIT_HIGH(text)
END_OF_FILE
# end of 'lib/window.h'
fi
if test -f 'src/do_button.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/do_button.c'\"
else
echo shar: Extracting \"'src/do_button.c'\" \(8518 characters\)
sed "s/^X//" >'src/do_button.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: do_button.c,v 4.2 88/06/28 15:25:58 bianchi Exp $
X	$Source: /tmp/mgrsrc/src/RCS/do_button.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/src/RCS/do_button.c,v $$Revision: 4.2 $";
X
X/* Figure out what to do with a button push */
X
X#include "bitmap.h"
X#include <stdio.h> 	/* temporary */
X#include <sys/signal.h>
X#include "menu.h"
X#include "defs.h"
X#include "font.h"
X#include "event.h"
X
Xdo_button(button)
Xint button;
X   {
X   register WINDOW *win;		/* window of interest */
X   int choice;				/* current menu choice */
X   int choice_ok;			/* valid choice flag */
X   struct menu_state *state;		/* place to keep menu state */
X   register int which_menu;		/* which menu indicator */
X
X#ifdef DEBUG
X   dprintf(b)(stderr,"do button %d (button state id %d)\n",button,button_state);
X#endif
X
X   /*	Insist on a transition before taking any action.
X   */
X   if( button == button_state )
X      return;
X
X   /*	Other button codes, such as chords, are not recognized and have no
X	effect.
X   */
X   switch( button ) {
X   case 0:
X   case BUTTON_SYS:
X   case BUTTON_2:
X   case BUTTON_1:
X	break;
X   default:
X	return;
X   }
X
X   /*	If button was down and now no button is down,
X		send the event stating the formerly down button is now up.
X	If some button is down, the same or some other,
X		do nothing.
X	Note that this creates a fundmental property of MGR:  namely that
X	once a button is pressed, no other button pressings have any effect
X	until all buttons are released.
X   */
X   if( button_state ) {
X      if ( button == 0 ) {
X	 int	b_event = -button_state;
X
X	 /* button_state must be cleared before sending a Button_Up event to
X	    prevent any event action from thinking the button is still down.
X	 */
X         button_state = 0;
X         do_event( b_event, active, E_MAIN );
X         }
X      return;
X      }
X
X   /* button_state is the global record of the current button state.
X   */
X   button_state = button;
X
X   /* Check for events associated with this button being pushed.
X   */
X   do_event(button,active,E_MAIN);
X   switch (button) {
X      case BUTTON_1:	/* temporary vi hack */
X#ifdef VI
X           if (active && ACTIVE(flags)&W_VI) {
X
X              int x = mousex-(ACTIVE(x0)+ACTIVE(text).x);
X              int y = mousey-(ACTIVE(y0)+ACTIVE(text).y);
X              int dx = ACTIVE(text).wide ? 
X                       ACTIVE(text).wide : BIT_WIDE(ACTIVE(window));
X              int dy = ACTIVE(text).wide ? 
X                       ACTIVE(text).high : BIT_HIGH(ACTIVE(window));
X
X              if (x<0 || x > dx)
X                 break;
X              if (y>=0 && y<=dy) {
X                 char buff[10];
X                 sprintf(buff,"%dH%d|",
X                      y/ACTIVE(font)->head.high+1,
X                      x/ACTIVE(font)->head.wide+1);
X                 write(ACTIVE(to_fd),buff,strlen(buff));
X                 } 
X              else if (y<0)
X                 write(ACTIVE(to_fd),"\025",1);	/* ASCII Control-U */
X              else
X                 write(ACTIVE(to_fd),"\004",1);	/* ASCII Control-D */
X              }
X#endif
X           if (active) {
X              go_menu(1);
X	   }
X           break;
X      case BUTTON_2:				/* for applic. menu */
X           if (active) {
X              go_menu(0);
X	   }
X           break;
X      case BUTTON_SYS:				/* for system operation */
X           /* see if mouse is in a window */
X           if (mousex < STRIPE)
X              win = (WINDOW *) 0;
X           else
X              for(win=active;win != (WINDOW *) 0;win=W(next))
X                 if(mousein(mousex,mousey,win,1))
X                    break;
X
X           /* do a menu for no window, or active window */
X           if (win == active || win == (WINDOW *) 0) {
X              if (active && win == active) {
X                 state = menu_define(font,active_menu,0,0,
X                         PUTCOLOR(W(style)),
X                         PUTCOLOR(W(background)));
X                 which_menu = 1;
X                 }
X              else if (next_window >= MAXWIN) {
X                 state = menu_define(font,full_menu,0,0,MENU_FG,MENU_BG);
X                 which_menu = 2;
X                 }
X              else {
X                 state = menu_define(font,main_menu,0,0,MENU_FG,MENU_BG);
X                 which_menu = 3;
X                 }
X              if (active) {
X                 cursor_off();
X                 if (which_menu != 1)
X                    ACTIVE_OFF();
X                 }
X              state = menu_setup(state,screen,mousex,mousey,0);
X              menu_get(state,mouse,0,0);
X              choice = menu_choice(state);
X              choice_ok = menu_ischoice(state);
X              menu_destroy(state);
X              if (choice_ok) {
X                 switch(which_menu) {
X                    case 1:
X			 ACTIVE_OFF();
X                         (*active_functions[choice])();
X                         break;
X                    case 2:
X                         (*full_functions[choice])();
X                         break;
X                    case 3:
X                         (*main_functions[choice])();
X                         break;
X                    }
X		 }
X              if (active) {
X                 ACTIVE(flags) &= ~W_NOINPUT;
X                 ACTIVE_ON();
X                 cursor_on();
X                 }
X	      do_button(0);
X              }
X           else {
X		   /* bring obscured window to the top */
X#ifdef DEBUG
X              dprintf(b)(stderr,"activating: %s\r\n",W(tty));
X#endif
X              if (active) {
X                  ACTIVE_OFF();
X                  cursor_off();
X                  }
X              expose(win);
X              if (active) {
X                 ACTIVE(flags) &= ~W_NOINPUT;
X                 ACTIVE_ON();
X                 cursor_on();
X                 }
X              }
X           break;
X           }
X   return;
X   }
X
X/* hide the active window */
X
Xint hide_win()
X   {
X   hide(active);
X   }
X
X/* quit with confirm */
X
Xint quit()
X   {
X   struct menu_state *state;		/* place to keep menu state */
X   int confirm;
X   
X   /* confirm the quit */
X
X   state = menu_define(font,quit_menu,0,0,MENU_BG,MENU_FG);
X   state = menu_setup(state,screen,mousex,mousey,0);
X
X   /* The extra call to menu_get() makes the use of the mouse buttons
X      consistent on the menus; namely the action is selected by the button
X      going up.
X   */
X   menu_get(state,mouse,BUTTON_SYS,0);
X   menu_get(state,mouse,0,0);
X
X   confirm = menu_ischoice(state) ? menu_choice(state) : 0;
X   menu_destroy(state);
X   if (confirm == M_QUIT) {
X      _quit();
X      exit(0);
X      }
X   else if (confirm == M_SUSPEND)
X      suspend();
X   }
X
X/* really quit */
X
Xint
X_quit()
X   {
X   register WINDOW *win;
X   static int really_quit=0;
X
X   if (really_quit++) {			/* we're in bad shape */
X      perror("PANIC!!  Error during _quit()!");
X      setreuid(getuid(),getuid());
X      abort();
X      }
X
X   MOUSE_OFF(mousex,mousey);
X
X   sleep(1);		/* let the key (if any) un-press before resetting
X			the kbd */
X   set_kbd(0);		/* fix up keyboard modes */
X   kbd_reset();		/* reset the keyboard */
X   reset_tty(0);	/* fix up console tty modes */
X
X   /* fix pttys */
X   if (geteuid() < 2)
X      for(win=active;win != (WINDOW *) 0;win=W(next)) {
X         chmod(W(tty),0666);
X         chown(W(tty),0,0);
X         }
X
X   /* fix utmp file */
X
X#ifdef WHO
X   close(getdtablesize()-1); /* make sure there are enough fd's left */
X   for(win=active;win != (WINDOW *) 0;win=W(next))
X      if (W(tty))
X          rm_utmp(W(tty));
X   restore_utmp(0,"");
X#endif
X
X   CLEAR(screen,BIT_CLR);
X   do_cmd( 'q' );	/* do the quiting command */
X   }
X
X/* redraw the screen, restore contents of saved windows */
X
Xint redraw()
X   {
X   register WINDOW *win;
X
X#ifdef DEBUG
X   dprintf(b)(stderr,"\r\n\tREDRAW\r\n");
X#endif
X   for(win=active;win != (WINDOW *) 0;win=W(next)) {
X      if (W(flags)&W_ACTIVE) {
X         save_win(win);
X         do_event(EVENT_REDRAW,win,E_MAIN);
X         }
X      }
X
X   erase_win(screen,0,0);
X   if (active) {
X      for(win=ACTIVE(prev);win != active;win=W(prev)) {
X         restore_win(win);
X         border(win,BLK_BDR,WH_BDR);
X         }
X      restore_win(active);
X      border(active,BLK_BDR,WH_BDR);
X      }
X   }
END_OF_FILE
# end of 'src/do_button.c'
fi
if test -f 'src/do_menu.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/do_menu.c'\"
else
echo shar: Extracting \"'src/do_menu.c'\" \(8358 characters\)
sed "s/^X//" >'src/do_menu.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: do_menu.c,v 4.1 88/06/21 13:21:47 bianchi Exp $
X	$Source: /tmp/mgrsrc/src/RCS/do_menu.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/src/RCS/do_menu.c,v $$Revision: 4.1 $";
X/* high level menu manipulation routines */
X
X#include "bitmap.h"
X#include <stdio.h> 	/* temporary */
X#include "menu.h"
X#include "defs.h"
X#include "font.h"
X
X/* do a tree of menus */
X
Xstatic int x_page = 5;		/* offset for paging menu */
Xstatic int y_page = -5;
Xstatic int x_slide = 40;	/* offset for scrolling menu */
Xstatic int y_slide = 10;
X
Xstruct menu_result *
Xdo_menus(screen,mouse,x,y,font,menu_list,menu,exit_code)
XBITMAP *screen;			/* bitmap screen */
Xint mouse;			/* fd to get mouse coordinates */
Xint x,y;			/* where the menu goes on the screen */
Xstruct font *font;		/* font to use for menus */
Xstruct menu_state *menu_list[];	/* list of available menus */
Xint menu;			/* current menu number */
Xint exit_code;			/* valid exit codes */
X   {
X   struct menu_state  *state;	/* 'cookie' for menu system */
X   struct menu_result *result;	/* messages for nodes of menu tree chosen */
X   int done=0;			/* true if ok to backup a level */
X   int first = 1;		/* true upon entry */
X   int next;			/* next menu # */
X   struct menu_result *add_result();
X   char *print_menu();
X
X   /* set up menu, get menu 'cookie' */
X
X   state = menu_list[menu];	/* fetch the menu state */
X   result = (struct menu_result *) 0;
X   state = menu_setup(state,screen,x,y,menu_choice(state));
X
X   if (state == (struct menu_state *) 0) {
X       perror("Error setting up menu");
X       return(NULL);
X       }
X
X   /* see if another page */
X
X   if (state->next >= 0)
X      exit_code |= EXIT_BOTTOM;
X   else
X      exit_code &= ~EXIT_BOTTOM;
X
X#ifdef DEBUG
X   dprintf(m)(stderr,"  Setting up menu %d at %d,%d: valid states %s\n",
X                      menu,x,y,print_menu(exit_code));
X#endif
X
X   /* get selection on current menu */
X
X   while (!done)
X     {
X
X     /* get menu state from user */
X#ifdef DEBUG
X   dprintf(m)(stderr,"  from user ..."); fflush(stderr);
X#endif
X
X     /* do auto right menus */
X
X     if (state->flags&MENU_PAGE && exit_code&EXIT_BOTTOM && first &&
X                     state->current >= state->count ) {
X        first=0;
X        state->exit = EXIT_BOTTOM;
X        }
X     else if (state->flags&MENU_AUTO && exit_code&EXIT_RIGHT && first) {
X        first=0;
X        state->exit = EXIT_RIGHT;
X        }
X     else
X        menu_get(state,mouse,0,exit_code);
X
X     /* execute appropriate state action */
X
X#ifdef DEBUG
X   dprintf(m)(stderr,"got menu %d (at %d,%d) selection %d (%s)\n",
X              menu,x,y,menu_choice(state),print_menu(menu_exit(state)));
X#endif
X
X     switch (menu_exit(state)) {
X        case EXIT_LEFT:		/* slid off to the left */
X        case EXIT_TOP:		/* slid of the top */
X             result = NULL;
X             done++;
X             break;
X        case EXIT_CHOICE:	/* add current choice onto list */
X             result = add_result(state,result);
X             done++;
X             break;
X        case EXIT_RIGHT:	/* slid off top the right */
X             if ((next = menu_next(state)) >=0 &&	/* link exists */
X                     menu_list[next] &&			/* menu exists */
X                     menu_list[next]->save == (BITMAP *) 0 &&	/* not used */
X                     (result=do_menus(screen,mouse,		/* choice */
X                                      x+x_slide,y-y_slide,font,menu_list,
X                                      next,exit_code|EXIT_LEFT))) {
X                done++;
X                }
X             break;
X        case EXIT_BOTTOM:
X             if ((next = menu_next(state)) >=0 &&	/* menu exists */
X                 menu_list[next]->save == (BITMAP *) 0 &&	/* not used */
X                     (result=do_menus(screen,mouse,		/* choice */
X                                      x+x_page,y+y_page,font,menu_list,
X                                      next,exit_code|EXIT_TOP))) {
X                done++;
X                }
X             break;
X        default:
X	     if( !debug )
X		break;
X             fprintf(stderr,"invalid menu state: 0%o\n",menu_exit(state));
X             result = NULL;
X             done++;
X             break;
X        }
X     }
X  
X#ifdef DEBUG
X   dprintf(m)(stderr,"  Tearing down %d at %d,%d choice: %d, returning: %s\n",
X              menu,x,y,menu_choice(state),print_menu(menu_exit(state)));
X#endif
X
X   /* add our action onto action list */
X
X   if (menu_exit(state) == EXIT_RIGHT && result && !(state->flags&MENU_SNIP)) {
X      result = add_result(state,result);
X      }
X
X   /* erase menu from the screen */
X
X   menu_remove(state);
X   return(result);
X   }
X
X/* add a value to list of menu values */
X
Xstruct menu_result *
Xadd_result(state,list)
Xstruct menu_state *state;		/* menu to add choice to */
Xstruct menu_result *list;		/* current list of results */
X   {
X   register struct menu_result *current;	/* current result */
X   char *malloc();
X
X   /* set up list */
X
X   if (list == (struct menu_result *) 0) {
X      list = (struct menu_result *) malloc(sizeof(struct menu_result));
X      list->next = NULL;
X      list->value = NULL;
X      }
X   else if (list->value == NULL)
X      return(list);
X
X   /* add entry to existing list */
X
X   if (menu_value(state) && *menu_value(state) && 
X                      (current = (struct menu_result *) 
X                       malloc(sizeof(struct menu_result)))) {
X      current->value = menu_value(state);
X      current->next = list;
X      }
X   else
X      current = list;
X   return(current);
X   }
X
X/* do a tree of menus */
X
Xgo_menu(n)
Xint n;					/* which menu button (0 or 1) */
X   {
X   struct menu_result *result = NULL;		/* result of menu selection */
X   register struct menu_result *current;	/* current action */
X   int pushed;
X   int exit = EXIT_RIGHT;			/* enable sliding and paging */
X   register int menu = ACTIVE(menu[n]);
X
X#ifdef DEBUG
X   dprintf(m)(stderr,"Starting menu %d, button %d\n",menu,n);
X#endif
X
X   /* go get a menu selection, return list of actions */
X
X   if (menu>=0 /* && mousein(mousex,mousey,active,0) */) {
X      result = do_menus(screen,mouse,mousex,mousey,
X               font,ACTIVE(menus),menu,exit);
X
X      /* send list of actions, and free action space */
X
X      for(current=result;current;) {
X         if (current->value)
X            Write(ACTIVE(to_fd),current->value,strlen(current->value));
X         result = current;
X         current = current->next;
X         free(result);
X         }
X        
X      /* button is no longer pushed down; record that fact */
X      do_button( 0 );
X      }
X   return;
X   }
X
X/* define a menu from menu download string */
X
Xstruct menu_state *
Xdo_menu(line,font,fg,bg)
Xchar *line;
Xstruct font *font;
Xint fg,bg;		/* fg and bg color */
X   {
X   register int count;
X   char *fields[MAXITEMS];
X
X   count = get_fields(line+1,*line,fields,MAXITEMS)/2;
X
X#ifdef DEBUG
X   dprintf(m)(stderr,"Setting up a menu, %d items\n",count);
X#endif
X   if (count < 1)
X      return((struct menu_state *) 0);
X
X   return(menu_define(font,fields,fields+count,count,fg,bg));
X   }
X
X
X/*******************************************************************************
X *
X * break a line into its component fields 
X */
X
Xstatic int
Xget_fields(line,delim,fields,max)
Xchar *line;				/* line to break into fields */
Xchar **fields;				/* resultant fields */
Xchar delim;				/* field delimeter */
Xint max;				/* max # fields */
X   {
X   register char c, *start;
X   register int count;
X 
X   for(count=0,start=line; count<max && (c = *line); line++)
X      if (c == delim) {
X         fields[count++]=start;
X         *line = '\0';
X         start=line+1;
X         }
X   if (start<line)
X       fields[count++] = start;
X   fields[count]=(char *) 0;
X   return(count);
X   }
X
X/* set slideing defaults */
X
Xint
Xset_slide(x,y)
Xint x,y;
X   {
X   if (x || y) {
X      x_slide = x;
X      y_slide = y;
X      }
X   return(0);
X   }
X
X/* set paging defaults */
X
Xint
Xset_page(x,y)
Xint x,y;
X   {
X   if (x || y) {
X      x_page = x;
X      y_page = y;
X      }
X   return(0);
X   }
END_OF_FILE
# end of 'src/do_menu.c'
fi
echo shar: End of archive 30 \(of 61\).
cp /dev/null ark30isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
	21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 \
	38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 \
	55 56 57 58 59 60 61 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 61 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.