MicroEMACS 3.10 UNIX-PC patchkit part 1 of 2

Floyd Davidson floydd at attctc.Dallas.TX.US
Fri Nov 17 17:54:29 AEST 1989


#  This is part 1 of 2 of the patch kit for MicroEMACS on the UNIX-PC.
#
#  This patch kit requires the original distribution files for
#  MicroEMACS 3.10.  The Readme file lists a free access BBS
#  from which the files may be downloaded.
#
#  This shar file contains:  Readme, Makefile, and unixpc.c
#
#
#----- cut here -----
#!/bin/sh
#
# TO EXTRACT:  remove the header and type "sh filename"
#
if `test ! -s ./Readme`
then
echo "\nWriting ./Readme"
echo "Original file:                   3476 Nov 11 15:11 ./Readme"
cat > ./Readme << '!rebmevoN!9891!'

 >>>>>From main.c:

"*	MicroEMACS 3.10
 *		written by Daniel M. Lawrence
 *		based on code by Dave G. Conroy.
 *
 *	(C)opyright 1988,1989 by Daniel M. Lawrence
 *	MicroEMACS 3.10 can be copied and distributed freely for any
 *	non-commercial purposes. MicroEMACS 3.10 can only be incorporated
 *	into commercial software with the permission of the current author.
 *"

Emacs.pat and original code in unixpc.c are unconditionally released
to the Public Domain.

Emacs.pat is a patch file to configure MicroEMACS 3.10 for a UNIX-PC.
Changes to distribution files are listed below.  MicroEMACS 3.10 is
available in *.arc files from "The Programmers' Room" at (317) 742-5533.
The files are in MSDOS format and must be renamed to lower case and have
all the ^M's removed. Once that is done, use patch, or manually edit,
to convert the files per emacs.pat.

Two new files:  unixpc.c and Makefile.

Unixpc.c is the UNIX-PC terminal driver.  Makefile is configured for
'gcc'.  Reconfiguration of Makefile for 'cc' is trivial, and one change
must be made to estruct.h:  change the GCC define from '1' to '0'.

In addition to the distribution files the Makefile requires the
use of Doug Gwyn's dirent directory library and header files.

Caveats:

This is essentially a beta version.  It is also configured very much
to the author's personal taste, which will likely irritate yours.
Change the key bindings.  If you prefer function and special keys to
be distinct for <Shift> and/or <Ctrl>, change fkeyd() in unixpc.c
by adding more case statements and removing to the uppercase conversion
of the escape sequence.

If the function key bindings are changed in ebind.h it is recommended
to change the default screen labels in unixpc.c.  This can be done by
macros or in .emacsrc, but startup will be slowed down.

*************************************************************************
Changes to bind.c:
    Cast 'errorm' to 'char *'.
    Change setkey() to setakey() to avoid shared lib conflict.
    Change crypt() to krypt() to avoid shared lib conflict.
Changes to bind.h:
    Ifdef out IBMPC function key bindings, ifdef in UNIXPC bindings.
Changes to estruct.h:
    Define USG, UNIX, TERMCAP to TRUE.
    Define COLOR to FALSE.
    Add and define GCC and UNIXPC to TRUE.
    Add conditional to define 'CONST' as 'const' for (UNIX && GCC)
         or '' if (UNIX && !GCC).
    Add conditional to define ETYPE as 'struct' for UNIX.
Changes to etype.h:
    Add 'int' type to all funtions with only 'PASCAL NEAR' or 'CDECL NEAR'.
Changes to eval.c:
    Cast 'errorm' to 'char *'.
    Cast 'falsem' to 'char *'.
    Cast 'truem' to 'char *'.
    Add EVTLABEL# and EVBLABEL# to case statements for setting and
        returning function label variables.
    Change setkey() references to setakey().
Changes to evar.h:
    Add names for function label variables.
    Add numbers for function label variables.
    Add declaration for setflabel() function.
Changes to isearch.c:
    Add 'int' type to reeat().
Changes to region.c:
    Cast 'errorm' to 'char *'.
Changes to tcap.c:
    Change 'UP' to 'UPP' to avoid conflict with shared lib.
    Change 'PC' to 'PCC' to avoid conflict with shared lib.
Changes to window.c:
    Add call to wndwopen() to refresh().


_______________________________________________________

	Floyd L. Davidson		attctc!floydd
	8347 Richardson Hwy.		jolnet!floydd
	Salcha, AK 99714
	(907) 488-3294 

_______________________________________________________
	
!rebmevoN!9891!
else
  echo "\nWill not over write ./Readme"
fi
ls -l ./Readme
#
if `test ! -s ./Makefile`
then
echo "\nWriting ./Makefile"
echo "Original file:                   2438 Nov 11 15:11 ./Makefile"
cat > ./Makefile << '!rebmevoN!9891!'
#
# Makefile  --  MicroEmacs 3.10 / UNIX-PC 7300/3B1
#
####################################################
#
#  compiler selection (uncomment one or the other)
#
####################################################
# uncomment only for 'gcc'
#   also, in file estruct.h define GCC=1
CC      =gcc
LD	=gcc
CFLAGS  =-O
LDFLAGS =-s -shlib
#
####################################################
# uncomment only for 'cc'
#   also, in file estruct.h define GCC=0
#CC      =cc
#LD	=ld
#CFLAGS  =-O
#LDFLAGS = /lib/crt0s.o /lib/shlib.ifile
####################################################

