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