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

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

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

#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file KEYS.C continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
sed 's/^X//' << 'SHAR_EOF' >> KEYS.C
X		case 'C': case 'D': case 'E': case 'F': case 'a': case 'b':
X		case 'c': case 'd': case 'e': case 'f': ret = 1 ; times = 0; break;
X        case  8 : 	thewin->icount = 0;  /* backspace  after one hex char */
X					graf_mouse(M_OFF, 0L);
X		/*	restore the byte and redraw line	*/
X					putbyte(thewin,thewin->position,saveb);
X					one_line2(thewin,thewin->position);
X					graf_mouse(M_ON, 0L);
X					times = 0;
X					ret = 0;
X				  	break;
X        default :	Bconout(2,7);
X					thewin->icount--; /*  wipe out nonhex char  */
X					times++;
X					if (times>2)
X	button = form_alert(1, "[1][ | | Enter a HEX digit or Backspace ][ OK ]");				
X					ret = 0;
X                }
X		return(ret);
X}
X
Xwr_ins_rpl(insflag) /* writes insert/replace/hex/ascii on menu line */
X	int	insflag;
X{	windowptr	thewin;
X	
X	cursor(60,0);
X	if(thewin = thefrontwin)
X	{	if(insflag && inhex)
X			{printf("%s\n","HEX   insert ");}
X		if(!(insflag) && inhex)
X			{printf("%s\n","HEX   replace");}
X		if(insflag && !(inhex))
X			{printf("%s\n","ASCII insert ");}
X		if(!(insflag) && !(inhex))
X			{printf("%s\n","ASCII replace");}
X	}
X	else
X		printf("%s\n","             ");
X}
X
Xcursor(x,y)   /* position the cursor*/
X        int x,y;
X  {     Bconout(2,27); Bconout(2,'Y');
X        Bconout(2,(32 + y)); Bconout(2,(32 + x));
X  }
SHAR_EOF
chmod 0600 KEYS.C || echo "restore of KEYS.C fails"
sed 's/^X//' << 'SHAR_EOF' > MAIN.C &&
X#include <gemdefs.h>
X#include <osbind.h>
X#include <obdefs.h>
X
X#define  extern
X#include "globals.h"
X#undef   extern
X
X
X/*
X	main - executes initialization code and the starts the program.
X*/
Xmain()
X{
X	int  dummy, button;
X
X	/*
X		Initiailize the ROMs.
X	*/
X	gl_apid = appl_init();
X
X	if(Getrez() == 0)
X		{	button = form_alert(1, "[1][ Sorry....    | Need medium or high resolution. ][OK]");
X		shutdown(2);
X		}      
X
X	/*
X		Load resources.
X	*/
X	init_resources();
X
X	/*
X		Read menu resource, draw menu bar, read dialog resources.
X	*/
X	init_menu();
X	init_dialog();
X	init_path();
X	/*
X		Get the Physical work station handle.
X	*/
X	phys_handle = graf_handle(&gl_wchar, &gl_hchar, &dummy, &dummy);
X
X
X	/*
X		Initialize the mouse.
X	*/
X	graf_mouse(ARROW, NULL);
X
X	set_table();	/*  makes two byte ascii hex table   */
X
X
X	/*
X		Handle events for application.
X	*/
X	TaskMaster(); 
X
X	/*
X		bye...  Note: This will never be executed.
X	*/
X	shutdown(0);
X}
X
Xset_table()	/* makes a table of ASCII hex bytes for 0 to 255  */
X{	unsigned i;
X	
X	table[0] = '\0';
X	for(i=0;i<256;i++)
X		sprintf(table+2*i,"%02x",i);
X}
SHAR_EOF
chmod 0600 MAIN.C || echo "restore of MAIN.C fails"
sed 's/^X//' << 'SHAR_EOF' > MAKEFILE &&
X#
X# Environment variable CC should be set to path to cc.ttp
X#
X
XOFILES= main.o init.o events.o wind.o menu.o files.o\
X		onepage.o bufman.o slider.o cursor.o keys.o button.o\
X		edit.o search.o	send.o printer.o xxedrsc.o
X
Xxxed.prg : $(OFILES)
X	$(CC) $(OFILES) -o xxed.prg
X
X$(OFILES) : globals.h xxed.h
SHAR_EOF
chmod 0600 MAKEFILE || echo "restore of MAKEFILE fails"
sed 's/^X//' << 'SHAR_EOF' > MENU.C &&
X
X#include <gemdefs.h>
X#include <obdefs.h>
X#include <osbind.h>
X
X#include "xxed.h"  	/* contains definition of menubar */
X#include "globals.h"	/* header file created by RCP     */
X
Xextern char *chk_sstr_len();
Xextern char *chk_rstr_len();
X
X/*
X	do_menu - determines which menu was selected and calls the
X		appropriate routine to handle the item selected.
X*/
Xdo_menu(message)
X	int *message;
X{
X	int menuid, itemid;
X
X	menuid = message[3];
X	itemid = message[4];
X
X	switch(menuid) {
X		case DESK:
X				handle_desk(itemid);
X				break;
X
X		case FILE:
X				handle_file(itemid);
X				break;
X
X		case EDIT:	handle_edit(itemid);
X					break;
X        case MARK: 	handle_marks(itemid);
X                   	break;
X		case SEARCH:	handle_search(itemid);
X						break;
X		case WINDOWS:	rot_wind();
X	}
X
X	menu_tnormal(menubar, menuid, 1);
X}
X
Xhandle_desk(itemid)
X	int itemid;
X{
X	switch(itemid) {
X		case ABOUT:	do_dialog(dialog2);
X					dialog2[OK1].ob_state = NORMAL;
X					break;
X	}
X}
X
X
X/*
X	handle_file - performs the appropriate action for the menu item selected.
X*/
Xhandle_file(itemid)
X	int itemid;
X{
X	int  button;
X	windowptr	thewin;
X
X	switch(itemid) {
X		case NEW:	new();
X					break;
X		case OPEN:
X			thewin = new_window(UPARROW | DNARROW | VSLIDE | SIZER
X									 | MOVER | FULLER | CLOSER | NAME);
X
X			if(thewin==NULL) break; /* abort if no more window handles */
X
X			if 	(button = getfile(thewin))
X				{	if	(read_file(thewin))
X						open_window(thewin);
X					else
X						dispose_win_resources(thewin);
X				}
X			else
X				dispose_win_resources(thewin);
X							break;
X        case SAVE:		if(thewin=thefrontwin)
X							save_file(thewin);
X						break;
X        case SAVEAS: 	if(thewin=thefrontwin)
X							write_file(thewin);
X				 		break;
X		case CLOSE:		if (thewin=thefrontwin)
X						{	dispose_buf(thewin);
X							dispose_window(thewin);
X						}
X						break;
X		case DELETE:	delfile();
X						break;
X		
X		case SPACE:		drives();
X						break;
X
X		case PRINT:		if(thewin = thefrontwin)
X							print(thewin);
X						break;
X        
X		case QUIT:		shutdown(0);
X						break;
X	}
X}
X
Xnew()  /* opens a new window with associated file  */
X{
X	int	button;
X	linkbufptr	bufptr;
X	windowptr	thewin;
X
X			thewin = new_window(UPARROW | DNARROW | VSLIDE | SIZER
X									 | MOVER | FULLER | CLOSER | NAME);
X			if(thewin==NULL)
X 				return; /* abort if no more window handles */
X            bufptr = addmember(thewin);
X			if (bufptr == NULL)
X				{ 	button = form_alert(1, "[1][ Out of memory. | Cannot create new workspace ][OK]");
X					dispose_win_resources(thewin);
X				}
X			else
X			{	open_window(thewin);
X				if(getfile(thewin))
X				{	bufptr->inuse=1;
X					thewin->flen =1;
X					ins = TRUE;
X					menubar[INSERT].ob_state = CHECKED;
X					menubar[REPLACE].ob_state = NORMAL;
X					wr_ins_rpl(ins);
X				}
X				else
X				{	dispose_buf(thewin);
X					dispose_window(thewin);
X				}
X			}
X}
X
X/*
X	handle_mark - performs the appropriate action for the menu item selected.
X*/
Xhandle_marks(itemid)
X	int itemid;
X{
X	char string[80]; 
X	windowptr thewin;
X       		
X	switch(itemid) {
X		case START	:   thewin = thefrontwin;
X						if(thewin && thewin->flen)/* a window is open ?  */
X						start_mark(thewin);
X						break;
X		 		
X
X		case END	:	thewin = thefrontwin;
X						if(thewin && thewin->flen)/* a window is open ?  */
X						end_mark(thewin);
X						break;
X
X		case CLEAR	: 	thewin = thefrontwin;
X						if(thewin && thewin->flen)/* a window is open ?  */
X						clear_marks(thewin);
X						break;
X
X
X	}
X
X}
X
Xstart_mark(thewin)
Xwindowptr	thewin;
X{	thewin->startmark = thewin->position;
X	if( (thewin->startmark <= thewin->endmark)
X				|| thewin->markson )
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
Xend_mark(thewin)
Xwindowptr	thewin;
X{	
X	thewin->endmark = thewin->position<thewin->flen-1 ?
X							 thewin->position : thewin->flen-2;
X	if( (thewin->endmark >= thewin->startmark)
X				|| thewin->markson )
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
Xclear_marks(thewin)
Xwindowptr	thewin;
X	{	thewin->startmark = 1;
X		thewin->endmark = 0;
X		one_page(thewin,0);
X		thewin->markson = FALSE;
X		menubar[CUT].ob_state = DISABLED;
X		menubar[COPY].ob_state = DISABLED;
X		menubar[ERASE].ob_state = DISABLED;
X	}
X
X
Xhandle_edit(itemid)
X	int itemid;
X{
X	char string[80]; 
X	windowptr thewin;
X	linkbufptr	amem;
X	long pos;
X       		
X	switch(itemid) {
X		case COPY	: 	if( (thewin = thefrontwin) && thewin->markson)
X						{	copy(thewin);
X							handle_marks(CLEAR);
X							menubar[CUT].ob_state = DISABLED;
X							menubar[COPY].ob_state = DISABLED;
X							menubar[ERASE].ob_state = DISABLED;
X							menubar[PASTE].ob_state = NORMAL;
X						}
X						break;
X		 		
X
X		case CUT	:	if( (thewin = thefrontwin) && thewin->markson)
X						{	copy(thewin);
X							cutit(thewin);
X							send_vslid(thewin);
X							thewin->changed = TRUE;
X							handle_marks(CLEAR);
X							menubar[CUT].ob_state = DISABLED;
X							menubar[COPY].ob_state = DISABLED;
X							menubar[ERASE].ob_state = DISABLED;
X							menubar[PASTE].ob_state = NORMAL;
X						}
X						break;
X
X		case PASTE	: 	if(thewin = thefrontwin)
X							paste(thewin);
X							thewin->changed = TRUE;
X						break;
X		case ERASE	:	if( (thewin = thefrontwin) && thewin->markson)		
X						{	cutit(thewin);
X							send_vslid(thewin);
X							thewin->changed = TRUE;
X							handle_marks(CLEAR);
X						}
X						break;
X		case INSERT :	ins = TRUE;
X						wr_ins_rpl(ins);
X				        menubar[INSERT].ob_state = CHECKED;
X						menubar[REPLACE].ob_state = NORMAL;
X						break;
X		case REPLACE :	ins = FALSE;
X						wr_ins_rpl(ins);
X				        menubar[INSERT].ob_state = NORMAL;
X						menubar[REPLACE].ob_state = CHECKED;
X						break;				
X
X
X	}
X
X}
X
Xhandle_search(itemid)
X	int itemid;
X{
X	char *sstr;
X	windowptr	thewin; 
X
X	if(thewin=thefrontwin)	
X	{	switch(itemid) {
X			case FIND	:		find0(thewin);
X								break;
X			case FORWARD	:	if(sstr = chk_sstr_len(thewin))
X								forward1(thewin,sstr);
X								check_scroll(thewin);
X								break;
X			case BACK	:		if(sstr = chk_sstr_len(thewin))
X								back1(thewin,sstr);
X								break;
X						}
X	}
X}
SHAR_EOF
chmod 0600 MENU.C || echo "restore of MENU.C fails"
sed 's/^X//' << 'SHAR_EOF' > ONEPAGE.C &&
X#include "stdio.h"
X#include "gemdefs.h"
X#include "obdefs.h"
X#include "osbind.h"
X
X#include "globals.h"
X
X
X	unsigned getbyte();
X
X	char str2[80],str3[80];
X	char twoblanks[5]="  ";
X
X/*		Display one window full of data.       */
X
Xone_page(thewin, blank) /* draw one window full of data */
X	windowptr	thewin;
X	int			blank;
X{	int i, nc;
X
X	wr_ins_rpl(ins); /* input status written upper rt.  see keys.c */
X
X	graf_mouse(M_OFF, 0L);
X	nc = (thewin->work.g_h/gl_hchar)*16;  /* nc is number of char */
X	if(partial)
X	{	nc = nc - (thewin->position - thewin->topchar ) + 16;
X		for(i=0;i<nc;i+=16)
X			one_line0(thewin,thewin->position+i);
X			partial = FALSE;
X	}
X	else
X	{
X		wind_blank(thewin);
X		for(i=0;i<nc;i+=16)
X			one_line0(thewin,thewin->topchar+i);
X	}
X		graf_mouse(M_ON, 0L);
X
X}
X
X
Xunsigned getbyte(thewin,pos) /* retreive any byte in file in ram */
X	windowptr thewin;
X	long pos;
X{	
X	linkbufptr amem;
X	char *addr;
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		return(*addr);
X	}
X	else return((unsigned)0x00);
X}
X
Xputbyte(thewin,pos,lnum) /* put byte lnum into file at pos */
X	windowptr	thewin;
X	long	pos, lnum;
X{
X	linkbufptr amem;
X	char *addr;
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		*addr = (char)lnum;
X		thewin->changed = TRUE;
X	}
X}
X
X
Xone_line0(thewin,pos)
X	windowptr	thewin;
X	long 		pos;
X{
X	long l;
X
X	l = pos&~0xf;
X	if( (l > thewin->endmark) || ((l+16) < thewin->startmark) )
X		one_line1(thewin,pos);
X	else
X		one_line2(thewin,pos);
X
X}
X
Xone_line2(thewin,pos)	/* handles mixed marked and unmarked */
X	windowptr	thewin;
X	long 		pos;
X
X{	int i, lineno;
X	int			tx, ty;
X	int			grafhandle;
X	long  l;
X	unsigned num;
X	register int j,k;
X	char *ptr3;
X
X	tx = thewin -> work.g_x + 7;
X	ty = thewin -> work.g_y + gl_hchar;
X	grafhandle = thewin -> graf.handle;
X
X
X	lineno = (pos - thewin->topchar)>>4;
X	ty += (gl_hchar*lineno);
X			l = pos&~0xf;
X			ptr3=str3;
X			str2[2] = '\0';
X		for (j=0; j < 16 ; j +=2 )
X         {  for (k=0; k < 2  ; k++   )
X			{	if(l+j+k < thewin->flen-1)
X				{	num = getbyte(thewin,l + j + k);
X					if(num)
X						*(ptr3++) = num;
X					else
X						*(ptr3++) = (unsigned)32;
X					bcopy(table+num*2,str2,2);
X					if( (l+j+k>=thewin->startmark) && (l+j+k<=thewin->endmark) )
X						vswr_mode(thewin->graf.handle,4);
X					else
X						vswr_mode(thewin->graf.handle,1);
X				}
X				else
X				{	bcopy(twoblanks,str2,3);
X					*(ptr3++) = (unsigned)32;
X				}
X						v_gtext(grafhandle, tx, ty, str2);
X					tx += 2*gl_wchar;
X			}		
X					vswr_mode(thewin->graf.handle,1);
X					bcopy(twoblanks,str2,3);
X					v_gtext(grafhandle, tx, ty, str2);
X					tx += 2*gl_wchar;
X		}
X				*(ptr3++)=0x0;
X				vswr_mode(thewin->graf.handle,1);
X				v_gtext(thewin->graf.handle, tx, ty, str3);
X}
X
Xone_line1(thewin,pos)	/* handles unmarked text	*/
X	windowptr	thewin;
X	long 		pos;
X
X{	int i, lineno;
X	int			tx, ty;
X	int			grafhandle;
X	long  l;
X	unsigned num;
X	register int j,k;
X	char *ptr2,*ptr3;
X
X	tx = thewin -> work.g_x + 7;
X	ty = thewin -> work.g_y + gl_hchar;
X
X	lineno = (pos - thewin->topchar)>>4;
X	ty += (gl_hchar*lineno);
X			l = pos&~0xf;
X			ptr2 = str2;
X			ptr3 = str3;
X
X	           for (j=0; j < 16 ; j +=2 )
X          {  for (k=0; k < 2  ; k++   )
X            {	num = getbyte(thewin,l + j + k);
X            	if(l+j+k < thewin->flen-1)
X				{
X					if(num)
X						*(ptr3++) = num;
X					else
X						*(ptr3++) = (unsigned)32;
X					bcopy(table+num*2,ptr2,2);
X					ptr2+=2;
X				}
X				else
X				{	bcopy(twoblanks,ptr2,2);
X					ptr2+=2;
X					*(ptr3++) = 0x20;
X				}
X             }
X				*(ptr2++)=0x20;
X				*(ptr2++)=0x20;
X           }   
X				*(ptr2++)=0x20;
X				*(ptr2++)=0x20;
X				*(ptr2++)=0x0;
X				v_gtext(thewin->graf.handle, tx, ty, str2);
X				tx += 48*gl_wchar; 
X				*(ptr3++)=0x0;
X				v_gtext(thewin->graf.handle, tx, ty,str3);
X}
X
SHAR_EOF
chmod 0600 ONEPAGE.C || echo "restore of ONEPAGE.C fails"
sed 's/^X//' << 'SHAR_EOF' > PRINTER.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	extern unsigned getbyte();
X	extern char str2[],str3[];
X	extern char twoblanks[];
X
X
Xprint(thewin) /* send file or block to printer */
Xwindowptr thewin;
X{
X	int button;
X	char str[200];
X	long l;
X
X	if(Bcostat(0)==0)
X	{	button = form_alert(1, "[1][ The printer is not connected | or not turned on! ][ OK ]");
X		return;
X	}
X
X	while(Cconis()) Crawcin(); /* make sure io buffer clear */
X	if(thewin->markson)
X	{	sprintf(str, "[1][ Print block from | %s ? | (Any key aborts    |  while printing) ][ OK | CANCEL ]",thewin->title);
X		button = form_alert(1,str);
X		if (button == 1)	
X			for (l=thewin->startmark;l<thewin->endmark+16;l+=16)
X            {   print_line(thewin,l);
X				if (Cconis())
X				{	Crawcin();
X				 	break;  /* any key to abort */
X				}		
X			}
X	}		
X	else
X	{	sprintf(str, "[1][ Print file | %s ? | (Any key aborts    |  while printing) ][ OK | CANCEL ]",thewin->title);
X		button = form_alert(1,str);
X		if (button == 1)	
X			for (l=0;l<thewin->flen+17;l+=16)
X            {   print_line(thewin,l);
X				if (Cconis())
X				{	Crawcin();
X				 	break;  /* any key to abort */
X				}		
X			}
X	}		
X	
X}
X
X
X
Xprint_line(thewin,pos) /* send a line to the printer */
X	windowptr	thewin;
X	long		pos;
X{	int i;
X	long  l;
X	unsigned num;
X	register int j,k;
X	char *ptr2,*ptr3;
X
X			l = pos&~0xf;
X			ptr2 = str2;
X			ptr3 = str3;
X
X	           for (j=0; j < 16 ; j +=2 )
X          {  for (k=0; k < 2  ; k++   )
X            {	num = getbyte(thewin,l + j + k);
X            	if(l+j+k < thewin->flen-1)
X				{
X					if(num>31)
X						*(ptr3++) = num;
X					else
X						*(ptr3++) = (unsigned)0x2E;
X					bcopy(table+num*2,ptr2,2);
X					ptr2+=2;
X				}
X				else
X				{	bcopy(twoblanks,ptr2,2);
X					ptr2+=2;
X					*(ptr3++) = 0x20;
X				}
X             }
X				*(ptr2++)=0x20;
X				*(ptr2++)=0x20;
X           }   
X				*(ptr2++)=0x20;
X				*(ptr2++)=0x20;
X				*(ptr2++)=0x0;
X				pr_print(str2);
X				*(ptr3++)=0x0D;
X				*(ptr3++)=0x0A;
X				*(ptr3++)=0x0;
X				pr_print(str3);
X}
X
X
Xpr_print(str) /* send a string to the printer */
X	char *str;
X{	int i;
X
X	{	for (i=0;i<(strlen(str)+1);i++)
X			Bconout(0,str[i]);
X	}
X}	
SHAR_EOF
chmod 0600 PRINTER.C || echo "restore of PRINTER.C fails"
sed 's/^X//' << 'SHAR_EOF' > SEARCH.C &&
X#include <stdio.h>
X#include <gemdefs.h>
X#include <obdefs.h>
X#include <osbind.h>
X
X#include "globals.h"
X#include "xxed.h"
X
Xlong forward2();
Xlong back2();
Xchar *chk_sstr_len();
Xchar *chk_rstr_len();
X
Xlong rl,sl;  /* length of replace and search strings  */
X
X
Xfind(thewin) /* handles search and replace dialog box  */
X	windowptr	thewin;
X{
X	int	button;
X	
X
X	button = do_dialog(dialog1);
X	dialog1[SFORWARD].ob_state = NORMAL;
X	dialog1[SBACK].ob_state = NORMAL;
X	dialog1[CANCEL1].ob_state = NORMAL;
X	dialog1[RONCE].ob_state = NORMAL;
X	dialog1[RALL].ob_state = NORMAL;
X	dialog1[RVER].ob_state = NORMAL;
X
X
X	return(button);
X}
X
Xchar *chk_sstr_len(thewin) /* check search string length */
X	windowptr	thewin;
X{
X	char *sstr;
X	int  button;
X
X		if( (dialog1[SCUTBUF].ob_state == SELECTED) )
X		{	sstr = cutbuffer;
X			sl = cutlength;
X		}
X		else
X		{	sstr = s_str;
X			sl = strlen(sstr);
X		}
X			if ( (sstr == NULL) || (sl == 0) )
X	{	button = form_alert(1, "[1][ Nul search string... | Aborting.   ][ OK ]");
X		return(0);
X	}
X			else
X		return(sstr);
X}
X
Xchar *chk_rstr_len(thewin)
X	windowptr	thewin;
X{
X	char *rstr;
X	int  button;
X
X		if( (dialog1[RCUTBUF].ob_state == SELECTED) )
X		{	rstr = cutbuffer;
X			rl = cutlength;
X		}
X		else
X		{	rstr = r_str;
X			rl = strlen(rstr);
X		}
X			if ( (rstr == NULL) || (rl == 0) )
X	{	button = form_alert(1, "[1][ Nul replace string... | Aborting.   ][ OK ]");
X		return(0);
X	}
X			else
X		return(rstr);
X}
X
Xfind0(thewin) /* handles results from srch/rpl dialog */
X	windowptr	thewin;
X{
X	char *sstr, *rstr;
X	int	button;
X	long	pos;
X
X		button = find(thewin);
X		if (button == CANCEL1)
X			return;
X		if (!(sstr = chk_sstr_len(thewin)))
X			return;
X
X		switch (button)
X		 	{
X			case SFORWARD :	forward1(thewin,sstr);
X							check_scroll(thewin);
X							break;
X			case SBACK :	back1(thewin,sstr);
X							break;
X			case RONCE :	if (!(rstr = chk_rstr_len(thewin)))
X								break;
X							ronce(thewin,sstr,rstr);
X							repos(thewin);
X							one_page(thewin,1);
X							redraw_vslider(thewin->handle);
X							break;
X			case RALL :		if (!(rstr = chk_rstr_len(thewin)))
X								break;
X							rall(thewin,sstr,rstr);
X							break;
X			case RVER :		if (!(rstr = chk_rstr_len(thewin)))
X								return;
X							rver(thewin,sstr,rstr);
X							break;
X			default : 		;
X			}		
X}
X
Xforward1(thewin,sstr) /* searches forward */
X	windowptr	thewin;
X	char *sstr;
X{
X	long	pos;
X	int	button;
X
X	graf_mouse(2,0L);
X
X	if(thewin->position < thewin->flen-2) thewin->position += 1;
X	if( (pos=forward2(thewin,sstr)) > 0 )
X	{	thewin->position = pos;
X		graf_mouse(0,0L);
X		return(-1);
X	}
X	else
X	{	button = form_alert(1, "[1][ | | No (further) occurrences of | the string can be found. |  ][ OK ]");
X		thewin->position -= 1;
X		graf_mouse(0,0L);
X		return(0);
X	}
X}
X
Xrp_forw(thewin,sstr) /* replace going forward */
X	windowptr	thewin;
X	char *sstr;
X{
X	long	pos;
X	int	button;
X
X	if( (pos=forward2(thewin,sstr)) > -1)
X	{	thewin->position = pos;
X		return(-1);
X	}
X	else
X	{	one_page(thewin,1);
X		redraw_vslider(thewin->handle);
X		button = form_alert(1, "[1][ | | No (further) occurrences of | the string can be found. |  ][ OK ]");
X		return(0);
X	}
X}
X
X
Xlong forward2(thewin,sstr)
X	windowptr	thewin;
X	char *sstr;
X{
X	unsigned	num;
X	int	j, strl;
X	long i;
X
X		strl = strlen(sstr);
X		for (i=thewin->position;i<(thewin->flen-strl);i++)
X		{	j=1;
X			num = getbyte(thewin,i);
X			if(num == sstr[0])
X			{	while (j<strl)
X				{	if( (num = getbyte(thewin,i+j)) == sstr[j])
X						j+=1;
X					else
X						break;
X				}
X				if (j == strl)
X					return(i);
X			}
X		}
X		return(-1);
X}
X
Xback1(thewin,sstr) /* search backwards */
X	windowptr	thewin;
X	char *sstr;
X{
X	long	pos;
X	int	button;
X
X	graf_mouse(2,0L);
X
X		 thewin->position -= 1;
X	if( (pos=back2(thewin,sstr)) > -1 )
X	{	thewin->position = pos;
X		check_scroll(thewin);
X	}
X	else
X	{	button = form_alert(1, "[1][ | |   String not found.   ][ OK ]");
X		thewin->position += 1;
X	}
X	graf_mouse(0,0L);
X}
X
Xlong back2(thewin,sstr)
X	windowptr	thewin;
X	char *sstr;
X{
X	unsigned	num;
X	int	j, strl;
X	long i;
X
X
X		strl = strlen(sstr);
X		for (i=thewin->position;i > -1;i--)
X		{	j=1;
X			num = getbyte(thewin,i);
X			if(num == sstr[0])
X			{	while (j<strl)
X				{	if( (num = getbyte(thewin,i+j)) == sstr[j])
X						j+=1;
X					else
X						break;
X				}
X				if (j == strl)
X					return(i);
X			}
X		}
X		return(-1);
X}		
X
Xronce(thewin,sstr,rstr) /* replace once */
X	windowptr	thewin;
X	char *sstr, *rstr;
X{
X	long rl;
X	int sl, button, c;
X
X
X	if((c = strcmp(sstr,rstr))==0)
X	{	button = form_alert(1, "[1][ | Search and Replace strings | are identical.  Aborting...  |  ][ OK ]");
X		return(0);
X	}
X	graf_mouse(2,0L);
X	if(rp_forw(thewin,sstr))
X	{	rl = strlen(rstr);
X		sl = strlen(sstr);
X		thewin->startmark = thewin->position;
X		thewin->position += sl;
X		thewin->endmark = thewin->position -1;
X		thewin->markson = TRUE;
X		cutit(thewin);
X		thewin->changed = TRUE;
X/* following code just clears the marks  */
X			{	thewin->startmark = 1;
X				thewin->endmark = 0;
X				thewin->markson = FALSE;
X			}
X	
X	/* insert_it() inserts rl bytes from string pointed to by rstr
X   	into the file before the position of the cursor... see edit.c
X	*/
X		insert_it(thewin,rl,rstr);
X		graf_mouse(0,0L);
X		return(-1);
X	}
X	else
X		graf_mouse(0,0L);
X		return(0);
X}	
X	
Xrall(thewin,sstr,rstr) /* replace all */
X	windowptr	thewin;
X	char *sstr, *rstr;
X{
X	int c, button;
X
X	if((c = strcmp(sstr,rstr))==0)
X	{	button = form_alert(1, "[1][ | Search and Replace strings | are identical.  Aborting...  |  ][ OK ]");
X		return(0);
X	}
X	one_page(thewin,1);
X	while(ronce(thewin,sstr,rstr))
X		thewin->position += rl;	
X	thewin->position -= rl;
X	jump_pos(thewin);
X	send_redraw(thewin);
X}
Xrver(thewin,sstr,rstr) /* replace with verify */
X	windowptr	thewin;
X	char *sstr, *rstr;
X{
X	int button, result, c;
X
X	if((c = strcmp(sstr,rstr))==0)
X	{	button = form_alert(1, "[1][ | Search and Replace strings | are identical.  Aborting...  |  ][ OK ]");
X		return(0);
X	}
X	graf_mouse(2,0L);
X	result = 1;	
X	while(result)
X	{	if(rp_forw(thewin,sstr))
X		{	repos(thewin);
X			one_page(thewin,1);
X			redraw_vslider(thewin->handle);
X				if(thewin = thefrontwin)
X				{	graf_mouse(M_OFF, 0L);
X					putcur(thewin);	/* cursor on	*/
X					graf_mouse(M_ON, 0L);
X				}
X			graf_mouse(0,0L);
X			button = do_dialxy(dialog3,100,100);
X			graf_mouse(2,0L);
X			dialog3[RPBUT].ob_state = NORMAL;
X			dialog3[SKBUT].ob_state = NORMAL;
X			dialog3[ABBUT].ob_state = NORMAL;
X				if(thewin = thefrontwin)
X				{	graf_mouse(M_OFF, 0L);
X					putcur(thewin);	/* cursor off	*/
X					graf_mouse(M_ON, 0L);
X				}
X		if(button == RPBUT)
X			{	thewin->startmark = thewin->position;
X				thewin->position += sl;
X				thewin->endmark = thewin->position -1;
X				thewin->markson = TRUE;
X				cutit(thewin);
X				thewin->changed = TRUE;
X		/* following code just clears the marks  */
X					{	thewin->startmark = 1;
X						thewin->endmark = 0;
X						thewin->markson = FALSE;
X					}
X			
X			/* insert_it() inserts rl bytes from string pointed to by rstr
X   			into the file before the position of the cursor... see edit.c
X			*/
X				insert_it(thewin,rl,rstr);
X				thewin->position += rl;
X				result = 1;
X			}
X			if(button == SKBUT)
X				if(thewin->position < thewin->flen-2)
X						thewin->position += 1;
X			if(button == ABBUT)
X				break;
X		} /* end of if(rp_forw())  */
X		else
X		{	thewin->position -= rl;	
X			result = 0;
X		}
X	}  send_redraw(thewin);
X	graf_mouse(0,0L);
X}
X		
X
Xdo_dialog(dialog)   /* draw dialog boxes   */
XOBJECT *dialog;
X{
X	int	cx, cy, cw, ch, button;
X
X	form_center(dialog, &cx, &cy, &cw, &ch);
X	form_dial(FMD_START, 0, 0, 0, 0, cx, cy, cw, ch);
X	objc_draw(dialog, 0, 10, cx, cy, cw, ch);
X	button = form_do(dialog, 0);
X	form_dial(FMD_FINISH, 0, 0, 0, 0, cx, cy, cw, ch);
X	return(button);
X}
Xdo_dialxy(dialog,x,y) /* draw dialog at specific position with form_do */
XOBJECT *dialog;
Xint x,y;
X{
X	int	cx, cy, cw, ch, button;
X
X	dialog->ob_x = x;
X	dialog->ob_y = y;
X	cx = x;
X	cy = y;
X	cw = dialog->ob_width;
X	ch = dialog->ob_height;
X
X	form_dial(FMD_START, 0, 0, 0, 0, cx, cy, cw, ch);
X	objc_draw(dialog, 0, 10, cx, cy, cw, ch);
X	button = form_do(dialog, 0);
X	form_dial(FMD_FINISH, 0, 0, 0, 0, cx, cy, cw, ch);
X	return(button);
X}
X
Xdrw_dialxy(dialog,x,y) /* draw object at a position.. no form_do */
XOBJECT *dialog;
Xint x,y;
X{
X	int	cx, cy, cw, ch;
X
X	dialog->ob_x = x;
X	dialog->ob_y = y;
X	cx = x;
X	cy = y;
X	cw = dialog->ob_width;
X	ch = dialog->ob_height;
X	form_dial(FMD_START, 0, 0, 0, 0, cx, cy, cw, ch);
X	objc_draw(dialog, 0, 10, cx, cy, cw, ch);
X}
SHAR_EOF
chmod 0600 SEARCH.C || echo "restore of SEARCH.C fails"
sed 's/^X//' << 'SHAR_EOF' > SEND.C &&
X
X#include "stdio.h"
X#include "gemdefs.h"
X#include "obdefs.h"
X#include "osbind.h"
X#include "globals.h"
X
Xsend_vslid(thewin) /* send application slider message */
X	windowptr	thewin;
X{  
X         int msg[8]; 
X                    /* the message buffer */ 
X
X	if(slid_flag)
X		return;
X/* return if there is already a vslid message pending	*/
X
X         msg[0] = WM_VSLID;        /* message type is vslid */ 
X         msg[1] = gl_apid;          /* application id*/ 
X         msg[2] = 0;                /* message is standard 16 bytes */ 
X         msg[3] = thewin->handle;        /* handle of window to refresh */ 
X         msg[4] = thewin->vslidepos;       /* position of vslider */ 
X
X         appl_write( gl_apid, 16, msg ); 
X		slid_flag = TRUE;
X
X}
X
X
Xsend_redraw(thewin) /* send application a redraw message */
X	windowptr	thewin;
X{  
X         int msg[8];
X	if(draw_flag)
X		return;
X/* return if there is already a draw message pending	*/
X
X                    /* the message buffer */ 
X         msg[0] = WM_REDRAW;        /* message type is redw */ 
X         msg[1] = gl_apid;          /* application id*/ 
X         msg[2] = 0;                /* message is standard 16 bytes */ 
X         msg[3] = thewin->handle;        /* handle of window to refresh */ 
X         msg[4] = thewin->work.g_x;            /* position and size of redraw */ 
X         msg[5] = thewin->work.g_y; 
X         msg[6] = thewin->work.g_w; 
X         msg[7] = thewin->work.g_h; 
X
X         appl_write( gl_apid, 16, msg ); 
X		draw_flag = TRUE;
X
X/* 
X This will send a redraw to your own application. The above routine is taken 
Xfrom COMPUTES Technical Reference Guide for the Atari ST - Volume 2 AES. Have 
Xfun. 
X*/  
X  
X}
X
Ximmed_redraw(thewin) /* bypass event multi and do a screen redraw */
X	windowptr thewin;
X{
X         int msg[8];
X
X                    /* the message buffer */ 
X         msg[0] = WM_REDRAW;        /* message type is redw */ 
X         msg[1] = gl_apid;          /* application id*/ 
X         msg[2] = 0;                /* message is standard 16 bytes */ 
X         msg[3] = thewin->handle;        /* handle of window to refresh */ 
X         msg[4] = thewin->work.g_x;      /* position and size of redraw */ 
X         msg[5] = thewin->work.g_y; 
X         msg[6] = thewin->work.g_w; 
X         msg[7] = thewin->work.g_h; 
X	do_window(msg);
X}
X
Xsend_arrow(thewin,direction) /* send application an arrow message */
X	windowptr	thewin;
X	int			direction;
X{  
X         int msg[8]; 
X                    /* the message buffer */
X
X	if(arro_flag)
X		return;
X/* return if there is already a arrow message pending	*/
X 
X         msg[0] = WM_ARROWED;        /* message type is */ 
X         msg[1] = gl_apid;          /* application id*/ 
X         msg[2] = 0;                /* message is standard 16 bytes */ 
X         msg[3] = thewin->handle;        /* handle of window to refresh */ 
X         msg[4] = direction;            /* up = 2, down = 3 */ 
X         msg[5] = 0;
X         msg[6] = 0; 
X         msg[7] = 0; 
X
X         appl_write( gl_apid, 16, msg ); 
X		arro_flag = TRUE;
X}
SHAR_EOF
chmod 0600 SEND.C || echo "restore of SEND.C fails"
sed 's/^X//' << 'SHAR_EOF' > SLIDER.C &&
X
X#include "stdio.h"
X#include "gemdefs.h"
X#include "obdefs.h"
X#include "osbind.h"
X#include "globals.h"
X
X
X/* takes care of displaying the correct text in the window after
X      the slider has been moved or the window resized  */
Xvhandler(message)
X	int *message;
X{	int	vslideold, vslide; 
X	long	totallines, topwlnmax, topwline, winlines, topchar;
X	int		handle, ret;
X	windowptr	thewin;
X
X	handle = message[3];
X	thewin = findwindowptr(handle);
X
X
X	totallines = 1 + thewin->flen/16;
X
X	winlines = thewin->work.g_h/gl_hchar; /* no of lines can put in window  */
X
X	vslideold = thewin->vslidepos;  /* save the old slider position  */
X
X /* calculate the line number (from the top of the file) for the top
X    line displayed on the screen when the last full page of text
X    is being displayed in the window   */
X
X	topwlnmax = ((totallines - winlines)>0) ? (totallines-winlines) : 0;
X
X  /* topwline is the top line of the currently displayed page */
X
X  	topwline = (thewin->topchar/16 < topwlnmax) ? thewin->topchar/16 : topwlnmax;
X
X	if(thewin->topchar > topwline*16)
X		send_redraw(thewin);
X	thewin->topchar = topwline*16;
X	if(topwlnmax)
X		thewin->vslidepos = (1000*topwline)/topwlnmax;
X	else
X		thewin->vslidepos = 1;
X
X  switch (message[0]) {
X	case WM_ARROWED	:		
X            switch (message[4]) {
X                case 0 :    /* uppage */
X                 	topwline = (topwline-winlines+1>0) ? topwline-winlines+1 : 0;
X					thewin->topchar = topwline*16;
X		          if(topwline == 0) thewin->vslidepos = 1;
X          		  else    thewin->vslidepos = (1000*topwline)/topwlnmax;
X					send_redraw(thewin); 
X            		break;
X                case 1 :     /* dnpage  */
X                 	topwline += winlines - 1;
X                  	if(topwline>topwlnmax)topwline = topwlnmax;
X					thewin->topchar = topwline*16;
X		          if(topwline == 0) thewin->vslidepos = 1;
X          		  else    thewin->vslidepos = (1000*topwline)/topwlnmax;
X					send_redraw(thewin); 
X                    break;
X                case 2 :     /* upline  */  
X					if(--topwline<0) topwline++;
X					else
X					{	thewin->topchar = topwline*16;
X			          if(topwline == 0) thewin->vslidepos = 1;
X          			  else    thewin->vslidepos = (1000*topwline)/topwlnmax;
X							scroll(thewin,0,1);
X							redraw_vslider(thewin->handle);
X					}  
X                    break;
X                case 3 :     /* dnline  */
X					if(++topwline>topwlnmax) topwline--;
X					else
X				 	{	thewin->topchar = topwline*16;
X		          	  if(topwline == 0) thewin->vslidepos = 1;
X          		  	  else    thewin->vslidepos = (1000*topwline)/topwlnmax;
X							scroll(thewin,1,0);
X							redraw_vslider(thewin->handle);
X					}  
X					break;		 }  /* end of switch message[4]  */
X
X					break; /* from WM_ARROWED */
X				
X	case WM_VSLID :
X			  /* the sliderbox was "pulled" up or down  */
X	   vslide = message[4];
X		  /* if the slider box was moved by less than 5 units do nothing */
X        	if (abs(vslideold-vslide)<5) 
X				{	vslide = vslideold;
X				}
X			else  {	topwline = vslide*topwlnmax/1000;
X					thewin->topchar = topwline*16;
X    				thewin->vslidepos = vslide;
X					send_redraw(thewin);
X			  	  }	
X      
X				break; /* from WM_VSLID   */
X					}	/* end of switch message[0]  */
X}
X
Xredraw_vslider(wihandle)    /* redraws vslider in new postion  */
X	int	wihandle;
X{
X	windowptr	thewin;
X	int vslide_size, ret;
X	long totallines, seenlines;
X	
X	thewin = findwindowptr(wihandle);
X
X	totallines = 1 + thewin->flen/16;
X   
X    seenlines = min(totallines,(thewin->work.g_h/gl_hchar));
X    vslide_size = min(1000,1000*seenlines/totallines);
X	
X  /* redraw the slider  to its new position and with new size */				
X	wind_update(BEG_UPDATE);			
X	wind_set(thewin->handle,WF_VSLSIZE,vslide_size,0,0,0);
X	wind_set(wihandle,WF_VSLIDE,thewin->vslidepos,&ret,&ret,&ret);      
X	wind_update(END_UPDATE);
X 
X}
X
Xsize_vslider(wihandle)  /* set slider size  and redraws it */
X	int wihandle;
X{   int vslide_size;
X	long totallines, seenlines;
X	windowptr thewin;
X	
X	thewin = findwindowptr(wihandle);
X
X	totallines = 1 + thewin->flen/16;
X   
X    seenlines = min(totallines,(thewin->work.g_h/gl_hchar));
X    vslide_size = min(1000,1000*seenlines/totallines);
X    wind_set(thewin->handle,WF_VSLSIZE,vslide_size,0,0,0);
X}
X
X   /* the scroll routine which moves text up if the up flag is set
X      and down if the dnflag is set.  The other flag must be zero.
X      Finally blanks the space for the new line at top or bottom
X      and sets the clipping rectangle for just that line in preparation
X      for the text in the window to be redrawn.  Be sure to reset
X      the clipping to the full window work area after redrawing the
X      text        */
X
Xscroll(thewin,upflag,dnflag)
X	windowptr thewin;
X   int upflag, dnflag;
X
X{	int pxy[8], pxyc[4], i, lines_onscrn;
X	int xwork, ywork, hwork, wwork;   
X	long totallines,seenlines;
X
X        /* upflag=1 dnflag=0 for scroll up one line  */
X        /* upflag=0 dnflag=1 for scroll down one line  */
X
X	xwork = thewin->work.g_x;
X	ywork = thewin->work.g_y;
X	hwork = thewin->work.g_h;
X	wwork = thewin->work.g_w;
X
X		lines_onscrn=hwork/gl_hchar;
X
X        pxy[0] = xwork;
X        pxy[2] = xwork+wwork;
X        pxy[4] = xwork;
X        pxy[6] = xwork+wwork;
X
X    if(upflag==1)
X     {  pxy[1] = ywork+gl_hchar;
X        pxy[3] = ywork+hwork-1;
X        pxy[5] = ywork;
X        pxy[7] = ywork+hwork-1-gl_hchar;
X     } 
X    if(dnflag==1)
X     {  pxy[1] = ywork;
X        pxy[3] = ywork+hwork-1-gl_hchar;
X        pxy[5] = ywork+gl_hchar;
X        pxy[7] = ywork+hwork-1;
X     } 
X      /* scroll window */
X      
X      vro_cpyfm(thewin->graf.handle,S_ONLY,pxy,
X          				&thewin->graf.mfdb,&thewin->graf.mfdb);
X     /* now blank the top or bottom line as appropriate  */
X        pxyc[0] = xwork;
X        pxyc[2] = xwork + wwork - 1;
X
X
X /* if scroll up/dwn then blank out the
X                       last/first line on the screen  */
X     if(upflag == 1)  
X      {  pxyc[1] = ywork + (lines_onscrn-1)*gl_hchar + 1;
X         pxyc[3] = ywork + hwork - 1;
X /* set the clip rect to the line to be redrawn */ 
X         vs_clip(thewin->graf.handle,1,pxyc);
X         vr_recfl(thewin->graf.handle,pxyc);
X		graf_mouse(M_OFF, 0L);
X		one_line2(thewin,thewin->topchar+(thewin->work.g_h/gl_hchar)*16-8); 
X		graf_mouse(M_ON, 0L);
X /* the pos passed to one_line2 is topchar+g_h/16*16   */
X      }
X     if(dnflag == 1)
X      {  pxyc[1] = ywork;
X         pxyc[3] = ywork + gl_hchar;
X /* set the clip rect to the line to be redrawn */ 
X         vs_clip(thewin->graf.handle,1,pxyc);
X         vr_recfl(thewin->graf.handle,pxyc);
X		graf_mouse(M_OFF, 0L);
X         one_line2(thewin,thewin->topchar); 
X		graf_mouse(M_ON, 0L);
X      }
X
X}
SHAR_EOF
chmod 0600 SLIDER.C || echo "restore of SLIDER.C fails"
sed 's/^X//' << 'SHAR_EOF' > WIND.C &&
X#include <osbind.h>
X#include <gemdefs.h>
X#include <obdefs.h>
X
X#include "globals.h"
X
X/*
X	External references for window update procs.
X*/
Xextern one_page();
X
X/*
X	do_window - determines the type of window event and then calls
X		the appropriate function to handle the event.
X*/
Xdo_window(message)
X	int *message;
X{
X	int handle;
X	windowptr	thewin;
X
X	handle = message[3];
X
X	graf_mouse(M_OFF, 0L);
X	wind_update(BEG_UPDATE);
X
X	switch (message[0]) {
X		case WM_REDRAW:
X			draw_flag = FALSE;
X			do_update(message);
X		break;
X
X		case WM_NEWTOP:
X		case WM_TOPPED:
X			make_frontwin(findwindowptr(handle));
X		break;
X
X		case WM_MOVED:
X		case WM_SIZED:
X			do_resize(message);
X			redraw_vslider(handle);
X		break;
X
X		case WM_FULLED:
X			do_fullsize(handle);
X			redraw_vslider(handle);
X		break;
X
X		case WM_CLOSED:
X			thewin = findwindowptr(handle);
X			dispose_window(thewin);
X			dispose_buf(thewin);
X		break;
X		
X		case WM_ARROWED:
X			arro_flag = FALSE;
X		case WM_VSLID:
X			slid_flag = FALSE;
X			vhandler(message);
X	}
X
X	wind_update(END_UPDATE);
X	graf_mouse(M_ON, 0L);
X
X}
X
X
X/*
X	do_resize - redraws the window at it's new postion and updates all
X		of the window's position records.
X*/
Xdo_resize(message)
X	int *message;
X{
X	int x, y, w, h;
X	int handle;
X
X	handle	= message[3];
X	x		= (message[4]&~0x7);
X	y		= message[5];
X	w		= ((message[6]&~0x7)+4);
X	h		= message[7];
X
X	/*
X		Make sure that the window doesn't become too small.
X	*/
X	if (w < 80) w = 80;
X	if (h < 80) h = 84;
X
X	/*
X		Redraw the window at it's new size.
X	*/
X	wind_set(handle, WF_CURRXYWH, x, y, w, h);
X	wind_get(handle, WF_WORKXYWH, &x, &y, &w, &h);
X
X	{
X		/*
X			Set the Window record data.
X		*/
X		windowptr	thewin;
X
X		thewin = findwindowptr(handle);
X
X		rect_set(&thewin -> work, x, y, w, h);
X		rect_set(&thewin -> box, x, y, w, h);
X		thewin -> fullsize = FALSE;
X	}
X}
X
X
X/*
X	do_fullsize - draws the window at it's fully defined size.  If the window
X		is at it's full size then this routines restores the window to it's
X		previous size.
X*/
Xdo_fullsize(handle)
X	int handle;
X{
X	register windowptr	thewin;
X
X	int x, y, w, h;
X	int d;
X
X	thewin = findwindowptr(handle);
X
X	if (thewin -> fullsize) {
X		/*
X			Back to normal size
X		*/
X		wind_calc(WC_WORK, thewin -> kind, thewin -> box,
X			&thewin -> work.g_x, &thewin -> work.g_y,
X			&thewin -> work.g_w, &thewin -> work.g_h);
X
X/* note here that thewin->box, a GRECT structure of 4 ints  */
X/* is passed to wind_calc in place of four ints     jlc     */
X 
X		wind_set(handle, WF_CURRXYWH, thewin -> box);
X		thewin -> fullsize = FALSE;
X	} else {
X		/*
X			Draw window at full size;
X		*/
X		wind_get(handle, WF_FULLXYWH, &x, &y, &w, &h);
X		wind_set(handle, WF_CURRXYWH, x, y, w, h);
X		wind_calc(WC_WORK, thewin -> kind, x, y, w, h,
X			&thewin -> work.g_x, &thewin -> work.g_y,
X			&thewin -> work.g_w, &thewin -> work.g_h);
X
X		thewin -> fullsize = TRUE;
X	}
X}
X
X
X/*
X	do_update - Update all of the rectangles affected by the update event.
X*/
Xdo_update(message)
X	int *message;
X{
X	int	 thewindow;
X	GRECT r1, therect;
X
X	thewindow = message[3];
X
X	rect_set(&therect, message[4], message[5], message[6], message[7]);
X
X	wind_get(thewindow, WF_FIRSTXYWH, &r1.g_x, &r1.g_y, &r1.g_w, &r1.g_h);
X
X	while (r1.g_w && r1.g_h) {
X		if (rect_intersect(therect, r1, &r1))
X		{
X			setclip(thewindow, &r1);
X			redraw_vslider(thewindow);
X			update_window(thewindow);
X		}
X
X		wind_get(thewindow, WF_NEXTXYWH, &r1.g_x, &r1.g_y, &r1.g_w, &r1.g_h);
X	}
X
X	{
X		int x, y, w, h;
X
X		/*
X			Restore clip rectangle of the desktop rectangle.
X		*/
X		wind_get(0, WF_WORKXYWH, &x, &y, &w, &h);
X		rect_set(&r1, x, y, x+w, y+h);
X		vs_clip(phys_handle, 1, &r1);
X	}
X}
X
X
X/*
X	update_window  -  execute the update procedure associated with the window.
X*/
Xupdate_window(windhandle)
X	int			windhandle;
X{
X	windowptr	thewin;
X
X	thewin = findwindowptr(windhandle);
X
X	(*thewin -> updateproc)(thewin,1);
X}
X
X
X/*
X	setclip  -  set the windows clipping rectangle.
X*/
Xsetclip(thewindow, r1)
X	int   thewindow;
X	GRECT *r1;
X{
X	GRECT cliprect;
X	int  grafhandle;
X
X	grafhandle = findwindowptr(thewindow) -> graf.handle;
X
X	rect_set(&cliprect, r1->g_x, r1->g_y, r1->g_x+r1->g_w-1, r1->g_y+r1->g_h-1);
X
X	vs_clip(grafhandle, 1, &cliprect);
X}
X
X
X/*
X				Window support routines.
X*/
X
X/*
X	findwindowptr  -  find the window record associated with the window
X		handle and return a pointer to that window record.
X*/
Xwindowptr findwindowptr(handle)
X	int handle;
X{
X	register windowptr thewin = firstwindow;
X    int button;
X
X	for (thewin = firstwindow; thewin; thewin = thewin -> next)
X/* tricky for-loop.  When thewin becomes a NULL the loop terminates  */
X		if (thewin -> handle == handle)
X			break;
X
X	if (!thewin) {
X		button = form_alert(1, "[1][ Internal Error: | No window found for handle ][OK]");
X		shutdown(2);
X	}
X
X	return thewin;
X}
X
X
X/*
X	new_window  -  create & draw a new window.
X
X	1.)  create the window.
X	2.)  draw the window with the wind_open()
X	3.)  create and setup the window record.
X*/
Xwindowptr new_window(thekind)
X	int			thekind;
X{
X	int			handle, button, dummy, i;
X	int			xdesk, ydesk, wdesk, hdesk;
X	windowptr	thewin;
X	static		window_count = 1;
X
X	/*
X		Get the desktop coordinates.
X	*/
X	wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
X
X	/*
X		Create the information for the window.  Max size is the desktop.
X	*/
X	handle = wind_create(thekind, xdesk, ydesk, wdesk, hdesk);
X
X	/*
X		Check for error.
X	*/
X	if (handle < 0) {
X		button = form_alert(1, "[1][ Sorry! | No more windows available. ][OK]");
X		return NULL;
X	}
X
X	/*
X		Allocate space for window record.
X	*/
X	thewin				  = (windowptr) malloc(sizeof(windowrec));
X	if (thewin == NULL)
X	{	button = form_alert(1, "[1][ Sorry! | Out of memory creating window. ][OK]");
X		wind_delete(handle); /* delete the window created above  */
X		return NULL;
X	}
X 
X
X	/*
X		Initialize window data structure.
X	*/
X	thewin -> next		  = NULL;
X	thewin -> handle	  = handle;
X	thewin -> kind		  = thekind;
X	thewin -> fullsize	  = TRUE;
X	thewin -> graf.handle = open_vwork(&thewin -> graf.mfdb);
X	strcpy(thewin->title,"untitled");
X	strcpy(fs_insel,"untitled");
X	wind_set(thewin->handle, WF_NAME, thewin -> title, 0, 0);
X
X /* set text alignment to bottom left  for all windows   */
X   vst_alignment(thewin->graf.handle,0,3,&dummy,&dummy);
X
X	thewin -> updateproc  = one_page;
X
X	thewin -> headptr	  = NULL;
X	thewin -> startmark   = 1;
X	thewin -> endmark	  = 0;
X	thewin -> markson     = FALSE;
X	thewin -> xcur		  = 0;
X	thewin -> ycur		  = 0;
X	thewin -> topchar	  = 0;
X	thewin -> flen		  = 0;
X	thewin -> position	  = 0;
X	thewin -> vslidepos   = 0;
X	thewin -> icount	  = 0;
X	thewin -> changed	  = 0;	
X
X	/*
X		Insert into windowlist.
X	*/
X	{
X		register windowptr	winptr = (windowptr) &firstwindow;  
X
X/* firstwindow is a pointer to the first windowrec in the linked list and  */
X/* is initialized to NULL.  Since the first thing in a windowrec is 	  */
X/* 'next', the pointer to the next windowrec, then 						 */
X/* '(windowptr)&firstwindow->next' or windptr->next starts at firstwindow */
X/* What a kludge to save a bit of code!  Below is some commented out      */
X/* tested code that is clearer.                                           */
X/*      if(!firstwindow)
X          firstwindow = thewin;  
X        else					
X        {   winptr = firstwindow;  
X     		while(winptr -> next) 
X			winptr = winptr -> next;
X		winptr -> next = thewin;
X        }
X        
X*/        
X		while(winptr -> next) 
X			winptr = winptr -> next;
X	
X		winptr -> next = thewin;
X	}   
X		return(thewin);
X}
X
X
Xopen_window(thewin)
X	windowptr	thewin;
X
X{	int			xdesk, ydesk, wdesk, hdesk;
X
X	/*
X		Get the desktop coordinates.
X	*/
X	wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
X
X	/*
X		A little flim-flammery.
X	*/
X	graf_growbox(0, 0, 0, 0, xdesk, ydesk, wdesk, hdesk);
X
X	/*
X		Draw the window.
X	*/
X	wind_open(thewin->handle, xdesk, ydesk, wdesk, hdesk);
X
X	wind_get(thewin->handle, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
X	rect_set(&thewin -> work, xdesk, ydesk, wdesk, hdesk);
X
X	wind_get(thewin->handle, WF_CURRXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
X	rect_set(&thewin ->  box, xdesk, ydesk, wdesk, hdesk);
X
X
X	make_frontwin(thewin);
X
X}
X
X/*
X	dispose_window - Closes the window and disposes the storage for
X		the window record.
X*/
Xdispose_window(thewin)
X	windowptr	thewin;
X{
X	int x, y, w, h;
X	int handle;
X
X	handle = thewin -> handle;
X
X
X	wind_close(handle);
X
X	wind_get(handle, WF_CURRXYWH, &x, &y, &w, &h);
X
X	graf_shrinkbox(0, 0, 0, 0, x, y, w, h);
X
X	dispose_win_resources(thewin);
X
X}
X
Xdispose_win_resources(thewin)
X	windowptr	thewin;
X{
X		/*
SHAR_EOF
echo "End of part 2, continue with part 3"
echo "3" > s2_seq_.tmp
exit 0