OFILES=	basic.o bind.o buffer.o char.o crypt.o display.o \
	eval.o exec.o file.o fileio.o input.o isearch.o \
	line.o main.o mouse.o random.o region.o \
	search.o tcap.o unixpc.o window.o word.o

CFILES=	basic.c bind.c buffer.c char.c crypt.c display.c \
	eval.c exec.c file.c fileio.c input.c isearch.c \
	line.c main.c mouse.c random.c region.c \
	search.c tcap.c unixpc.c window.c word.c

HFILES1=estruct.h etype.h edef.h elang.h

emacs:		$(OFILES)
		$(LD) $(LDFLAGS) $(OFILES) -ldirent -o em1
		mv em1 emacs

basic.o:	basic.c $(HFILES1)
		${CC} ${CFLAGS} -c basic.c

bind.o:		bind.c $(HFILES1) epath.h
		${CC} ${CFLAGS} -c bind.c

buffer.o:	buffer.c $(HFILES1)
		${CC} ${CFLAGS} -c buffer.c

char.o:		char.c $(HFILES1)
		${CC} ${CFLAGS} -c char.c

crypt.o:	crypt.c $(HFILES1)
		${CC} ${CFLAGS} -c crypt.c

display.o:	display.c $(HFILES1)
		${CC} ${CFLAGS} -c display.c

eval.o:		eval.c $(HFILES1) evar.h
		${CC} ${CFLAGS} -c eval.c

exec.o:		exec.c $(HFILES1)
		${CC} ${CFLAGS} -c exec.c

file.o:		file.c $(HFILES1)
		${CC} ${CFLAGS} -c file.c

fileio.o:	fileio.c $(HFILES1)
		${CC} ${CFLAGS} -c fileio.c

input.o:	input.c $(HFILES1)
		${CC} ${CFLAGS} -c input.c

isearch.o:	isearch.c $(HFILES1)
		${CC} ${CFLAGS} -c isearch.c

line.o:		line.c $(HFILES1)
		${CC} ${CFLAGS} -c line.c

main.o:		main.c $(HFILES1) efunc.h ebind.h
		${CC} ${CFLAGS} -c main.c

mouse.o:	mouse.c $(HFILES1) efunc.h ebind.h
		${CC} ${CFLAGS} -c mouse.c

random.o:	random.c $(HFILES1)
		${CC} ${CFLAGS} -c random.c

region.o:	region.c $(HFILES1)
		${CC} ${CFLAGS} -c region.c

search.o:	search.c $(HFILES1)
		${CC} ${CFLAGS} -c search.c

tcap.o:		tcap.c $(HFILES1)
		${CC} ${CFLAGS} -c tcap.c

unixpc.o:	unixpc.c $(HFILES1)
		${CC} ${CFLAGS} -c unixpc.c

window.o:	window.c $(HFILES1)
		${CC} ${CFLAGS} -c window.c

word.o:		word.c $(HFILES1)
		${CC} ${CFLAGS} -c word.c

!rebmevoN!9891!
else
  echo "\nWill not over write ./Makefile"
fi
ls -l ./Makefile
#
if `test ! -s ./unixpc.c`
then
echo "\nWriting ./unixpc.c"
echo "Original file:                  25254 Nov 11 15:06 ./unixpc.c"
cat > ./unixpc.c << '!rebmevoN!9891!'
/*	unixpc.c -- unix.c for the UNIX-PC 7300/3B1

		Operating specific I/O and Spawning functions
		under UNIX V7, BSD4.2/3, System V, SUN OS and SCO XENIX
		for MicroEMACS 3.10
		(C)opyright 1988 by Daniel M. Lawrence

Mouse and function key support for the AT&T Unix-PC 7300/3b1.

Modified from MicroEMACS 3.10 distribution file unix.c.
Modifications are Public Domain.

**************************************************************************
   Default function key screen labels should be customized for whatever
   bindings are set in ebind.h.  They can be changed with macros or by
   .emacsrc, but it does make startup slowwww.
**************************************************************************

DISCLAIMER:  This was written to satisfy my personal editor needs (spelled
		r-e-l-i-g-i-o-n).  E.g. having all function and special
		keys the same whether or not the shift or control keys are
		pressed.  Others may want them decoded separately.
		
		
	Floyd L. Davidson		attctc!floydd
	8347 Richardson Hwy.		jolnet!floydd
	Salcha, AK 99714

*/


