/**************************************************************
 *
 *	CRISP - Custom Reduced Instruction Set Programmers Editor
 *
 *	(C) Paul Fox, 1989
 *
 *
 *    Please See COPYLEFT notice.
 *
 **************************************************************/
# ifndef	_DEF
# define	_DEF

/**********************************************************************/
/*   Following  macro  used  to  allow  compilation  with ANSI C and  */
/*   non-ANSI C compilers automatically.			      */
/**********************************************************************/
# if !defined(PROTO)
# 	if	defined(__STDC__)
#		define	PROTO(x)	x
#	else
#		define	PROTO(x)	()
#	endif
# endif

# include	"machine.h"
# include	<stdio.h>
# if	defined(GOT_STDLIB)
# 	include	<stdlib.h>
# endif
# include	<memory.h>

# undef NULL		/* Some system define NULL to be a stupid value */
# define NULL	0	/* E.g., Microsoft sets it to (void *) 0. 	*/

# if	defined(VMS)
# 	include	"llist.h"
#	define	EXIT_FAILURE	0
#	define	EXIT_SUCCESS	1
# else
# 	include	"llist/llist.h"
#	if !defined(EXIT_FAILURE)
#		define	EXIT_FAILURE	1
#		define	EXIT_SUCCESS	0
#	endif
# endif


# if		defined(VMS)
# 	include	<stat.h>
# 	include	<file.h>
#	define	fork	vfork
# else
# 	include	<fcntl.h>
# 	include	<sys/types.h>
# 	include	<sys/stat.h>
# endif

# if	defined(EGA43)
#	include	<sys/at_ansi.h>
#	include	<sys/kd.h>
#	undef	DOWN
# 	undef	UP
#	undef	REVERSE
#	undef	CTRL
#	undef	SHIFT
#	undef	ALT
#	undef	NORMAL
# endif

# if defined(O_NONBLOCK) && !defined(O_NDELAY)
#	define	O_NDELAY	O_NONBLOCK
# endif

/**********************************************************************/
/*   Following  definition  is  DIRTY  but  needed.  We want WNOHANG  */
/*   from  <sys/wait.h>  but  we dont actually want to include it on  */
/*   Suns  because  their  include files are so fucked up when using  */
/*   an ANSI C compiler that it hurts.				      */
/**********************************************************************/
# if !defined(WNOHANG)
# 	define  WNOHANG		1
# endif
# if !defined(HAVE_WAITPID)
#	define	waitpid(pid, statusp, options)	wait(statusp)
# endif

# include	<assert.h>
# include	"splay/sptree.h"
# include	"foxlib/chkalloc.h"

# if	defined(SYSV) || defined(VMS) || CR_DOS
#	include	<string.h>
# endif

# if defined(BSD)
#	include	<strings.h>
# endif

/**********************************************************************/
/*   Need  some  types  from  <sys/bsdtypes.h> but its more portable  */
/*   to go for <sys/socket.h>					      */
/**********************************************************************/
# if defined(WANT_SYS_SOCKET_H)
#	include	<sys/socket.h>
# endif

# if	defined(lint) || defined(__STDC__)
# define	SCCSID(x)
# else
# define	SCCSID(x)	static char sccsid[] = x;
# endif

typedef long     RSIZE;			/* Type for file/region sizes   */
typedef short   KEY;			/* Type for internal keystrokes */
typedef	unsigned short 	u_int16;
typedef	unsigned long	u_int32;
# ifndef	U_CHAR
typedef	unsigned char	u_char;
# endif

# if !defined(ROOT)
#	define	ROOT	"/usr/local/lib/crisp"
# endif

/*
 * Universal.
 */
# if !defined(FALSE)
#define FALSE   0		/* False, no, bad, etc.			*/
#define TRUE    1		/* True, yes, good, etc.		*/
# endif
#define ABORT   2		/* Death, ^G, abort, etc.		*/

/**********************************************************************/
/*   Private flags -- mainly used for porting.			      */
/**********************************************************************/
# define	PRI_SELECT	0x01	/* select() not available.	*/

