[comp.sources.atari.st] v03i005: xxed -- Hex/ASCII file editor part01/03

koreth@panarthea.ebay.sun.com (Steven Grimm) (11/11/89)

Submitted-by: charltn@ccu.umanitoba.ca (Jim Charlton)
Posting-number: Volume 3, Issue 5
Archive-name: xxed/part01

[Documentation is included in the sharfile. -sg]

#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
#	Run the following text with /bin/sh to create:
#	  BUFMAN.C
#	  BUTTON.C
#	  CURSOR.C
#	  EDIT.C
#	  EVENTS.C
#	  FILES.C
#	  FNCTLST.DOC
#	  GLOBALS.H
#	  INIT.C
#	  KEYS.C
#	  MAIN.C
#	  MAKEFILE
#	  MENU.C
#	  ONEPAGE.C
#	  PRINTER.C
#	  SEARCH.C
#	  SEND.C
#	  SLIDER.C
#	  WIND.C
#	  XXED.DEF
#	  XXED.H
#	  XXED.RSC
#	  XXEDRSC.C
#	  XXEDSRC.DOC
#
if test -r s2_seq_.tmp
then echo "Must unpack archives in sequence!"
     next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
     exit 1; fi
sed 's/^X//' << 'SHAR_EOF' > BUFMAN.C &&
X#include "stdio.h"
X#include "gemdefs.h"
X#include "obdefs.h"
X#include "osbind.h"
X#include "globals.h"
X#include "xxed.h"
X/*
XNote:  Each window has its own file buffer.  This file buffer is composed
Xof a linked list of blocks.  addmember() adds a new block to the end of the
Xlist of blocks in the buffer, or puts the first block into the list if
Xthere were no blocks in the list.  The size of the blocks in the buffer
Xis set with the globabl constant BLOCKSIZE.  Using a linked list of blocks
Xfor a buffer simplifies memory management and speeds up inserts and deletes
Xsince only the block containing the data in question need be modified.
Xinsert_member() inserts a block into the linked list and splits the data
Xin the previous block between it and the new block.  This leaves two half
Xfilled blocks for insertions.  dispose_member() deletes a block out of the
Xlist....  happens when all of the data in a block is deleted or cut.
Xdispose_buf() will delete the entire file buffer by deleting all of its
Xblocks
X*/
X
X/* add a member to the linked list at the end  */
X
Xlinkbufptr addmember(thewin)
X	windowptr	thewin;
X{   
X	linkbufptr newmem, amem;
X	int c;	
X
X	/* allocate space for the new member */
X	newmem = (linkbufptr)malloc(sizeof(linkbuf));
X	if(newmem == NULL) return NULL;  /* no more memory available  */
X
X	/* initialize the newmem linkbuf */
X	
X	newmem->next = NULL;
X	bzero(newmem->block,BLOCKSIZE);
X    newmem->inuse = 0;
X	/* insert into the linked list       */
X	
X	if(!thewin->headptr)	/* if thewin->headptr is NULL   */
X	  thewin->headptr = newmem;
X	else
X	{  amem = thewin->headptr;
X	  	   while(amem->next)
X	         amem = amem->next;
X	   amem->next = newmem;
X	}  
X      return(newmem);
X}
X
X/* insert a new linked buffer in the list for any list */
X
Xinsert_member(bufptr)
X	linkbufptr	bufptr;
X{
X	linkbufptr newmem;
X	int totransfer, left, i;	
X
X	/* allocate space for the new member */
X	newmem = (linkbufptr)malloc(sizeof(linkbuf));
X	if ( newmem == NULL)  /* no more memory available  */
X		return(-1);
X	/* initialize the newmem linkbuf and insert into list */
X	
X	newmem->next = bufptr->next;
X	bzero(newmem->block,BLOCKSIZE);
X    newmem->inuse = 0;
X	bufptr->next = newmem;
X
X	/* now split the contents of the block in bufptr between old & new */
X	
X	totransfer = bufptr->inuse - bufptr->inuse/2;
X    left = bufptr->inuse/2;
X/*	strncpy(newmem->block,bufptr->block+left,totransfer);	*/
X	bcopy(bufptr->block+left,newmem->block,totransfer);
X    newmem->inuse = totransfer;
X    bufptr->inuse = left;
X}
X
Xdispose_buf(thewin)
X	windowptr 	thewin;
X{
X	int button;
X	linkbufptr	amem;
X	char str[160];
X
X	if(thewin->changed == TRUE)
X	{	sprintf(str,"[0][ | File %s | has been changed. | Do you want to SAVE | before closing? ][ YES | NO ]", thewin->title);
X		button = form_alert(1, str);
X		if(button == 1)
X			handle_file(SAVE);
X	}      
X
X	 for (amem=thewin->headptr;amem;amem = thewin->headptr)
X	{	dispose_member(thewin,amem);
X    }
X
X}
Xdispose_member(thewin,memtodel)
X	windowptr	thewin;
X	linkbufptr memtodel;
X	
X{	linkbufptr amem;
X	int button;
X
X	if(thewin->headptr)
X	{
X		if (thewin->headptr == memtodel)
X	  		 thewin->headptr = thewin->headptr->next;
X	  	else
X      {	 for (amem = thewin->headptr;(amem->next != memtodel) ;amem=amem->next)
X	 				if (!amem) break;
X	    /* search list 'til find memtodel in amem->next or amem==NULL */
X	    if(amem)
X			   amem->next = amem->next->next;
X	    else
X			{	button = form_alert(1, "[1][ Internal Error: |  member to delete not in list. ][OK]");
X			shutdown(2);
X			}      
X	   }		   	        
X  	   	free((char *)memtodel); /* free up space of deleted member  */
X	}  	   	
X}	        	   	   
X 
SHAR_EOF
chmod 0600 BUFMAN.C || echo "restore of BUFMAN.C fails"
sed 's/^X//' << 'SHAR_EOF' > BUTTON.C &&
X#include "xxed.h"
X#include <gemdefs.h>
X#include <obdefs.h>
X#include <osbind.h>
X
X#include "globals.h"
X
X
Xdo_button(mousex,mousey)
X	int	mousex,mousey;
X{	
X	windowptr	thewin;
X	int	x,y,x2,y2,status,lastw,lasth;
X	long oldpos, newpos;
X
X
X/* WARNING  There are multiple 'returns' in this function  */
X	
X	thewin = thefrontwin;
X	status = 1;
X	lasth=lastw=0;
X	oldpos = thewin->position;
X	while(status==1)
X	{	vq_mouse(thewin->graf.handle,&status,&x,&y);
X		if ((abs(x-mousex))>6 || ((abs(y-mousey))>6))
X			graf_rubberbox(mousex,mousey,6,6,&lastw,&lasth);
X	}
X	if(lastw>7 || lasth>7)
X	{
X
X		newpos = calc_pos(mousex,mousey);
X		if(newpos == -1L) return;
X		if(newpos == -2L)
X		{	thewin->position = thewin->flen-1;
X			return;				
X		}
X		thewin->startmark = newpos;
X		newpos = calc_pos(x-3,y-3);
X		if(newpos == -1) return;
X		thewin->endmark = newpos<thewin->flen-1 ?
X							newpos : thewin->flen-2;
X		thewin->position = thewin->endmark;
X		if(thewin->startmark <= thewin->endmark) /* it must !! */
X		{	send_redraw(thewin);
X			thewin->markson = TRUE;
X			menubar[CUT].ob_state = NORMAL;
X			menubar[COPY].ob_state = NORMAL;
X			menubar[ERASE].ob_state = NORMAL;
X		}
X	}
X	else 
X	{	newpos = calc_pos(mousex,mousey);
X		if(newpos == -1) return;
X		if(newpos == -2L)
X		{	thewin->position = thewin->flen-1;
X			return;				
X		}
X	}
X	thewin->position = newpos;
X}
X			
X
Xlong calc_pos(mousex,mousey)
X	int	mousex,mousey;
X{
X	int x,y,w,h,i;
X	windowptr	thewin;
X	long	pos;
X	int button, xin;
X
X		thewin = thefrontwin;  /* move cursor around in frontwin */
X		x = thewin->work.g_x;
X		y = thewin->work.g_y;
X		w = thewin->work.g_w;
X		h = thewin->work.g_h;
X		mousex -= 5;
X
X		if(mousex > x + w) mousex = x + w - gl_wchar;
X		if(mousex > (x + gl_wchar * 48) && mousex < (x + gl_wchar * 64))
X			{	xin = (mousex - x - gl_wchar*48)/gl_wchar;
X				mousex = x + xoffset[xin]*gl_wchar+1;
X				inhex = FALSE;
X				wr_ins_rpl(ins);
X					/* go to ascii input	*/
X			}
X		else
X			{	inhex = TRUE;
X				wr_ins_rpl(ins);		/* hex input	*/
X			}
X		if(mousex < x) mousex = x + gl_wchar/2;
X		if(mousex > (x + gl_wchar * 48)) mousex = x + gl_wchar * 48;
X		if(mousey < y) mousey = y + gl_wchar/2;
X		if(mousey > y + h) mousey = y + h - gl_wchar/2;
X			{	for (i=0;xoffset[i]*gl_wchar < (mousex-x);i++);
X				pos = 16*((mousey-y)/gl_hchar) + 
X								i + thewin->topchar - 1;
X			}
X
X	if(pos>thewin->flen-1)
X		{
X	return(-2L); /* trying to move cursor outside file !   */				
X		}
X	if(thewin->icount!=0) /* don't allow cursor move til finish entry*/
X		{	
X	Bconout(2,7);
X	button = form_alert(1, "[1][ | | Enter a HEX digit or Backspace ][ OK ]");				
X	return(-1L);				
X		}
X			pos = pos < (thewin->flen-1) ? pos : (thewin->flen-1) ;
X
X			return pos;
X}
X
X
SHAR_EOF
chmod 0600 BUTTON.C || echo "restore of BUTTON.C fails"
sed 's/^X//' << 'SHAR_EOF' > CURSOR.C &&
X#include <osbind.h>
X#include <gemdefs.h>
X#include <obdefs.h>
X
X#include "globals.h"
X
X
Xputcur(thewin,type)
X	windowptr	thewin;
X	int			type;  /* actually, type is never used */
X
X{   int			xpos, ypos; 
X	int diff, num, rect[4];
X	int	x,y,w,h;
X	int	xacur, yacur;
X	long winlines, bottomchar;
X	
X	winlines = thewin->work.g_h/gl_hchar; /* no of lines can put in window  */
X	bottomchar = thewin->topchar + (winlines * 16) - 1;
X
X	if( (thewin->position < thewin->topchar) ||
X					(thewin->position > bottomchar) )
X		return;	/* don't try to draw cursor unless on page  */ 
X
X/* set the clipping rectange in case it was not set    */
X
X	wind_get(thewin->handle, WF_WORKXYWH, &x, &y, &w, &h);
X	rect[0] = x;
X	rect[1] = y;
X	rect[2] = x+w-1;
X	rect[3] = y+h-1;
X	
X	vs_clip(thewin->graf.handle,1,rect);
X
X	if (thewin = thefrontwin)  /*  cursor action for frontwin only */
X  {
X		diff = thewin->position - thewin->topchar;	
X		num = diff % 16;
X		thewin->ycur = (diff/16)*gl_hchar + thewin->work.g_y + 1;
X		thewin->xcur = xoffset[num]*gl_wchar + gl_wchar -1
X											 + thewin->work.g_x;
X		yacur = thewin->ycur;
X		xacur = thewin->work.g_x + 49*gl_wchar + num*gl_wchar; 
X
X	rect[0] = thewin->xcur+1;
X	rect[1] = thewin->ycur;
X	rect[2] = rect[0]+gl_wchar*2-1;
X	rect[3] = rect[1]+gl_hchar-1;
X	
X	vsf_perimeter(thewin->graf.handle,0);
X	vsf_interior(thewin->graf.handle,1);
X	vsf_style(thewin->graf.handle,1);
X	vswr_mode(thewin->graf.handle,3);
X	v_bar(thewin->graf.handle,rect);
X
X	rect[0] = xacur -1;
X	rect[1] = yacur;
X	rect[2] = rect[0] + gl_wchar-1;
X	rect[3] = rect[1] + gl_hchar-1;
X	v_bar(thewin->graf.handle,rect);
X
X	vswr_mode(thewin->graf.handle,1);
X  }
X}    
X
SHAR_EOF
chmod 0600 CURSOR.C || echo "restore of CURSOR.C fails"
sed 's/^X//' << 'SHAR_EOF' > EDIT.C &&
X#include <gemdefs.h>
X#include <obdefs.h>
X#include <osbind.h>
X#include <stdio.h>
X#include "xxed.h"  
X
X#include "globals.h"
X
X
Xdelete_one(thewin,pos,flag) /* delete one byte */
X	windowptr	thewin;
X	long		pos;
X	int	flag;
X{
X		linkbufptr amem;
X		char *addr, *addr2;
X		int	button;
X
X/*	flag is 0 when saving the file in which case can delete last byte */
X	if( (thewin->position==thewin->flen-1) && flag) /* last byte */
X	{	button = form_alert(1, "[1][ The last byte in the file is | a dummy byte and cannot be | changed or deleted. It is | not saved with the file. ][ OK ]");				
X		return;
X	}			 
X
X		amem = thewin->headptr;
X		while (amem->inuse<=pos)
X			{	pos = pos - amem->inuse;
X				amem = amem->next;
X			}
X		addr = (char *)(amem->block+pos);
X	for (addr2=addr;addr2<(char *)amem->block+amem->inuse;addr2++)
X		*addr2 = *(addr2+1);  
X
X		amem->inuse--;
X		thewin->flen--; 
X	if(thewin->position>=thewin->flen) 
X		thewin->position= thewin->flen-1; 
X	if(flag)	/* don't set to partial if deleting last byte in file	*/
X		thewin->changed = TRUE;
X}
X
Xcutit(thewin) /* cut out the marked text   */
X	windowptr	thewin;
X{
X	char		*addr;
X	linkbufptr	amem;
X	long		pos, togo;
X	int			inthis, dummy;
X
X	pos = thewin->startmark;
X	    if (pos<=thewin->flen)
X	{	amem = thewin->headptr;
X		while (amem->inuse <= pos)
X			{	pos = pos - amem->inuse;
X				amem = amem->next;
X			}
X		inthis = amem->inuse - pos;
X	}
X	togo = thewin->endmark - thewin->startmark + 1;
X	if(togo > 0)
X	{	while (inthis < togo)
X		{	amem->inuse = pos;
X			if(amem->inuse==0)
X				dispose_member(thewin,amem);
X			amem = amem->next;
X			togo -= inthis;
X			thewin->flen -= inthis;
X			inthis = amem->inuse;
X			pos = 0;
X		}
X		if(togo > 0)
X		{	bcopy(amem->block+pos+togo,amem->block+pos,
X								(int)(amem->inuse-togo-pos));
X			amem->inuse -= togo;
X			thewin->flen -= togo;
X		}
X	}
X	thewin->position = thewin->startmark;
X	if(thewin->topchar >= thewin->position) 
X		thewin->topchar = thewin->position&~0x7;   
X}
X
X
Xcopy(thewin) /* copy the marked text to the cutbuffer */
X	windowptr	thewin;
X{
X	linkbufptr	amem;
X	long		pos;
X	long		tocopy;
X	int			bufbytes, num, button;
X	char		*addr, *addr2;
X
X	pos = thewin->startmark;
X
X	    if (pos<=thewin->flen)
X	{	amem = thewin->headptr;
X		while (amem->inuse <= pos)
X			{	pos = pos - amem->inuse;
X				amem = amem->next;
X			}
X		addr = (char *)(amem->block+pos);
X	}
X	
X
X	if(cutbuffer) free(cutbuffer);
X	cutlength = thewin->endmark - thewin->startmark +1;
X	tocopy = cutlength;
X	if (cutlength<=0) return; /* bail out if end is before start */
X	cutbuffer = malloc((unsigned)(tocopy+2));
X
X	if (cutbuffer == NULL)
X	{	button = form_alert(1, "[1][ Sorry! | Out of memory creating cut buffer. ][OK]");
X		return;
X	}
X
X	bufbytes = amem->inuse - pos;
X	addr2 = cutbuffer;
X
X	while(tocopy > 0)
X		{	num = (tocopy < bufbytes) ? tocopy : bufbytes;
X			bcopy(addr,addr2,num);
X			tocopy -= bufbytes;
X		if(tocopy > 0)
X			{	amem = amem->next;
X				addr = amem->block;
X				bufbytes = amem->inuse;
X				addr2 += num;
X			}	
X		}
X	*(cutbuffer + cutlength ) = 0;
X}		
X
Xpaste(thewin) /* paste the cutbuffer into the file before the cursor */
X	windowptr	thewin;
X{
X	insert_it(thewin,cutlength,cutbuffer);
X	send_vslid(thewin);
X	send_redraw(thewin);
X}
X
X/* insert_it() inserts incopy bytes from string pointed to by addr2
X   into the file before the position of the cursor
X*/
X
Xinsert_it(thewin,incopy,addr2)
X	windowptr	thewin;
X	long	incopy;
X	char	*addr2;
X{
X	long		pos, insertpos, tocopy;
X	linkbufptr	amem;
X	char		*posaddr,*addr,*addr3,*addr4;
X	int			havenow, num, tomoveup, button, ret;
X
X	insertpos = thewin->position;
X	tocopy = incopy;
X	while(tocopy>0)
X	{
X		/* calculate amem that cursor is in */
X		pos = insertpos;
X			{	amem = thewin->headptr;
X				while (amem->inuse < pos)
X				{	pos = pos - amem->inuse;
X					amem = amem->next;
X				}
X			posaddr = (char *)(amem->block+pos);
X			}
X		if (amem->inuse == BLOCKSIZE)
X		{
X			ret = insert_member(amem);	/* free up some space for the insert */
X		if (ret == -1)  /* no more memory available  */
X	{   	button = form_alert(1, "[1][ Out of memory. | Partial insert. ][OK]");
X	 		break;
X	}	/* recalculate pos and amem */
X			pos = insertpos;
X			{	amem = thewin->headptr;
X				while (amem->inuse <= pos)
X				{	pos = pos - amem->inuse;
X					amem = amem->next;
X				}
X			posaddr = (char *)(amem->block+pos);
X			}
X		}
X	/* pos is now position of cursor in number of bytes from amem->block */
X
X		addr = posaddr;
X		havenow = BLOCKSIZE - amem->inuse;
X		num = (tocopy < havenow) ? tocopy : havenow;
X		for(tomoveup = amem->inuse - pos-1;tomoveup>-2;tomoveup--) 
X			*(addr+tomoveup+num) = *(addr+tomoveup);
X		bcopy(addr2,addr,num);
X		amem->inuse += num;
X		addr2 += num;
X		insertpos += num;	
X		tocopy -= num;
X	}
X	thewin->flen += incopy;
X}
X
SHAR_EOF
chmod 0600 EDIT.C || echo "restore of EDIT.C fails"
sed 's/^X//' << 'SHAR_EOF' > EVENTS.C &&
X#include <gemdefs.h>
X#include <obdefs.h>
X#include <osbind.h>
X
X#include "globals.h"
X
X/*
X	Handle Application Events.
X*/
X
XTaskMaster()
X{
X	int event;			/* The event code.					*/
X	int button = TRUE;	/* desired Button state				*/
X	int	message[8];		/* Event message buffer.			*/
X	int	mousex, mousey;	/* The current mouse position.		*/
X	int mousebutton;	/* The state of the mouse button    */
X
X	int keycode;		/*  The code for the key pressed.	*/
X	int keymods;		/*  The state of the keyboard modifiers.
X							(shift, ctrl, etc). */
X	int clicks;			/*	The number of mouse clicks that occurred in the 
X							given time. */
X	windowptr	thewin;
X	int	c;
X
X			sprintf(fsize_str," File size:%ld",0L);
X			sprintf(pos_str," Position:%ld",0L);
X	do {
X		if(thewin = thefrontwin)
X		{	graf_mouse(M_OFF, 0L);
X			putcur(thewin);	/* cursor on	*/
X			graf_mouse(M_ON, 0L);
X		}
X		wr_ins_rpl(ins);
X
X		event = evnt_multi(
X			MU_MESAG | MU_BUTTON | MU_KEYBD,   /* set messages to respond to. */
X                      /* MU_MESAG    is a message event    */
X			1,				/* Time frame for events.					*/
X			1,				/* Keyboard Event mask.						*/
X			button,			/* desired key state						*/
X			0, 0, 0, 0, 0,	/* rectangle one information (ignored)		*/
X			0, 0, 0, 0, 0,	/* rectangle two information (ignored)		*/
X			message,		/* The message buffer 						*/
X			0, 0,			/* Number of Ticks for Timer event. 		*/
X			&mousex,		/* The x-coordinate of the mouse at event.  */
X			&mousey,		/* The y-coordinate of the mouse at event.  */
X			&mousebutton,	/* The state of the mouse buttons at event. */
X			&keymods,		/* The state of the keyboard modifiers.     */
X			&keycode,		/* The key code for the key pressed.        */
X			&clicks			/* The number of times the event occurred	*/
X		);
X		
X		if(thewin = thefrontwin)
X		{	graf_mouse(M_OFF, 0L);
X			putcur(thewin);	/* cursor off	*/
X			graf_mouse(M_ON, 0L);
X		}
X
X
X		if (event & MU_KEYBD)
X				{
X					if (thewin = thefrontwin)
X/*  if repos is true.  eg. cursor is off the page, redraw page */
X						if (repos(thewin))
X						{	partial = FALSE;
X							one_page(thewin,1);
X							redraw_vslider(thewin->handle);
X						}
X					draw_flag = FALSE;
X					arro_flag = FALSE;
X					slid_flag = FALSE;
X					do_kbd(keycode, keymods);
X				}	
X		else if (event & MU_MESAG) {
X			switch (message[0]) {
X				/*
X					Window Support
X				*/
X				case WM_REDRAW:
X				case WM_TOPPED:
X				case WM_FULLED:
X				case WM_ARROWED:
X				case WM_HSLID:
X				case WM_VSLID:
X				case WM_SIZED:
X				case WM_MOVED:
X				case WM_NEWTOP:
X				case WM_CLOSED:
X					do_window(message);
X					break;
X
X				/*
X					Menu Support
X				*/
X				case MN_SELECTED:
X					do_menu(message);
X					button ^= TRUE;	
X				break;
X
X				/*
X					Desk Accessory Support
X				*/
X				case AC_OPEN:
X				case AC_CLOSE:
X				break;
X			}
X		}
X
X		else if (event & MU_BUTTON)
X		{
X				if(button)
X					do_button(mousex, mousey);
X				button ^= TRUE;
X		}
X		if(thewin = thefrontwin)
X		{	sprintf(fsize_str," File size:%ld",thewin->flen-1);
X			sprintf(pos_str," Position:%ld",thewin->position);
X		}
X
X	}
X 	while(1);
X}
SHAR_EOF
chmod 0600 EVENTS.C || echo "restore of EVENTS.C fails"
sed 's/^X//' << 'SHAR_EOF' > FILES.C &&
X
X#include "gemdefs.h"
X#include "obdefs.h"
X#include "osbind.h"
X#include "fcntl.h"
X#include "xxed.h"
X#include "globals.h"
X
X	int				drarray[16] = {AA,BB,CC,DD,EE,FF,GG,HH,II,JJ,
X										KK,LL,MM,NN,OO,PP};
X/*  The drive letters are defined in HEXED.H    */
X
Xread_file(thewin)
X	windowptr	thewin;
X
X{	int fildes, c, button, ret;
X	long skres, flenr, toread, readnow, red;
X	linkbufptr	bufptr;
X	char str2[30];
X
X		graf_mouse(2,0L);
X		  ret = 1;	
X          fildes = open(thewin->title,O_BINARY);
X          skres = lseek(fildes,0L,0);       /* rewind */
X          flenr = Fseek(0L,fildes,2);        /* get file length */
X          	 if (flenr >= 1 && fildes != -1 && skres != -1)
X           	{  	skres = lseek(fildes,0L,0);       /* rewind again */
X			for(toread=flenr;toread>0;toread=toread-BLOCKSIZE)
X				{	readnow = (toread < BLOCKSIZE) ? toread : BLOCKSIZE;
X					bufptr = addmember(thewin); 
X		if (bufptr == NULL)  /* no more memory available  */
X	{   	button = form_alert(1, "[1][ Out of memory. | Partial file read. ][OK]");
X	 		ret = 0; break;
X	}
X						/* read file to ram */
X               	if( (red = Fread(fildes,readnow,bufptr->block)) > 0 )
X					{
X						bufptr->inuse = red;
X						thewin->flen += red;
X					}	  
X				else
X					{	button = form_alert(1, "[1][ File read error ][OK]");
X						ret = 0; break;
X					}	
X			     }
X			c = close(fildes);
X           	}
X           	 else	{button = form_alert(1, "[1][ File read error | or file not found ][OK]");
X						ret = 0;
X					}
X
X				/* put extra char 00 at end of file  */
X		if(thewin->flen > 0)
X		{	if(bufptr->inuse < BLOCKSIZE)
X			{	bufptr->inuse += 1;
X				thewin->flen += 1;
X			}
X			else
X			{	bufptr = addmember(thewin); 
X			if (bufptr == NULL)  /* no more memory available  */
X				{   	button = form_alert(1, "[1][ Out of memory. | Partial file read. ][OK]");
X		 				ret = 0;
X				}
X			else				
X				{	bufptr->inuse += 1;
X					thewin->flen += 1;
X				}
X			}	
X		}
X		graf_mouse(0,0L);
X          return(ret);
X}
X
X
Xwrite_file(thewin)
X  windowptr thewin;
X{
X		int button,w;
X		
X		drw_dialxy(dialog5,230,38/(16/gl_hchar));  /* may not work on colour   */
X		if (getfile(thewin))
X			 save_file(thewin);
X		form_dial(FMD_FINISH, 0, 0, 0, 0, 230, 38/(16/gl_hchar),
X							 dialog5->ob_width, dialog5->ob_height);
X
X} 
X
Xsave_file(thewin)
X	windowptr	thewin;
X{
X	int fildes, c, button;
X	long flenw;   /* length of buffer written to file */
X	linkbufptr	amem;
X	unsigned dummy;
X
X
X		if (thewin->flen < 2) 
X			 {button = form_alert(1, "[1][ Null file........ | Save aborted. ][OK]");
X						 return;
X			}
X       
X		graf_mouse(2,0L);
X/* delete the dummy byte at end of file if it is still a 0x00 */
X
X		if((dummy = getbyte(thewin,thewin->flen-1))==0)
X/*	the 0 flag in the delete_one call allows for delete last byte	*/
X			delete_one(thewin,thewin->flen-1,0);
X
X				fildes = open(thewin->title,O_RDONLY);
X			if (fildes > 0)
X			{	button =  form_alert(1, "[1][ File already exists. | Ok to overwrite? ][OK|CANCEL]");
X				if (button == 2)
X					{	c = close(fildes);
X						return;
X					}
X				else
X					c = close(fildes);
X			}
X      			Fdelete(thewin->title);
X				fildes = creat(thewin->title,O_RDWR);
X			if(fildes != -1)	
X			{	for(amem=thewin->headptr;amem;amem=amem->next)
X         		{  if(flenw = Fwrite(fildes,amem->inuse,amem->block))
X         				;
X         		   else {button = form_alert(1, "[1][ File write error ][OK]");
X						 break;
X						}
X         		}	c = close(fildes);
X					thewin->changed = FALSE;
X			}
X			else
X			button = form_alert(1, "[1][ Error creating file | Try 'SAVE AS' ][OK]");
X		graf_mouse(0,0L);
X}
X
Xgetfile(thewin)  /* returns 1 with name in thewin->title, 0 with cancel */
X 	windowptr thewin;
X
X{		int  fs_button, c, i, len;
X
X        c = fsel_input(fs_inpath,fs_insel,&fs_button);
X		if(( c!=0 ) && (fs_button != 0))
X		{
X			len = strlen(fs_inpath);
X			for(i=len;i>0;i--)  /* find last occurrence of \  */
X				if(fs_inpath[i]=='\\') break;
X
X			strncpy(thewin->title,fs_inpath,i+1); /* copy pathname to title */
X    		thewin->title[i+1] = '\0';
X    		strcat(thewin->title,fs_insel);
X			wind_set(thewin->handle, WF_NAME, thewin -> title, 0, 0);
X			return(1);
X		}
X    	else	return(0);
X}
X
Xdelfile()  /* returns 1 with del, 0 with cancel */
X
X     {  int  fs_button, c, i, len;
X        char filespec[40];
X
X		drw_dialxy(dialog6,230,38/(16/gl_hchar));  /* may not work on colour   */
X									/* see form_dial at end of func */
X		c = fsel_input(fs_inpath,fs_insel,&fs_button);
X		form_dial(FMD_FINISH, 0, 0, 0, 0, 230, 38/(16/gl_hchar),
X							 dialog6->ob_width, dialog6->ob_height);
X		if(( c!=0 ) && (fs_button != 0))
X		{
X			len = strlen(fs_inpath);
X			for(i=len;i>0;i--)  /* find last occurrence of \  */
X				if(fs_inpath[i]=='\\') break;
X
X			strncpy(filespec,fs_inpath,i+1); /* copy pathname to filespec*/
X    		filespec[i+1] = '\0';
X    		strcat(filespec,fs_insel);
X			c = Fdelete(filespec);
X            if(c>=0)
X				return(1);
X			else
X				form_error(c);
X		}
X    	else	return(0);
X}
X
Xdrives()
X{
X	unsigned long	drvs;
X	int				dr, cx, cy, cw, ch, button, idr;
X	int				dx, dy, dw, dh;
X	disk_info		myinfo;
X
X	dr_str[0] = 0;
X	for (dr = 1; dr < 17; dr++)
X			dialog4[drarray[dr]].ob_state = DISABLED;
X		
X	idr = 0;
X	drvs = Drvmap();
X	for (dr = 1; dr < 17; dr++, drvs >>= 1)
X		if(drvs & 0x001)
X			dialog4[drarray[dr-1]].ob_state = NORMAL;
X
X		form_center(dialog4, &cx, &cy, &cw, &ch);
X		form_dial(FMD_START, 0, 0, 0, 0, cx, cy, cw, ch);
X		objc_draw(dialog4, 0, 10, cx, cy, cw, ch);
X	while((button = form_do(dialog4, 0)) != DREXIT)
X	{	for(dr = 1;dr<18;dr++)
X			if(drarray[dr-1] == button)
X				idr = dr;
X		Dfree(&myinfo,idr);
X		sprintf(dr_str,"%ld Free bytes in disk %c",
X				myinfo.b_free*myinfo.b_clsiz*myinfo.b_secsiz,
X				'A' + (idr-1));
X		dialog4[button].ob_state = NORMAL;
X		objc_draw(dialog4, button, 10, cx, cy, cw, ch);
X		objc_draw(dialog4, DRBOX, 1, cx, cy, cw, ch);
X	}
X		form_dial(FMD_FINISH, 0, 0, 0, 0, cx, cy, cw, ch);
X		dialog4[DREXIT].ob_state = NORMAL;
X
X}
X				
SHAR_EOF
chmod 0600 FILES.C || echo "restore of FILES.C fails"
sed 's/^X//' << 'SHAR_EOF' > FNCTLST.DOC &&
XMAIN.C
X	main() - executes initialization code and the starts the program.
X	set_table()	   makes a table of ASCII hex bytes for 0 to 255    
XINIT.C
X	init_resources() -     loads resource array   
X	init_menu() -          sets up menu bar    
X	init_dialog() -        sets up dialog boxes    
X	init_path() -	       sets up fs_inpath for fsel_input in files.c
X	shutdown(code)
X	cleanup() - 		   cleans up memory on shutdown   
X	int open_vwork(form) - open virtual work area for each window   
XEVENTS.C
X	TaskMaster() -         handles event_multi call
XWIND.C
X	do_window(message) -   handles all window messages
X	do_resize(message)
X	do_fullsize(handle)
X	do_update(message)
X	update_window(windhandle)
X	setclip(thewindow, r1)
X	windowptr findwindowptr(handle)
X	windowptr new_window(thekind)
X	open_window(thewin)
X	dispose_window(thewin)
X	dispose_win_resources(thewin)
X	make_frontwin(thewin)
X	rot_wind()
X	wind_blank(thewin)
XMENU.C
X	do_menu(message) - 	handles menu messages
X	handle_desk(itemid)
X	handle_file(itemid)
X	new()  /* opens a new window with associated file  */
X	handle_marks(itemid)
X	start_mark(thewin)
X	end_mark(thewin)
X	clear_marks(thewin)
X	handle_edit(itemid)
X	handle_search(itemid)
XFILES.C
X	read_file(thewin) - 	read file into ram buffer
X	write_file(thewin) - 	write to a named file
X	save_file(thewin) -		write to current file thewin->title
X	getfile(thewin) - ret 1 name in thewin->title or 0 with cancel
X	delfile() - returns 1 with del, 0 with cancel 
X	drives() -  display disk space on selected drive
XONEPAGE.C
X	one_page(thewin, blank) - draw one window full of data 
X	unsigned getbyte(thewin,pos) - get any byte in file in ram
X	putbyte(thewin,pos,lnum) - put byte lnum into file at pos 
X	one_line0(thewin,pos) - draw a single line of data in window
X	one_line2(thewin,pos)	/* handles mixed marked and unmarked */
X	one_line1(thewin,pos)	/* handles unmarked text	*/
XBUFFMAN.C
X	linkbufptr addmember(thewin) - add new block to linked list
X	insert_member(bufptr) -  insert a new block into a lined list
X	dispose_buf(thewin) - delete an entire file buffer, all blocks in list
X	dispose_member(thewin,memtodel) - delete one block from linked list
XSLIDER.C
X	vhandler(message)
X	redraw_vslider(wihandle)    /* redraws vslider in new postion  */
X	size_vslider(wihandle)  /* set slider size  and redraws it */
X	scroll(thewin,upflag,dnflag) - scroll text in window
XCURSOR.C
X	putcur(thewin,type) - draws and undraws the cursor
XKEYS.C
X	do_kbd(keycode,keymods) - handles all keyboard input
X	do_kbd2(thewin,keycode,keymods) - handles hexadecimal input
X	cur_up(thewin)
X	cur_down(thewin)
X	cur_right(thewin)
X	cur_left(thewin)
X	check_scroll(thewin) - cursor off screen?  scroll or reposition
X	repos(thewin)  /* reposition and redraw with cursor on screen */
X	jump_pos(thewin) /* reset display parameters so cursor on screen */
X	ins_rpl(thewin)  /* enters hex charactes into the file */
X	enter_it(thewin,inbuf,lnum)- insert or replace byte redrawing screen
X	hex_chk(thewin, ch) /* checks to see if a hex character was entered */
X	wr_ins_rpl(insflag) /* writes insert/replace/hex/ascii on menu line */
X	cursor(x,y)   /* position the cursor*/
XBUTTON.C
X	do_button(mousex,mousey) - handles all mouse stuff including drag box
X	long calc_pos(mousex,mousey) claculates new position in file
XEDIT.C
X	delete_one(thewin,pos,flag) /* delete one byte */
X	cutit(thewin) /* cut out the marked text   */
X	copy(thewin) /* copy the marked text to the cutbuffer */
X	paste(thewin) /* paste the cutbuffer into the file before the cursor */
X	insert_it(thewin,incopy,addr2)
X		inserts incopy bytes from string pointed to by addr2
X		into the file before the position of the cursor
XSEARCH.C
X	find(thewin) /* handles search and replace dialog box  */
X	char *chk_sstr_len(thewin) /* check search string length */
X	char *chk_rstr_len(thewin) /* check replace string length */
X	find0(thewin) /* handles results from srch/rpl dialog */
X	forward1(thewin,sstr) /* searches forward */
X	long forward2(thewin,sstr)
X	rp_forw(thewin,sstr) /* replace going forward */
X	back1(thewin,sstr) /* search backwards */
X	long back2(thewin,sstr)
X	ronce(thewin,sstr,rstr) /* replace once */
X	rall(thewin,sstr,rstr) /* replace all */
X	rver(thewin,sstr,rstr) /* replace with verify */
X	do_dialog(dialog)   /* draw dialog boxes centered with form_do  */
X	do_dialxy(dialog,x,y) /* draw dialog at specific position with form_do */
X	drw_dialxy(dialog,x,y) /* draw object at a position.. no form_do */
XSEND.C
X	send_vslid(thewin) /* send application slider message */
X	send_redraw(thewin) /* send application a redraw message */
X	immed_redraw(thewin) /* bypass event multi and do a screen redraw */
X	send_arrow(thewin,direction) /* send application an arrow message */
XPRINTER.C
X	print(thewin) /* send file or block to printer */
X	print_line(thewin,pos) /* send a line to the printer */
X	pr_print(str) /* send a string to the printer */
X
X
X
X
X
X
X
SHAR_EOF
chmod 0600 FNCTLST.DOC || echo "restore of FNCTLST.DOC fails"
sed 's/^X//' << 'SHAR_EOF' > GLOBALS.H &&
X
X#ifndef TRUE
X#define TRUE		1
X#define FALSE		0
X#define NULL		0L
X#endif 
X
X#define WORKSIZE	1
X#define BORDSIZE	0
X
X#define	min(a, b)	((a < b)? a : b)
X#define max(a, b)	((a > b)? a : b)
X
X/*
X	Each window will have a grafport so that it is easy to maintain 
X	drawing environments accross windows.
X*/
Xtypedef struct _grafport {
X	int		handle;		/*  Virtual workstation handle  					*/
X	MFDB	mfdb;		/*  memory definition block for virtual workstation	*/
X} grafport;
X
X
X/*
X	Window definition.
X*/
Xtypedef struct _windowrec {
X	struct _windowrec	*next;		/*  Window link						*/
X	int					handle;		/* Window Handle					*/
X	int					kind;		/* The windows type					*/
X	int					fullsize;	/* In full-screen mode				*/
X	int					vslidepos;	/* vertical slider position			*/
X	char				title[30];	/* Title of window					*/
X	GRECT				box;		/* Window Box dimensions			*/
X	GRECT				work;		/* Window content region dimensions	*/
X	grafport			graf;		/* Window graphics port definition  */
X	int					(*updateproc)(); /* Pointer to update procedure */
X/************************************************************************/
X/* the following are specific to the program HEXED                      */
X
X	struct _linkbuf		*headptr;
X	long				startmark;
X	long				endmark;
X	int					markson;
X	int 				xcur;		/* xpos of cursor on screen			*/
X	int					ycur;       /* ypos of cursor on screen			*/
X	long				topchar;	/* number of char at top left 		*/
X	long				flen;		/* length of file in total			*/
X	long				position;	/* position of cursor in file		*/
X	char				input[2];	/* input buffer						*/
X	int					icount;		/* input buffer end pointer			*/
X	int					changed;
X/************************************************************************/		
X} windowrec;
Xtypedef windowrec *windowptr;
X
X
X/*
X	Declare the GEM specific variables required by the ROM routines.
X*/
X
Xextern int contrl[12];
Xextern int intin[256],  ptsin[256];
Xextern int intout[256], ptsout[256];
Xextern gl_apid;
X
X
X/*
X	Application Global Variables.
X*/
Xextern OBJECT		*menubar;
Xextern OBJECT		*dialog2;
Xextern OBJECT		*dialog1;
Xextern OBJECT		*dialog3;
Xextern OBJECT		*dialog4;
Xextern OBJECT		*dialog5;
Xextern OBJECT		*dialog6;
Xextern int			phys_handle;
Xextern char			table[600];
Xextern int			gl_hchar;
Xextern int			gl_wchar;
X
X#ifdef extern
Xwindowptr	firstwindow = NULL;       /* in MAIN.C these lines used  */
Xwindowptr	thefrontwin = NULL;
X#else
Xextern windowptr	firstwindow;
Xextern windowptr	thefrontwin;
X#endif
X
X/*
X	Functions
X*/
Xextern char 		*malloc();
Xextern windowptr	new_window();
Xextern windowptr	frontwindow();
Xextern windowptr	findwindowptr();
X
X/* globals for HEXED      */
X
X#define BLOCKSIZE 4096
Xtypedef struct  _linkbuf {
X	struct  _linkbuf	*next;
X	char			 	block[BLOCKSIZE];
X	long				inuse;
X} linkbuf;
Xtypedef linkbuf *linkbufptr; 
X
Xextern linkbufptr addmember();
Xextern linkbufptr add_cutmem();
Xextern int read_file();
Xextern long calc_pos();
X
X#ifdef extern
X	char	fsize_str[32]={" File size:"};
X	char	pos_str[32]={" Position:"};
X	char	s_str[32];
X	char	r_str[32];
X	char	dr_str[32]={""};
X	int	xoffset[33]={0,2,6,8,12,14,18,20,24,26,30,32,36,38,42,44,
X					 48,50,54,56,60,62,66,68,72,74,78,80,84,86,90,92,96};
X	char	lastpath[64];
X	char	fs_insel[40];
X	char	fs_inpath[40];
X	char	*cutbuffer = NULL;
X	long	cutlength = 0L;
X	int		ins	= FALSE;
X	int		inhex = TRUE;
X	int		partial = FALSE;
X	int		draw_flag = FALSE;
X	int		slid_flag = FALSE;
X	int		arro_flag = FALSE;
X#else
Xextern		char	fsize_str[];
Xextern		char	pos_str[];
Xextern		char	s_str[];
Xextern		char	r_str[];
Xextern		char	dr_str[];
Xextern		int		ins;
Xextern		int		inhex;
Xextern		int		partial;
Xextern		int		draw_flag;
Xextern		int		slid_flag;
Xextern		int		arro_flag;
Xextern		char	*cutbuffer;
Xextern		long	cutlength;		/* markbuf end pointer			*/
Xextern 		int 	xoffset[];
Xextern 		char 	lastpath[];
Xextern		char	fs_insel[];
Xextern		char	fs_inpath[];
X#endif
SHAR_EOF
chmod 0600 GLOBALS.H || echo "restore of GLOBALS.H fails"
sed 's/^X//' << 'SHAR_EOF' > INIT.C &&
X
X#include <osbind.h>
X#include <gemdefs.h>
X#include <obdefs.h>
X
X#include "xxed.h"	/* header file created by RCP     */
X#include "globals.h"  	/* contains definition of menubar */
X
X
Xinit_resources()  /* loads resource array */
X{
X/*	if (!rsrc_load("xxed.rsc")) {
X		form_alert(1, "[0][Cannot find xxed.rsc file|Terminating ...][OK]");
X		exit(2);
X	}
X*/
X		mrsrc_load(XXEDRSC);  /* using .C RSC */
X
X}
X
Xinit_menu()  /* sets up menu bar  */
X{
X	rsrc_gaddr(0, MENUBAR, &menubar);
X	menubar[FSIZE].ob_spec = fsize_str;
X	menubar[POS].ob_spec = pos_str;
X	menu_bar(menubar, 1);
X}
X
Xinit_dialog()  /* sets up dialog boxes  */
X{
X    rsrc_gaddr(0, DIALOG2, &dialog2);
X    rsrc_gaddr(0, DIALOG1, &dialog1);
X    rsrc_gaddr(0, DIALOG3, &dialog3);
X    rsrc_gaddr(0, DIALOG4, &dialog4);
X    rsrc_gaddr(0, DIALOG5, &dialog5);
X    rsrc_gaddr(0, DIALOG6, &dialog6);
X
X	((TEDINFO *)dialog1[SSTRING].ob_spec)->te_ptext = s_str;
X	((TEDINFO *)dialog1[SSTRING].ob_spec)->te_txtlen = 24;
X	((TEDINFO *)dialog1[RSTRING].ob_spec)->te_ptext = r_str;
X	((TEDINFO *)dialog1[RSTRING].ob_spec)->te_txtlen = 24;
X	dialog4[DRSTR1].ob_spec = dr_str;
X	dialog1[SSTRBUT].ob_state = SELECTED;
X	dialog1[RSTRBUT].ob_state = SELECTED;
X
X}
X
Xinit_path()	/* initialize fs_inpath with current path */
X{
X	int drv;
X
X	drv = Dgetdrv();
X	Dgetpath(lastpath,0);
X	sprintf(fs_inpath,"%c:%s\\*.*",'A' + drv,lastpath);
X	strcpy(fs_insel,"untitled");
X}
X
X/*
X	shutdown - is the code that closes down the application.  This routine
X		is called when errors occurs and guarantees that all window's will
X		be closed properly before exiting.
X*/
Xshutdown(code)
X	int code;
X{
X	/*
X		Clean up memory.
X	*/
X	cleanup();
X
X	/*
X		Clean up the io buffer because of bug in TOS ?
X	*/
X
X	while(Cconis()) Crawcin();
X
X	/*
X		Shut down the application.
X	*/
X	appl_exit();
X
X	/*
X		bye ...
X	*/
X	exit(code);
X}
X
X
X/*
X	cleanup - releases the memory used by the application.
X*/
Xcleanup()
X{
X	windowptr	thewin;
X
X	/*
X		Close down the windows.
X	*/
X	for (thewin = firstwindow; thewin; thewin = thewin -> next)
X	{	dispose_buf(thewin);
X		dispose_window(thewin);
X	}
X
X	/*
X		free cutbuffer space
X	*/
X
X	if(cutbuffer) free(cutbuffer);
X
X
X	/*
X		Free memory used by resource.
X	
X	rsrc_free();  not needed now as using .C RSC
X
X	*/
X}
X
X
X/*
X	open_vwork - Open a virtual workstation.
X
X	Note: a virtual workstation is associated with each window created.
X		This means that each window's graphic attributes are independent
X		of the other's.
X*/
Xint open_vwork(form)
X	register MFDB	*form;
X{
X	register int x;
X	int 	 work_in[11];
X	int		 handle, d;
X	int		 work_out[57];
X
X	/*
X		Initialize workstation variables.
X	*/
X	for(x=0; x<10; x++)
X		work_in[x] = 1;
X
X	work_in[10] = 2;
X
X	handle = graf_handle(&d, &d, &d, &d);
X	v_opnvwk(work_in, &handle, work_out);
X
X	form -> fd_addr 	= Logbase();
X	form -> fd_w		= work_out[0] + 1;
X	form -> fd_h		= work_out[1] + 1;
X	form -> fd_wdwidth	= form -> fd_w / 16;
X	form -> fd_stand	= 0;
X
X	switch(work_out[13]) {
X		case 16: form -> fd_nplanes = 4; break;
X		case 08: form -> fd_nplanes = 3; break;
X		case 04: form -> fd_nplanes = 2; break;
X		default: form -> fd_nplanes = 1; break;
X	}
X
X	return handle;
X}
SHAR_EOF
chmod 0600 INIT.C || echo "restore of INIT.C fails"
sed 's/^X//' << 'SHAR_EOF' > KEYS.C &&
X
X#include <gemdefs.h>
X#include <obdefs.h>
X#include <osbind.h>
X
X#include "globals.h"
X#include "xxed.h"
X
Xlong saveb;
X
X
Xdo_kbd(keycode,keymods)
X	int	keycode,keymods;
X{	
X	windowptr	thewin;
X	char 		inbuf[8];
X	long		lnum;
X	int			skip,button;
X
X/* this fuction is probably the most tangled code in the whole program */
X
X
X	if(inhex)
X		if(keycode == 0x1011)
X			handle_file(QUIT);
X
X	if (firstwindow == NULL) return; /* no window open  */
X
X	thewin = thefrontwin;
X
X	if(thewin->markson)
X		handle_marks(CLEAR);
X
X	graf_mouse(M_OFF, 0L);
X	skip = TRUE;
X	if(thewin->icount!=0) /* in the middle of a hex num input */
X		do_kbd2(thewin,keycode,keymods); /* handle hex input */
X	else
X	{	saveb = getbyte(thewin,thewin->position);
X				/* store the current undirtied byte	*/
X				/* then check for special keys		*/
X	switch (keycode) {
X		case 0x5200:	ins ^= TRUE;
X						if(ins)
X				    	{	menubar[INSERT].ob_state = CHECKED;
X							menubar[REPLACE].ob_state = NORMAL;
X						}
X						else
X						{	menubar[INSERT].ob_state = NORMAL;
X							menubar[REPLACE].ob_state = CHECKED;
X						}
X						wr_ins_rpl(ins);
X						break;
X		case 0x4d00:	cur_right(thewin);
X						break;
X		case 0x5000:	cur_down(thewin);
X						break;
X		case 0x4800: 	cur_up(thewin);
X						break;
X		case 0x4b00: 	cur_left(thewin);
X						break;
X		case 0x537f:	delete_one(thewin,thewin->position,1);
X						if(repos(thewin))
X							partial = FALSE;
X						else
X							partial = TRUE;
X						send_redraw(thewin);
X						break;
X		case 0x0e08:	if(thewin->position-1 >= 0)
X						{	delete_one(thewin,--thewin->position,1);
X							if(repos(thewin))
X								partial = FALSE;
X							else
X								partial = TRUE;
X							one_page(thewin,1);
X						}
X						break;
X		default: skip = FALSE;
X					}
X	if (!(skip))	/* if it was not a special key	*/
X		{
X		if(inhex)
X			do_kbd2(thewin,keycode,keymods); /* handle hex input */
X		else 	/* handle ascii input	*/
X			{	if( (thewin->position==thewin->flen-1) && !ins) /* in replace mode on terminal dummy byte */
X				{	button = form_alert(1, "[1][ The last byte in the file is | a dummy byte and cannot be | changed. It is not saved | with the file. Use insert mode. ][OK]");				
X					thewin->icount = 0;
X					graf_mouse(M_ON, 0L);
X					return;
X				}
X					if(keycode & 0xff)	
X						{	sprintf(inbuf,"%x",(keycode & 0xff));
X    	    				inbuf[2] = 0;
X    	    				lnum = (long)keycode & 0xff;
X							enter_it(thewin,inbuf,lnum);
X						}
X			}
X		}
X	} /* end of else for if(thewin->icount!=0).....  */
X	graf_mouse(M_ON, 0L);
X	
X}
X		
Xdo_kbd2(thewin,keycode,keymods) /* handles hex input */
X	windowptr	thewin;
X	int	keycode,keymods;
X{
X
X	if(thewin->icount==0)  /* not in the middle of entering a hex number */
X   {switch (keycode) {
X
X		case 0x3002:	handle_search(BACK);
X						break;
X		case 0x1e01:	handle_search(FORWARD);
X						break;
X		case 0x2106:	graf_mouse(M_ON, 0L);
X						handle_search(FIND);
X						graf_mouse(M_OFF, 0L);
X						break;
X		case 0x1910:	handle_marks(CLEAR);
X						break;
X		case 0x180f:	handle_marks(END);
X						break;
X		case 0x1709:	handle_marks(START);
X						break;
X		case 0x1205:	handle_edit(ERASE);
X						break;
X		case 0x2f16:	handle_edit(PASTE);
X						break;
X		case 0x2e03:	handle_edit(COPY);
X						break;
X		case 0x2d18:	handle_edit(CUT);
X						break;
X		case 0x1011:	handle_file(QUIT);
X						break;
X		case 0x1f13:	handle_file(SAVE);
X						break;
X		default	   :	thewin->input[thewin->icount++] = keycode & 0xFF;
X						if(thewin->markson) clear_marks(thewin);
X						ins_rpl(thewin);
X					}
X	}
X	else	{	thewin->input[thewin->icount++] = keycode & 0xFF;
X						ins_rpl(thewin);
X			}
X
X}
X
Xcur_up(thewin)
X	windowptr	thewin;
X{
X	 if((thewin->position-=16)<0)
X		thewin->position+=16;
X		else check_scroll(thewin);
X}
X
X
Xcur_down(thewin)
X	windowptr	thewin;
X{
X	 if((thewin->position+=16)>thewin->flen-1)
X		thewin->position-=16;
X		else check_scroll(thewin);
X}
X
Xcur_right(thewin)
X	windowptr	thewin;
X{
X 		if(++thewin->position>thewin->flen-1)
X			thewin->position--;
X			else check_scroll(thewin);
X}
X
Xcur_left(thewin)
X	windowptr	thewin;
X{
X	if(--thewin->position<0)
X		thewin->position++;
X		else check_scroll(thewin);
X}
X
Xcheck_scroll(thewin) /* cursor off screen?? scroll or reposition */
X	windowptr	thewin;
X{
X	long winlines, bottomchar;
X	int up, down;
X	
X	winlines = thewin->work.g_h/gl_hchar; /* no of lines can put in window  */
X	bottomchar = thewin->topchar + (winlines * 16) - 1;
X	
X	up = 2; down = 3;
X	
X	if (thewin->position > bottomchar )
X		if (thewin->position > bottomchar +16)
X			{	jump_pos(thewin);
X				send_redraw(thewin);
X			}
X		else	send_arrow(thewin,down);
X	if (thewin->position < thewin->topchar)
X		if (thewin->position < thewin->topchar - 16)
X			{	jump_pos(thewin);
X				send_redraw(thewin);
X			}
X		else	send_arrow(thewin,up);
X
X}
X
X
Xrepos(thewin)  /* reposition and redraw with cursor on screen */
X	windowptr	thewin;
X{
X	long winlines, bottomchar;
X	
X	winlines = thewin->work.g_h/gl_hchar; /* no of lines can put in window  */
X	bottomchar = thewin->topchar + (winlines * 16) - 1;
X	
X	if ( (thewin->position > bottomchar )||
X			(thewin->position < thewin->topchar) )
X	{	jump_pos(thewin);
X		return(1);
X	}
X	else
X		return(0);
X}
X
Xjump_pos(thewin) /* reset display parameters so cursor on screen */
X	windowptr	thewin;
X{	
X	long totallines, winlines, topwlnmax, topwline,dummy;
X	int		vslide;
X
X
X	totallines = 1 + thewin->flen/16;
X	winlines = thewin->work.g_h/gl_hchar; /* no of lines can put in window  */
X
X	thewin->topchar = ((thewin->position - (8 * winlines)) & 0xfffffff0);
X	if (thewin->topchar < 0)
X		thewin->topchar = 0;
X
X	topwlnmax = ((totallines - winlines)>0) ? (totallines-winlines) : 0;
X  	topwline = (thewin->topchar/16 < topwlnmax) ? thewin->topchar/16 : topwlnmax;
X	vslide = (1000*topwline)/topwlnmax;
X	thewin->vslidepos = vslide;
X}
X
Xins_rpl(thewin)  /* enters hex charactes into the file */
X	windowptr	thewin;
X{
X	int		x,y,handle,button;
X	char	*inbuf;
X	long	lnum;
X	unsigned	b;
X
X	x = 	thewin->xcur;
X	y = 	thewin->ycur + gl_hchar-1;
X	handle = thewin->graf.handle;
X	inbuf = thewin->input;
X
X		inbuf[thewin->icount]='\0';
X	if( (thewin->position==thewin->flen-1) && !ins) /* in replace mode on terminal dummy byte */
X	{	button = form_alert(1, "[1][ The last byte in the file is | a dummy byte and cannot be | changed. It is not saved | with the file. Use insert mode. ][OK]");				
X		thewin->icount = 0;
X		return;
X	}			 
X		if (hex_chk(thewin,inbuf[thewin->icount-1])==1) /* is a hex char */
X			if (thewin->icount==1) /* first hex char coming   */
X				{	b = saveb;	/* saveb is the current byte	*/
X					b = b & 0xf;
X					lnum = strtol(thewin->input,(char **)NULL,16);
X					lnum = (lnum<<4) + b;
X					/* write it back with top nibble changed	*/
X					putbyte(thewin,thewin->position,lnum);
X					v_gtext(handle, x, y, inbuf);
X				}
X			else 	
X	/* two valid hex characters entered. Enter in buffer and redrw line */
X			{	lnum = strtol(thewin->input,(char **)NULL,16);
X				enter_it(thewin,inbuf,lnum);
X			}
X		
X}
X
Xenter_it(thewin,inbuf,lnum) /* insert or replace byte redrawing screen */
X	windowptr	thewin;
X	char		*inbuf;
X	long		lnum;
X
X{	int x,y,handle;
X
X				handle = thewin->graf.handle;
X				x = 	thewin->xcur;
X				y = 	thewin->ycur + gl_hchar-1;
X				v_gtext(handle, x, y, inbuf);
X				thewin->icount=0;
X			if(!ins)	/* in replace mode	*/
X			{
X					putbyte(thewin,thewin->position,lnum);
X					graf_mouse(M_OFF, 0L);
X					one_line2(thewin,thewin->position);	/* see onepage.c */
X					cur_right(thewin);
X					graf_mouse(M_ON, 0L);
X			}
X			else	/* in insert mode	*/
X			{	inbuf = "  ";
X					*inbuf = (char)lnum;
X						/* restore current byte as HEX input dirties it */
X					putbyte(thewin,thewin->position,saveb);
X					insert_it(thewin,1L,inbuf);  /* see edit.c	*/
X					graf_mouse(M_OFF, 0L);
X				if(thewin->position == thewin->flen-1)
X						one_line2(thewin,thewin->position);
X				else
X				{	
X					one_line2(thewin,thewin->position);	/* see onepage.c */
X					partial = TRUE;
X					send_redraw(thewin);
X				}
X					graf_mouse(M_ON, 0L);
X					cur_right(thewin);
X			}
X}
X
X
Xhex_chk(thewin, ch) /* checks to see if a hex character was entered */
X	windowptr	thewin;
X	char	ch;
X{
X	int ret, button;
X	static int times;
X	switch (ch) {
X		case '0': case '1': case '2': case '3': case '4': case '5':
X		case '6': case '7': case '8': case '9': case 'A': case 'B':
SHAR_EOF
echo "End of part 1, continue with part 2"
echo "2" > s2_seq_.tmp
exit 0