/*
 * Support for the Unix-Pc mouse, function and special keys
 * is implemented by converting escape code sequences to
 * appropriate characters or sequences for MicroEMACS.
 *
 * Function and special keys are defined such that
 * <Ctrl> or <Shift> does NOT change the key definition.
 *
 * Mouse button functions are defined in mouse.c.
 * Function and special key bindings are defined in ebind.h.
 *
 * The following table shows the (SPEC|character) that each key
 * sends to MicroEMACS:
 *
 *			   MicroEMACS KEYMAP
 *			    Unix-Pc 7300/3b1
 *
 *  ClearLine	'O'	  Rstrt/Ref	'P'	  F1	  	'1'
 *  Creat	'T'	  Save		'U'	  F2	  	'2'
 *  Undo	'Y'	  Redo		'Z'	  F3	  	'3'
 *  Find	'd'	  Rplac		'e'	  F4	  	'3'
 *  Move	'C'	  Copy		'D'	  F5	  	'5'
 *  Dlete	'E'	  DleteChar	'F'	  F6	  	'6'
 *  Slect/Mark	'I'	  InputMode	'J'	  F7	  	'7'
 *						  F8	  	'8'
 *
 *  Exit	'Q'	  Msg		----	  Help	  	'S'
 *  Suspd	----	  Rsume		----	  Opts	  	'X'
 *  Cmd		'a'	  Close/Open	'b'	  Cancl	  	'c'
 *  Print	'f'	  Clear/Rfrsh	'A'	  Page	  	'i'
 *  Beg		'B'	  Home		'M'	  End	  	'N'
 *  Prev	'G'	  UpArrow	'g'	  Next	  	'H'
 *  LeftArrow 	'K'	  DownArrow	'h'	  RghtArrow	'L'
 *
 *
 *  Keys marked '----' are owned by the system (ie. ph and smgr).
 *  In addition Sh-Print is owned by the system.
 *
 */

#include        <stdio.h>
#include	<track.h>
#include	"estruct.h"
#include	"etype.h"
#include        "edef.h"
#include	"elang.h"
#include	<termio.h>
#include	<fcntl.h>
#include	<dirent.h>
#include	<sys/stat.h>

char		kbdq;		/* char we've already read		*/
int		mouserow;	/* mouse row				*/
int		mousecol;	/* mouse column				*/
int		lbutton;	/* flag that left button changed	*/
int		mbutton;	/* flag that middle button changed	*/
int		rbutton;	/* flag that right button changed	*/
int		nullflag;	/* flag a null, not a mouse action	*/
int		lkey;		/* last key action			*/
int		kbdflgs;	/* saved keyboard fd flags		*/
int		kbdpoll;	/* in O_NDELAY mode			*/
int		kbdqp;		/* there is a char in kbdq		*/
int		mvalue;		/* mouse return value			*/
int		kbdch;		/* char to return			*/
int		fkeyd();	/* return decoded/encoded keystroke	*/
int		getmouse();	/* decodes mouse escape sequences	*/
struct termio	otermio;	/* original terminal characteristics	*/
struct termio	ntermio;	/* charactoristics to use inside	*/

#define MAXSLK 79
#define SLKTEXT " %s %s %s    %s %s    %s %s %s "
struct utdata	utd;		/* new window data structure	        */
char		utd1old[MAXSLK];/* original window labels, line 1	*/
char		utd2old[MAXSLK];/* original window labels, line 2	*/
struct umdata	mdnew;		/* new mouse info data structure	*/
struct umdata	mdold;		/* original mouse info data structure	*/

#ifdef ESC
#undef ESC
#endif
#define	ESC	0x1b

/*
 * default function key labels.
 */

char *deflabels[] = {
	/* strings for the top line of labels */
	"  exec",	/* F1 key */
	"  begin",	/* F2 key */
	"  end",	/* F3 key */
	" ",	/* F4 key */
	" ",	/* F5 key */
	" ",	/* F6 key */
	" ",	/* F7 key */
	" ",	/* F8 key */
	/* strings for the botton line of labels */
	"  macro",	/* F1 key */
	"  macro",	/* F2 key */
	"  macro",	/* F3 key */
	" ",	/* F4 key */
	" ",	/* F5 key */
	" ",	/* F6 key */
	" ",	/* F7 key */
	" "	/* F8 key */
};

char *flabels[16];

/*  Labels for function keys.  These may be changed using
 *   environmental variables $tlabel1 to $tlabel8 for the
 *   top line and $blabel1 to $blabel8 for the bottom line.
 *   Only 8 characters are used, any excess is discarded.
 *    
 *  setflabel() returns a pointer to the label string, and
 *  sets a new string.
 */

char *setflabel(s,n)
char	*s;
int	n;
{
	char buffer[18];
	unsigned int i;
	static int flag = 0;

	if (!flag) {
		for (i=0;i < 16; ++i) {
			flabels[i] = (char *) malloc(9);
			if (flabels[i] == (char *)NULL) {
				printf("memory fault");
				exit(1);
			}
			strncpy(buffer,deflabels[i],8);
			buffer[8] = '\0';
			strcat(buffer,"        ");
			strncpy(flabels[i],buffer,8);
			flabels[i][8] = '\0';
		}
	flag = 1;
	}

	if (s != (char *) NULL) {
		/* truncate and/or fill labels to exactly eight characters */
		strncpy(buffer,s,8);
		buffer[8] = '\0';
		strcat(buffer,"        ");
		strncpy(flabels[n],buffer,8);
		flabels[n][8] = '\0';
	}
	return(flabels[n]);
}