/**********************************************************************/
/*   Following  macros  used  for  speed  up. 'C' version in word.c.  */
/*   Used to access data objects in lists in a portable manner.	      */
/**********************************************************************/
# define	LGET16(lp)	((((LIST *) lp)[1] << 8) | ((LIST *)lp) [2])
/**********************************************************************/
/*   Hilight types (anchors).					      */
/**********************************************************************/
# define	MK_NORMAL	1
# define	MK_COLUMN	2
# define	MK_LINE		3
# define	MK_NONINC	4

/**********************************************************************/
/*   Some miscellaneous definitions.				      */
/**********************************************************************/
# define	HUGE_CURSOR_VAL		2000	/* A rather large number.	*/
# define	NTABS			6	/* Max. number of tab stops.	*/

struct k_tbl {
	short	key;
	char	*name;
	};

/**********************************************************************/
/*   Following  structure  is a character map. This is a map for all  */
/*   256  ASCII  characters  so user can customise the appearance of  */
/*   output  when  looking at a buffer. This scheme is used to allow  */
/*   users  to  see  the  buffer  inside  a  window  in any one of a  */
/*   number  of  ways, e.g. hex, or control-characters, or EDT mode,  */
/*   etc.							      */
/**********************************************************************/
# define	MAX_CMAP_CHARS	256
typedef struct cmap_t {
	int		cmap_id;
	unsigned char	cm_flags[MAX_CMAP_CHARS];/* Zero to print character. */
						 /* 1 to indicate a tab.     */
						 /* 2 to indicate an ESC.    */
	unsigned short	cm_length[MAX_CMAP_CHARS];
	char		*cm_str[MAX_CMAP_CHARS];
	char		*cm_eol;		/* End of line character.   */
	} cmap_t;
extern Head_p	hd_cmap;
extern cmap_t 	*cur_cmap;
extern cmap_t	*default_cmap;
/**********************************************************************/
/*   Flag settings for various characters in the character set.	      */
/**********************************************************************/
# define	CMAP_TAB	1
# define	CMAP_BACKSPACE	2
# define	CMAP_ESCAPE	3
/**********************************************************************/
/*   Structure describing a window on the screen.		      */
/**********************************************************************/
# define	WB_TOP		0x01	/* Top border present.		*/
# define	WB_BOTTOM	0x02	/* Bottom border present.	*/
# define	WB_LEFT		0x04	/* Left border present.		*/
# define	WB_RIGHT	0x08	/* Right border present.	*/
typedef struct  WINDOW {
	struct WINDOW	*w_wndp;	/* Next window.			*/
	struct  BUFFER *w_bufp;		/* Buffer displayed in window   */
	long	w_layer;		/* Relative window layer to allow*/
					/* windows to sit on top of each*/
					/* other.			*/
	int	w_indent;		/* Left hand margin.		*/
	int	w_top_line;		/* Top line in window.		*/
	struct LINE	*w_cache;	/* Pointer to current line.	*/
	int	w_line;			/* Current line no.		*/
	int	w_old_line;		/* Line where cursor used to be.*/
					/* Used after page-up/down to   */
					/* keep cursor on same line.	*/
	int	w_col;			/* Current column number.	*/
	int	w_left;			/* Left hand column.		*/
	int	w_mined;		/* Lowest line modified.	*/
	int	w_maxed;		/* Highest line modified.	*/
	int	w_borders;		/* Bit map telling us which borders */
					/* are present.			*/
	int	w_color;		/* Current background color.	*/
	u_int16	w_x, w_y;
	u_int16	w_h, w_w;
	u_char	w_tiled;
	struct WINDOW	*w_prev;	/* Previous window.		*/
	char    w_force;		/* If NZ, forcing row.		*/
	char    w_flag;			/* Flags.			*/
	u_char	w_corner_hints[4];	/* Hints about how the corners	*/
					/* should intersect.		*/
	char	*w_ttitle;		/* Top title line.		*/
	char	*w_btitle;		/* Bottom line title.		*/
	u_int16	w_num;			/* Window number for inq_window */
	u_int16	w_popup;		/* TRUE if pop-up window.	*/
	cmap_t	*w_cmap;		/* Pointer to a character map for */
					/* viewing buffer in strange ways.*/
	u_int16	w_linked;		/* Id of window we are scroll linked */
					/* to.				*/
	} WINDOW;
# define	W_POPUP	0x01		/* Window is a pop-up.		*/
# define	W_ROOT	0x02		/* Window is part of background.*/