/*
 * gets and parses a mouse input escape sequence .
 */
int getmouse()
{
	register int	ccnt;
	unsigned char	mque[15];	/* mouse sequence que		*/
	unsigned char	*qptr;		/* ptr into kbdque[]  		*/
	unsigned char	*xptr[4];	/* ptrs to mouse data segments	*/
	unsigned int	i = 0;		/* token counter		*/
	unsigned int	k = 0;		/* char counter			*/
	int		ckey;		/* current key action		*/
	int		key;		/* individual key		*/
	char		*s1,*s2;

	xptr[i++] = &mque[0];

	for (k=0;k < 15;++k) {

		ccnt = read(0, &mque[k], 1);	/* get another character */

		if (!ccnt)
			return;			/* no char, must be error */

		if (';' == mque[k]) {
			mque[k] = '\0';
			xptr[i++] = &mque[k+1];	/* set next token ptr */

		} else if ('M' == mque[k]) {
			mque[k] = '\0';
			break;				/* end of data */

		} else if ('\0' == mque[k]) {
			++i;				/* flag error */
			break;
		}
	}


	k = atoi(xptr[3]);
	mousecol = (atoi(xptr[0])+8) / 9;
	mouserow = (atoi(xptr[1])+11) / 12;
	if (!mousecol) mousecol = 1;
	if (!mouserow) mousecol = 1;

/*
 *  need to do this different. Keep a new flag and and old
 *  flag for each one.  set the button flags if they have
 *  changed.
 */
	ckey = atoi(xptr[2]);

	if(2 == k)
		ckey = lkey - ckey;

	if(1 == k)
		ckey = ckey - lkey;


	lkey = atoi(xptr[2]);

	lbutton = ckey & 4;
	mbutton = ckey & 2;
	rbutton = ckey & 1;
	mvalue  = k;

	return(TRUE);
}


/*
 *   decode function key escape sequence to a single chararacter.
 *
 *   All keys are tranlated to the same character whether
 *   unshifted or Shift or Ctrl.
 *
 */
int fkeyd()
{
register int	ccnt;
char		kbdque[4];

	/* set O_NDELAY */
	if (!kbdpoll && fcntl(0, F_SETFL, kbdflgs | O_NDELAY) < 0)
		return(FALSE);
	kbdpoll = TRUE;

	ccnt=read(0, kbdque, 2);	/* get 2 more chars */

	if (ccnt < 1)
		return (ESC);		/* only an ESC, return it */

	kbdque[ccnt] = 0;		/* terminate it */

/*****************************************************************\
* Delete this statement and add case statements for lower case if *
* Shift or Ctrl is to be decoded distinctly.			  *
\*****************************************************************/

	/* convert to upper case (except 'z') */
	kbdque[1] = ( (kbdque[1] >= 'a') && (kbdque[1] < 'z') ) ? kbdque[1] - 0x20 : kbdque[1];

	switch (kbdque[0]) {
/* \ENx */	case 'N': switch (kbdque[1]) {
	/* Clear/Rfrsh */	case 'A': ccnt = (SPEC | 'A');break;
	/* s-Beg  */		case 'B': ccnt = (SPEC | 'B');break;
	/* Move */		case 'C': ccnt = (SPEC | 'C');break;
	/* Copy */		case 'D': ccnt = (SPEC | 'D');break;
	/* Dlete */		case 'E': ccnt = (SPEC | 'E');break;
	/* DleteChar */		case 'F': ccnt = (SPEC | 'F');break;
	/* Prev */		case 'G': ccnt = (SPEC | 'G');break;
	/* Next */		case 'H': ccnt = (SPEC | 'H');break;
	/* Slect/Mark */	case 'I': ccnt = (SPEC | 'I');break;
	/* InputMode */		case 'J': ccnt = (SPEC | 'J');break;
	/* s-LeftArrow */	case 'K': ccnt = (SPEC | 'K');break;
	/* s-RghtArrow */	case 'L': ccnt = (SPEC | 'L');break;
	/* s-Home */		case 'M': ccnt = (SPEC | 'M');break;
	/* s-End */		case 'N': ccnt = (SPEC | 'N');break;
	/* invalid sequence */	default : ccnt = (SPEC | '!');break;
			};break;

/* \EOx */	case 'O': switch (kbdque[1]) {
	/* ClearLine */		case 'A': ccnt = (SPEC | 'O');break;
	/* Rstrt/Ref */		case 'B': ccnt = (SPEC | 'P');break;
	/* F1 */		case 'C': ccnt = (SPEC | '1');break;
	/* F2 */		case 'D': ccnt = (SPEC | '2');break;
	/* F3 */		case 'E': ccnt = (SPEC | '3');break;
	/* F4 */		case 'F': ccnt = (SPEC | '4');break;
	/* F5 */		case 'G': ccnt = (SPEC | '5');break;
	/* F6 */		case 'H': ccnt = (SPEC | '6');break;
	/* F7 */		case 'I': ccnt = (SPEC | '7');break;
	/* F8 */		case 'J': ccnt = (SPEC | '8');break;
	/* Exit */		case 'K': ccnt = (SPEC | 'Q');break;
	/* Msg */		case 'L': ccnt = (SPEC | 'R');break;
	/* Help */		case 'M': ccnt = (SPEC | 'S');break;
	/* Creat */		case 'N': ccnt = (SPEC | 'T');break;
	/* Save */		case 'O': ccnt = (SPEC | 'U');break;
	/* Suspd */		case 'P': ccnt = (SPEC | 'V');break;
	/* Rsume */		case 'Q': ccnt = (SPEC | 'W');break;
	/* Opts */		case 'R': ccnt = (SPEC | 'X');break;
	/* Undo */		case 'S': ccnt = (SPEC | 'Y');break;
	/* Redo */		case 'T': ccnt = (SPEC | 'Z');break;
	/* Cmd */		case 'U': ccnt = (SPEC | 'a');break;
	/* Close/Open */	case 'V': ccnt = (SPEC | 'b');break;
	/* Cancl */		case 'W': ccnt = (SPEC | 'c');break;
	/* Find */		case 'X': ccnt = (SPEC | 'd');break;
	/* Rplac */		case 'Y': ccnt = (SPEC | 'e');break;
	/* Print */		case 'z': ccnt = (SPEC | 'f');break;
	/* invalid sequence */	default : ccnt = (SPEC | '@');break;
			};break;

/* \EPx */	case 'P': switch (kbdque[1]) {
	/* PF1 '1'*/		case 'A': ccnt = (SPEC | 'G');break;
	/* PF2 '2'*/		case 'B': ccnt = (SPEC | 'g');break;
	/* PF3 '3'*/		case 'C': ccnt = (SPEC | 'H');break;
	/* PF4 '4'*/		case 'D': ccnt = (SPEC | 'B');break;
	/* PF5 '5'*/		case 'E': ccnt = (SPEC | 'M');break;
	/* PF6 '6'*/		case 'F': ccnt = (SPEC | 'N');break;
	/* PF7 '7'*/		case 'G': ccnt = (SPEC | 'f');break;
	/* PF8 '8'*/		case 'H': ccnt = (SPEC | 'A');break;
	/* PF9 '9'*/		case 'I': ccnt = (SPEC | 'k');break;
	/* PF10 '0'*/		case 'J': ccnt = (SPEC | 'h');break;
	/* PF11 '-'*/		case 'K': ccnt = (SPEC | 'K');break;
	/* PF12 '='*/		case 'L': ccnt = (SPEC | 'L');break;
	/* invalid sequence */	default : ccnt = (SPEC | '#');break;
			};break;

/* \E[x */	case '[': switch (kbdque[1]) {
	/* UpArrow */		case 'A': ccnt = (SPEC | 'g');break;
	/* DnArrow */		case 'B': ccnt = (SPEC | 'h');break;
	/* RghtArrow */		case 'C': ccnt = (SPEC | 'L');break;
	/* LeftArrow */		case 'D': ccnt = (SPEC | 'K');break;
	/* Home */		case 'H': ccnt = (SPEC | 'M');break;
	/* s/^ Clear/Rfrsh */	case 'J': ccnt = (SPEC | 'A');break;
	/* Roll up */		case 'S': ccnt = (SPEC | 'h');break;
	/* Roll down */		case 'T': ccnt = (SPEC | 'g');break;
	/* Page */		case 'U': ccnt = (SPEC | 'i');break;
	/* s-Page */		case 'V': ccnt = (SPEC | 'i');break;
	/* s-Tab */		case 'Z': ccnt = ('\011');break;
	/* Mouse */		case '?': if(getmouse()) {
						  ccnt = '\0';
						  nullflag = 2; /* flag null sent */
						  break;
				   	   } else {ccnt = (SPEC | '*');break;}
				   	   
	/* invalid sequence */	default : ccnt = (SPEC | '$');break;
			};break;

/* \Ex */
	/* Beg */	case '9': ccnt = (SPEC | 'B');break;
	/* End */	case '0': ccnt = (SPEC | 'N');break;
	/* invalid sequence */	default:  ccnt = (SPEC | '%');break;
	}

	return (ccnt);
}


/*
 * Set up the terminal.
 */
ttopen()
{
	struct uwdata uw;
	void	wndwopen();

	ioctl(0, TCGETA, &otermio);	/* save old settings */
	ntermio.c_iflag 	= 0;	/* setup new settings */
	ntermio.c_oflag 	= 0;
	ntermio.c_cflag 	= otermio.c_cflag;
	ntermio.c_lflag 	= 0;
	ntermio.c_line 		= otermio.c_line;
	ntermio.c_cc[VMIN] 	= 1;
	ntermio.c_cc[VTIME] 	= 1;
	ioctl(0, TCSETAW, &ntermio);	/* and activate them */

	kbdflgs = fcntl( 0, F_GETFL, 0 );
	kbdpoll = FALSE;

	/* on all screens we are not sure of the initial position
	   of the cursor					*/

	ttrow = 999;
	ttcol = 999;

	/*  See if it's a bitmapped display */
	if ( 0 == ioctl(1,WIOCGETD, &uw)) {
		wndwopen(TRUE);
	}
}