/**********************************************************************/
/*   Definitions  of  the corners of a window for the w_corner_hints  */
/*   array.							      */
/**********************************************************************/
# define	TL_CORNER	0
# define	TR_CORNER	1
# define	BL_CORNER	2
# define	BR_CORNER	3

/**********************************************************************/
/*   Definitions  of  the  corner settings. This is used to indicate  */
/*   how  the  corners  of  a  window intersect so we can change the  */
/*   corner  points  so  we  have  a  solid  line. The syntax of the  */
/*   names correspond to the ahnds on a clock.			      */
/**********************************************************************/
# define	CORNER_12	0x01
# define	CORNER_3	0x02
# define	CORNER_6	0x04
# define	CORNER_9	0x08
/*
 * Window flags are set by command processors to
 * tell the display system what has happened to the buffer
 * mapped by the window. Setting "WFHARD" is always a safe thing
 * to do, but it may do more work than is necessary. Always try
 * to set the simplest action that achieves the required update.
 * Because commands set bits in the "w_flag", update will see
 * all change flags, and do the most general one.
 */
#define WFMOVE  0x02		/* Movement from line to line.  */
#define WFEDIT  0x04		/* Editing within a line.       */
#define WFHARD  0x08		/* Better to a full display.    */
#define	WFDELL	0x10		/* Line been deleted.		*/
#define	WFINSL	0x20		/* Line inserted.		*/


/**********************************************************************/
/*   Text  is  kept  in  buffers.  A buffer header, described below,  */
/*   exists  for  every  buffer  in the system. The buffers are kept  */
/*   in  a  big  list,  so that commands that search for a buffer by  */
/*   name  can  find  the  buffer header. The text for the buffer is  */
/*   kept  in  a  circularly linked list of lines, with a pointer to  */
/*   the header line in "b_linep".				      */
/**********************************************************************/

typedef struct undo_info {
	long	u_chain;		/* Buffer undo chain.		*/
	long	u_last;			/* ftell() position of undo.	*/
	} undo_info;
typedef struct  BUFFER {
	struct BUFFER	*b_bufp;	/* Next buffer in list.		*/
	struct  BUFFER *b_altb;		/* Link to alternate buffer     */
	int	b_line;			/* Current line no.		*/
	int	b_col;			/* Current column number.	*/
	int	b_numlines;		/* Lines in buffer.		*/
	int	b_top;			/* Top line on screen.		*/
	struct  LINE *b_linep;		/* Link to the header LINE      */
	int	b_cline;		/* Cached line number.		*/
	struct LINE	*b_clinep;	/* Pointer to currently cached  */
					/*  line.			*/
	char    b_nwnd;			/* Count of windows on buffer   */
	u_int16 b_flag;			/* Flags			*/
	char    *b_fname;		/* File name			*/
	char	*b_title;		/* Title from create_buffer.	*/
	short	b_bufnum;		/* Buffer number.		*/
	undo_info b_undo;
	undo_info b_redo;
	long	b_nummod;		/* No. of modifications to buffer. */
					/* When zero, buffer has not been*/
					/* modified.			*/
	char	b_uchar;		/* Last character selfinserted  */
					/* to do undo collapsing.	*/
	int	b_mode;			/* Mode for chmod().		*/
	long	b_mtime;		/* Time when buffer modified when */
					/* we read it in.		*/
	u_int16	b_tabs[NTABS+1];	/* Tab columns.			*/
	Head_p	b_alist;		/* Anchor list.			*/
	SPTREE	*b_syms;		/* Local symbols.		*/
	struct ANCHOR 	*b_anchor;	/* Pointer to current anchor.	*/
	struct	DISPLAY	*b_display;	/* Pointer to screen buffer if this*/
					/* buffer is attached to a pty. */
	int	b_wstat;		/* Exit status of child process.*/
	struct keytree_t *b_keyboard;	/* Local keyboard.		*/
	Head_p	b_register;		/* List of registered macros    */
	char	**b_chunk;		/* Original file.		*/
	cmap_t	*b_cmap;		/* Pointer to a character map for */
					/* viewing buffer in strange ways.*/
	} BUFFER;