/*
 * If the tty is a windowed device we assume is also has a mouse,
 * and initialize the mouse and screen labels.  When called with
 * a saveflag value TRUE all label and mouse data is saved, otherwise
 * not.
 */
void wndwopen(saveflag)
{
	char		slkbuf1[81];
	char		slkbuf2[81];
	char		*ptr0,*ptr1;
	char		label[16][18];
	unsigned int	i;

	/* turn on the mouse */

	if (saveflag) {
		ioctl(0, WIOCGETMOUSE, &mdold);	/* save original data */
	}

	ioctl(0, WIOCGETMOUSE, &mdnew);
	mdnew.um_icon = (struct icon *)NULL;	/* use default pointer */
	mdnew.um_flags = MSDOWN | MSUP;		/* sent up/down data */
	ioctl(0, WIOCSETMOUSE, &mdnew);

	/* set up function key labels */

	utd.ut_num = WTXTSLK1;
        ioctl(0, WIOCGETTEXT, &utd);		/* save original data */

	if (saveflag) {
		ptr0=utd1old;
		ptr1=utd.ut_text;
		strncpy(ptr0,ptr1,MAXSLK);
		utd.ut_num = WTXTSLK2;
	        ioctl(0, WIOCGETTEXT, &utd);
	        ptr0=utd2old;
		ptr1=utd.ut_text;
		strncpy(ptr0,ptr1,MAXSLK);
	}

	/* strings for the top line of labels */
	sprintf(slkbuf1,SLKTEXT,		/* make new labels */
		setflabel(0,0),
		setflabel(0,1),
		setflabel(0,2),
		setflabel(0,3),
		setflabel(0,4),
		setflabel(0,5),
		setflabel(0,6),
		setflabel(0,7)
		);

	/* strings for the botton line of labels */
	sprintf(slkbuf2,SLKTEXT,
		setflabel(0,8),
		setflabel(0,9),
		setflabel(0,10),
		setflabel(0,11),
		setflabel(0,12),
		setflabel(0,13),
		setflabel(0,14),
		setflabel(0,15)
		);
	slkbuf1[80] = slkbuf2[80] = '\0';
	winit();
	wslk(0, 0, slkbuf1, slkbuf2, 0);
	wdelete(wgetsel());

}

/*
 * Restore original terminal device state.
 */
ttclose()
{
	struct uwdata uw;
	void	wndwclose();

	ioctl(0, TCSETA, &otermio);		/* restore terminal */
	fcntl(0, F_SETFL, kbdflgs);

	/*  See if it's a bitmapped display */
	if ( 0 == ioctl(1,WIOCGETD, &uw)) {
		wndwclose();
	}
}

/*
 *  Close window, restore original mouse and label data.
 */
void wndwclose()
{
	char *ptr0,*ptr1;

	ioctl(0, WIOCSETMOUSE, &mdold);		/* restore mouse */

	ptr0 = utd.ut_text;
	ptr1 = utd1old;
	strncpy(ptr0,ptr1,MAXSLK);
	utd.ut_num = WTXTSLK1;
        ioctl(0, WIOCSETTEXT, &utd);		/* restore labels  */

	ptr0 = utd.ut_text;
	ptr1 = utd2old;
	utd.ut_num = WTXTSLK2;
	strncpy(ptr0,ptr1,MAXSLK);
        ioctl(0, WIOCSETTEXT, &utd);
}

/*
 * Write a character to the display.
 */
ttputc(c)
{
        fputc(c, stdout);
}

/*
 * Flush terminal buffer.
 */
ttflush()
{
        fflush(stdout);
}

/*	TTGETC:	Read a character from the terminal, performing no
		editing and doing no echo at all.

*/

ttgetc()
{

	/* return queued character first */
	if (kbdqp) {
		kbdqp = FALSE;
		return (kbdch);
	}


	/* return nulls or mouse sequences */
	if ( lbutton | mbutton | rbutton | nullflag ) {

		++nullflag;

		if ( (nullflag > 1) && !(lbutton|mbutton|rbutton) )
			nullflag = 1;

		switch (nullflag) {
			case (0): nullflag = 0;return('\0');/* for real null */
			case (1): nullflag = 0;break;
			case (2): nullflag = 0;return('\0');/* mark esc seq. */
			case (3): return(MOUS >> 8);	    /* prefix a mouse */
			case (4): return(mousecol-1);	    /* x-axis */
			case (5): return(mouserow-1);	    /* y-axis */
			case (6): mvalue += (0x60);	    /* what happened */
				  nullflag = 0;
				  if (lbutton) {
					lbutton = 0;
					return(mvalue);
				  }

				  else if (mbutton) {
					mbutton = 0;
					return(mvalue+2);
				  }

				  else if (rbutton) {
					rbutton = 0;
					return(mvalue+4);
				  }
			 	  /* end of case (5) */
			default: nullflag = 0;break; /* error if we do this */
		} /* switch (nullflag) */
	} /* if flags */


	/* the character que is empty, no nulls are needed and no mouse seq. */
	/* so turn off O_NDELAY and wait patiently...			     */

	if (kbdpoll && fcntl(0, F_SETFL, kbdflgs) < 0)
		return(FALSE);
	kbdpoll = FALSE;	/* no polling */

	while (read(0,&kbdq,1) < 1)
		;

	kbdch = kbdq & 0x7f;		/* make Reset/Break a <DEL> */
	if(!kbdch) nullflag = -1;	/* send two nulls for a null */
	if(kbdch == ESC)
		kbdch = fkeyd();	/* decode possible /E seq */

	return(kbdch);
}

/* typahead:	Check to see if any characters are already in the
		keyboard buffer
*/

typahead()
{
	/* already queued up */
	if (kbdqp) {
		return (TRUE);
	}

	/* mouse sequence is processing, que it */
	if (lbutton | mbutton | rbutton | nullflag) {
		kbdch = ttgetc();
		kbdqp = TRUE;
		return (TRUE);
	}

	/* set O_NDELAY and get a character to que */
	if (!kbdpoll && fcntl(0, F_SETFL, kbdflgs | O_NDELAY) < 0)
		return(FALSE);

	kbdpoll = TRUE;
	kbdqp = (1 == (read(0,&kbdq,1)));
	if(kbdqp) {
		kbdch = kbdq & 0x7f;		/* change the Reset/Break key*/
		if(!kbdch) nullflag = -1;	/* send two nulls for a null */
		if (kbdch == ESC) {
			kbdch = fkeyd();	/* decode possible /E seq */
		}
	}

	return(kbdqp);
}

/*
 * Create a subjob with a copy of the command intrepreter in it. When the
 * command interpreter exits, mark the screen as garbage so that you do a full
 * repaint. Bound to "^X C".
 */
spawncli(f, n)
{
        register char *cp;
        char    *getenv();

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

        movecursor(term.t_nrow, 0);             /* Seek to last line.   */
        TTflush();
        TTclose();                              /* stty to old settings */
        if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
                system(cp);
        else
                system("exec /bin/sh");
        sgarbf = TRUE;
	sleep(2);
        TTopen();
        return(TRUE);
}


/*
 * Run a one-liner in a subjob. When the command returns, wait for a single
 * character to be typed, then mark the screen as garbage so a full repaint is
 * done. Bound to "C-X !".
 */
spawn(f, n)
{
        register int    s;
        char            line[NLINE];

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

        if ((s=mlreply("shell-command: ", line, NLINE)) != TRUE)
                return(s);
        TTputc('\n');                           /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
        system(line);
        TTopen();
        TTflush();
	/* if we are interactive, pause here */
	if (clexec == FALSE) {
	        mlwrite("[End]");
	        TTflush();
        	tgetc();
        }
        sgarbf = TRUE;
        return(TRUE);
}

/*
 * Run an external program with arguments. When it returns, wait for a single
 * character to be typed, then mark the screen as garbage so a full repaint is
 * done. Bound to "C-X $".
 */

execprg(f, n)
{
        register int    s;
        char            line[NLINE];

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

        if ((s=mlreply("shell-command: ", line, NLINE)) != TRUE)
                return(s);
        TTputc('\n');                           /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
        system(line);
        TTopen();
        mlwrite("[End]");                        /* Pause.               */
        TTflush();
        while ((s = tgetc()) != '\r' && s != ' ')
                ;
        sgarbf = TRUE;
        return(TRUE);
}

/*
 * Pipe a one line command into a window
 * Bound to ^X @
 */
pipecmd(f, n)
{
        register int    s;	/* return status from CLI */
	register WINDOW *wp;	/* pointer to new window */
	register BUFFER *bp;	/* pointer to buffer to zot */
        char	line[NLINE];	/* command line send to shell */
	static char bname[] = "command";

	static char filnam[NFILEN] = "command";

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

	/* get the command to pipe in */
        if ((s=mlreply("pipe-command: ", line, NLINE)) != TRUE)
                return(s);

	/* get rid of the command output buffer if it exists */
        if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
		/* try to make sure we are off screen */
		wp = wheadp;
		while (wp != NULL) {
			if (wp->w_bufp == bp) {
				onlywind(FALSE, 1);
				break;
			}
			wp = wp->w_wndp;
		}
		if (zotbuf(bp) != TRUE)

			return(FALSE);
	}

        TTputc('\n');                       /* Already have '\r'    */
        TTflush();
        TTclose();                          /* stty to old modes    */
	strcat(line,">");
	strcat(line,filnam);
        system(line);
        TTopen();
        TTflush();
        sgarbf = TRUE;
        s = TRUE;

	if (s != TRUE)
		return(s);

	/* split the current window to make room for the command output */
	if (splitwind(FALSE, 1) == FALSE)
			return(FALSE);

	/* and read the stuff in */
	if (getfile(filnam, FALSE) == FALSE)
		return(FALSE);

	/* make this window in VIEW mode, update all mode lines */
	curwp->w_bufp->b_mode |= MDVIEW;
	wp = wheadp;
	while (wp != NULL) {
		wp->w_flag |= WFMODE;
		wp = wp->w_wndp;
	}

	/* and get rid of the temporary file */
	unlink(filnam);
	return(TRUE);
}