#define BFCHG		0x01    /* Changed.				*/
#define BFBAK		0x02    /* Need to make a backup.		*/
#define	BFRO		0x04	/* Read-only.				*/
#define	BFREAD		0x08	/* Buffer needs to be read in.		*/
#define	BFEXEC		0x10	/* File is executable.			*/
#define BFPROC		0x20	/* Buffer has process attached. 	*/
#define BFBINARY	0x40	/* Binary buffer.			*/
#define	BFANSI		0x80	/* If TRUE, ANSI-fication is done.	*/
#define	BFTABS		0x100	/* Buffer inserts real-tabs.		*/
#define	BF_SYSBUF	0x200	/* Buffer is a system buffer.		*/
#define	BF_LITERAL	0x400	/* Make all characters visible in window*/
#define	BF_NO_UNDO	0x800	/* Dont keep undo info.			*/
#define	BF_NEW_FILE	0x1000	/* File is a new file so we can write	*/
				/* even if no changes.			*/
#define	BF_CR_MODE	0x2000	/* Append <CR> to end of each line on output */

/**********************************************************************/
/*   Definitions for the edit_file primitive.			      */
/**********************************************************************/
# define	EDIT_NORMAL	0x00	/* Guess file type.		*/
# define	EDIT_BINARY	0x01	/* Force file to be read in binary mode */
# define	EDIT_ASCII	0x02	/* Force file to be read in ascii mode. */
# define	EDIT_CR		0x04	/* Force CR removal on input and write */
					/* them on output.		*/

typedef struct ANCHOR {
	u_int16		a_type;
	int		a_line;
	int		a_offset;
	} ANCHOR;
	
# define	MAX_PT	20
/*----------------------------------------------*/
/*						*/
/*		/-------+------\ 		*/
/*		|       |      |		*/
/*		+-------+------+		*/
/*		|       |      |		*/
/*		\-------+------/		*/
/*----------------------------------------------*/
typedef	struct pt	{
	char	pt_top_left[MAX_PT];	/* Top left corner.	     */
	char	pt_top_right[MAX_PT];	/* Top right corner.	     */
	char	pt_bot_left[MAX_PT];	/* Bottom left corner.	     */
	char	pt_bot_right[MAX_PT];	/* Bottom right corner.	     */
	char	pt_vertical[MAX_PT];	/* Vertical Line.	     */
	char	pt_horizontal[MAX_PT];	/* Horizontal line.	     */
	char	pt_top_join[MAX_PT];	/* Horizontal line, with     */
					/* Vertical join going down  */
	char	pt_bot_join[MAX_PT];	/* Horizontal line, with     */
					/* vertical join going up    */
	char	pt_cross[MAX_PT];	/* Four way intersection.    */
	char	pt_left_join[MAX_PT];	/* Vertical line with join   */
					/* going left.		     */
	char	pt_right_join[MAX_PT];	/* Vertical line with join   */
					/* going right.		     */
	char	pt_space[MAX_PT];	/* Escape sequence to        */
					/* erase multiple spaces.    */
					/* eg ESC [ %d X on Xenix    */
	char	pt_character[MAX_PT];	/* Sequence to print         */
					/* special characters,       */
					/* eg ESC [ %d g on Xenix    */
	char	pt_icursor[MAX_PT];	/* Escape sequence for insert*/
					/* mode cursor.		     */
	char	pt_ocursor[MAX_PT];	/* Escape sequence for overst*/
					/* mode cursor.		     */
	char	pt_vicursor[MAX_PT];	/* Escape sequence for insert*/
					/* mode cursor.	(Virtual)    */
	char	pt_vocursor[MAX_PT];	/* Escape sequence for overst*/
					/* mode cursor.	(Virtual)    */
	char	pt_escape[MAX_PT];	/* Sequence to print ESC.    */
	char	pt_repeat[MAX_PT];	/* Sequence for repeating last*/
					/* character.		     */
	char	pt_0m;			/* ESC [ 0m resets color as well */
					/* as character attributes.   */
	char	pt_color;		/* TRUE if terminal supports */
					/* color.                    */
	char	pt_escC[MAX_PT];	/* Sequence to move cursor   */
					/* on same line.	     */
	char	pt_clr_color_is_black[MAX_PT];
					/* Erasing line (as in ESC[K)  */
					/* clears to a black space) if this */
					/* is TRUE. If FALSE, it erases to */
					/* current background color.  */
	char	pt_noscroll[MAX_PT];	/* Don't scroll screens for optimisation */
					/* because its slower.		*/
	char	pt_graphics[MAX_PT];	/* Sequence to go into graphics mode */
	char	pt_text[MAX_PT];	/* Sequence to go into text mode */
	} PHYS_TERM;
	