rename(old, new)	/* change the name of a file */

char *old;	/* original file name */
char *new;	/* new file name */

{
	link(old, new);
	unlink(old);
}

/*
 * filter a buffer through an external program
 * Bound to ^X #
 */
filter(f, n)
{
        register int	s;			/* return status from CLI */
	register BUFFER	*bp;			/* pointer to buffer to zot */
        char		line[NLINE];		/* command line send to shell */
	char		tmpnam[NFILEN];		/* place to store real file name */
	static char	bname1[]  = "fltinp";
	static char	filnam1[] = "fltinp";
	static char	filnam2[] = "fltout";

	/* don't allow this command if restricted */
	if (restflag)
		return(resterr());

	if (curbp->b_mode&MDVIEW)	/* don't allow this command if	*/
		return(rdonly());	/* we are in read only mode	*/

	/* get the filter name and its args */
        if ((s=mlreply("filter-buffer: ", line, NLINE)) != TRUE)
                return(s);

	/* setup the proper file names */
	bp = curbp;
	strcpy(tmpnam, bp->b_fname);	/* save the original name */
	strcpy(bp->b_fname, bname1);	/* set it to our new one */

	/* write it out, checking for errors */
	if (writeout(filnam1) != TRUE) {
		mlwrite("[Cannot write filter file]");
		strcpy(bp->b_fname, tmpnam);
		return(FALSE);
	}

        TTputc('\n');                /* Already have '\r'    */
        TTflush();
        TTclose();                              /* stty to old modes    */
	strcat(line," <fltinp >fltout");
        system(line);
        TTopen();
        TTflush();
        sgarbf = TRUE;
        s = TRUE;

	/* on failure, escape gracefully */
	if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
		mlwrite("[Execution failed]");
		strcpy(bp->b_fname, tmpnam);
		unlink(filnam1);
		unlink(filnam2);
		return(s);
	}

	/* reset file name */
	strcpy(bp->b_fname, tmpnam);	/* restore name */
	bp->b_flag |= BFCHG;		/* flag it as changed */

	/* and get rid of the temporary file */
	unlink(filnam1);
	unlink(filnam2);
	return(TRUE);
}

/*
 * Return a system dependant string with the current time.
 */

char * timeset()

{
	register char *sp;	/* temp string pointer */
	char buf[16];		/* time data buffer */
	extern char *ctime();

	time(buf);
	sp = ctime(buf);
	sp[strlen(sp)-1] = 0;
	return(sp);
}

#if	COMPLET
/*	FILE Directory routines		*/

DIR *dirptr = NULL;	/* pointer to the current directory being searched */

char path[NFILEN];	/* path of file to find */
char rbuf[NFILEN];	/* return file buffer */
char *nameptr;		/* ptr past end of path in rbuf */

/*	do a wild card directory search (for file name completion) */

char * getffile(fspec)

char *fspec;	/* pattern to match */

{
	register int index;		/* index into various strings */
	register int point;		/* index into other strings */
	register int extflag;		/* does the file have an extention? */

	/* first parse the file path off the file spec */
	strcpy(path, fspec);
	index = strlen(path) - 1;
	while (index >= 0 && (path[index] != '/' &&
				path[index] != '\\' && path[index] != ':'))
		--index;
	path[index+1] = 0;

	/* check for an extension */
	point = strlen(fspec) - 1;
	extflag = FALSE;
	while (point >= 0) {
		if (fspec[point] == '.') {
			extflag = TRUE;
			break;
		}
		point--;
	}

	/* open the directory pointer */
	if (dirptr != NULL) {
		closedir(dirptr);
		dirptr = NULL;
	}
	dirptr = opendir(path);
	if (dirptr == NULL)
		return(NULL);

	strcpy(rbuf, path);
	nameptr = &rbuf[strlen(rbuf)];

	/* and call for the first file */
	return(getnfile());
}

char * getnfile()

{
	register struct dirent *dp;	/* directory entry pointer */
	register int index;		/* index into various strings */
	struct stat fstat;

	/* and call for the next file */
nxtdir:	dp = readdir(dirptr);
	if (dp == NULL)
		return(NULL);

	/* check to make sure we skip directory entries */
	strcpy(nameptr, dp->d_name);
	stat(rbuf, &fstat);
	if ((fstat.st_mode & S_IFMT) != S_IFREG)
		goto nxtdir;

	/* return the next file name! */
	return(rbuf);
}
#else
char * getffile(fspec)

char *fspec;	/* file to match */

{
	return(NULL);
}

char * getnfile()

{
	return(NULL);
}

#endif
!rebmevoN!9891!
else
  echo "\nWill not over write ./unixpc.c"
fi
ls -l ./unixpc.c
#
echo "\nPart 1 Finished...\n"



More information about the Unix-pc.sources mailing list