# define	CH_MIN		240
# define	CH_HORIZONTAL	CH_MIN+0
# define	CH_VERTICAL	CH_MIN+1
# define	CH_TOP_LEFT	CH_MIN+2
# define	CH_TOP_RIGHT	CH_MIN+3
# define	CH_BOT_LEFT	CH_MIN+4
# define	CH_BOT_RIGHT	CH_MIN+5
# define	CH_TOP_JOIN	CH_MIN+6
# define	CH_BOT_JOIN	CH_MIN+7
# define	CH_LEFT_JOIN	CH_MIN+8
# define	CH_RIGHT_JOIN	CH_MIN+9
# define	CH_CROSS	CH_MIN+10
# define	CH_MAX		CH_MIN+10
/**
 * All text is kept in circularly linked
 * lists of "LINE" structures. These begin at the
 * header line (which is the blank line beyond the
 * end of the buffer). This line is pointed to by
 * the "BUFFER". Each line contains a the number of
 * bytes in the line (the "used" size), the size
 * of the text array, and the text. The end of line
 * is not stored as a byte; it's implied. 
 */
# define	L_INCORE	0x0001	/* Line is in-memory.		*/
# define	L_LOCKED	0x0002	/* Line has been locked.	*/
# define	L_FILE		0x0004	/* Line must be copied before   */
					/* operating on.		*/
typedef struct LINE {
	struct LINE	*l_fp;		/* Link to the next line	*/
	struct  LINE	*l_bp;		/* Link to the previous line    */
	u_int32		l_size;		/* Allocated size		*/
	u_int32		l_used;		/* Used size			*/
	u_int16		l_lineno;	/* Old line number.		*/
	u_int16		l_flags;
	union {
		u_char	*text;
		long	tell;		/* Offset in file when swapped out.*/
		} u;
	} LINE;
# define	l_tell	u.tell
# define	l_text	u.text

/*
 * The rationale behind these macros is that you
 * could (with some editing, like changing the type of a line
 * link from a "LINE *" to a "REFLINE", and fixing the commands
 * like file reading that break the rules) change the actual
 * storage representation of lines to use something fancy on
 * machines with small address spaces.
 */
#define lforw(lp)	((lp)->l_fp)
#define lback(lp)	((lp)->l_bp)
#define lgetc(lp, n)    ((lp)->l_text[(n)])
#define ltext(lp)	((lp)->l_text)
#define	llength(lp)	((lp)->l_used)

# define	SWAP(a,b,c)	c=a,a=b,b=c

/**********************************************************************/
/*   The  following  structure  is  used  to overide escape sequence  */
/*   code  for  functional  code  when  doing things that affect the  */
/*   screen. Mainly provided for the support of OS/2 and X11.	      */
/**********************************************************************/
typedef struct scrfn_t {
	void	(*scr_cursor)();	/* Set insert/overwrite cursor */
	void	(*scr_8bit)();		/* Routine to print 8-bit characters*/
	void	(*scr_repeat)();	/* Function to print multiple chars */
	void	(*scr_window_size)();	/* Hook to get current window size. */
	void	(*scr_show_cursor)();	/* Hook to cause cursor to be displayed. */
	void	(*scr_print_string)();	/* Function to draw string at certain position */
	int	(*scr_select)();	/* Replacement for the select function. */
	int	(*scr_event_pending)();	/* Check for pending X event.		*/
	void	(*scr_beep)();		/* Beep or flash window.		*/
	int	(*scr_read)();		/* Function to replace read() when reading */
					/* from keyboard.			*/
	void	(*scr_flush)();		/* Flush output to window.		*/
	int	(*scr_set_names)();	/* Function to set window and icon name */
	void	(*scr_init)();		/* Realize window			*/
	int	(*scr_font)();		/* Change window font.			*/
	int	(*scr_insert_line)();	/* Insert line.				*/
	int	(*scr_delete_line)();	/* Delete line.				*/
	} scrfn_t;

extern scrfn_t scrfn;
#endif
char	*getenv();
char	*strchr();
char	*strrchr();
char	*strtok();

