home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
formge.arj
/
IOED.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-04-18
|
18KB
|
454 lines
#include <alloc.h>
#include <dos.h>
#include <mem.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "iolib.h"
/*=========================================================================*/
/* ioed.c -- library of i/o functions for use from Turbo C */
/* part II : the editor-in-a-box */
/* by John Queern, Belleville, IL (public domain) */
/*=========================================================================*/
/* NOTE: you must also link in iolib.obj if using ioed */
/* function prototypes */
void do_help (void); /* box editor help */
void redraw (char *edscreen,int sx, /* draw/redraw editor data */
int sy, int wid, int lines); /* */
int edit (char *edscreen,int sx, /* editor-in-a-box */
int sy, int *px, int *py, int wid,
int lines);
typedef struct BOX_CHARSET {
char bul; /* box upper left */
char bh; /* box horiz */
char bhc; /* box upper horizontal with cross */
char bhlc; /* box lower horizontal with cross */
char bur; /* box upper right */
char bv; /* box vertical */
char blvc; /* box left vertical with cross */
char brvc; /* box right vertical with cross */
char bll; /* box lower left */
char bc; /* box cross */
char blr; /* box lower right */
} BOXCHARS;
BOXCHARS *get_boxchar(void); /* (fncn for internal use) */
BOXCHARS single = { '┌','─','┬','┴','┐','│','├','┤','└','┼','┘'};
BOXCHARS duble = { '╔','═','╦','╩','╗','║','╠','╣','╚','╬','╝'};
BOXCHARS sindub = { '╒','═','╤','╧','╕','│','╞','╡','╘','╪','╛'};
BOXCHARS dubsin = { '╓','─','╥','╨','╖','║','╟','╢','╙','╫','╜'};
BOXCHARS ascii = { '+','-','+','+','+','|','+','+','+','+','+'};
BOXCHARS half1 = { '░','░','░','░','░','░','░','░','░','░','░'};
BOXCHARS half2 = { '▒','▒','▒','▒','▒','▒','▒','▒','▒','▒','▒'};
BOXCHARS half3 = { '▓','▓','▓','▓','▓','▓','▓','▓','▓','▓','▓'};
BOXCHARS solid = { '█','█','█','█','█','█','█','█','█','█','█'};
BOXCHARS *box = &single; /* box char pointer, default style */
/*========================================================================*/
void do_help (void)
/* help screen for the editor */
{
char ch;
savescreen(1);
bclear(0);
bwrite(0,5,2, "╔═════════════════════════════════════════════════════════════════════╗");
bwrite(0,5,3, "║ EDIT HELP SCREEN ║");
bwrite(0,5,4, "║ F1 - show this help screen ║");
bwrite(0,5,5, "║ Home - goto line 1, column 1 ║");
bwrite(0,5,6, "║ ^e PgUp, ^r - goto top ║");
bwrite(0,5,7, "║ PgDn, ^c - goto bottom ║");
bwrite(0,5,8, "║ ^ End, ^w - save changes, exit ║");
bwrite(0,5,9, "║ | Ins, ^v - toggle insert mode ║");
bwrite(0,5,10,"║ | Del, ^g - delete one character ║");
bwrite(0,5,11,"║ ^s <----o----> ^d Tab, ^i - goto next tab position ║");
bwrite(0,5,12,"║ | ^y - delete line ║");
bwrite(0,5,13,"║ | ^z - blank everything ║");
bwrite(0,5,14,"║ v ^t - delete word right ║");
bwrite(0,5,15,"║ ^a/^f - advance word left/right ║");
bwrite(0,5,16,"║ ^x ^qs/^qd - goto beginning/end of line ║");
bwrite(0,5,17,"║ ^n - insert line ║");
bwrite(0,5,18,"║ Cursor Movement ^b/^u, F7/F8 - generate/erase a box ║");
bwrite(0,5,19,"║ (or use cursor keys) F6 - change box character set ║");
bwrite(0,5,20,"║ F9/F10 - horiz/vert line draw/erase ║");
bwrite(0,5,21,"║ Note: ^ = hold Ctrl ║");
bwrite(0,5,22,"╚═════════════════════════════════════════════════════════════════════╝");
bwrite(0,5,24,"Press any key to continue editing...");
restorescreen(0);
getch();
restorescreen(1);
}
/*========================================================================*/
BOXCHARS *get_boxchar(void)
/* display box character set options, & return pointer to selected set */
{
int i,j;
char ch;
BOXCHARS *b;
savescreen(1);
savescreen(0);
bwrite(0,5,2, "╔══════════════════════════════════╗");
bwrite(0,5,3, "║ Box Character Selection: ║");
bwrite(0,5,4, "║ ║");
bwrite(0,5,5, "║ ┌───┐ ║");
bwrite(0,5,6, "║ a. single │╔═══╗ ║");
bwrite(0,5,7, "║ b. double └║╒═══╕ ║");
bwrite(0,5,8, "║ c. sing/doub ╚│╓───╖ ║");
bwrite(0,5,9, "║ d. doub/sing ╘║+---+ ║");
bwrite(0,5,10,"║ e. ascii ╙|░░░░░ ║");
bwrite(0,5,11,"║ f. half1 +░▒▒▒▒▒ ║");
bwrite(0,5,12,"║ g. half2 ▒▓▓▓▓▓ ║");
bwrite(0,5,13,"║ h. half3 ▓█████ ║");
bwrite(0,5,14,"║ i. solie █████ ║");
bwrite(0,5,15,"║ ║");
bwrite(0,5,16,"║ Selection (a-i)? ║");
bwrite(0,5,17,"║ ║");
bwrite(0,5,18,"╚══════════════════════════════════╝");
restorescreen(0);
gotoxy(26,16);
fflush(stdin);
ch=getche();
ch=tolower(ch);
switch (ch) {
case 'a': b=&single; break;
case 'b': b=&duble; break;
case 'c': b=&sindub; break;
case 'd': b=&dubsin; break;
case 'e': b=&ascii; break;
case 'f': b=&half1; break;
case 'g': b=&half2; break;
case 'h': b=&half3; break;
case 'i': b=&solid;
}
restorescreen(1);
return(b);
}
/*========================================================================*/
void redraw (char *edscreen,int sx, int sy, int wid, int lines)
/* redraw internal part of screen */
/* NOTE: this routine uses screen buffer 1 */
{
int i;
savescreen(1);
for (i=0; i<lines; i++) pad(edscreen + i*wid+i,wid); /* pad lines */
for (i=0; i<lines; i++) bwrite(1,sx,i+sy,(edscreen + i*wid + i));
restorescreen(1);
}
/*========================================================================*/
int edit (char *edscreen,int sx, int sy, int *px, int *py, int wid, int lines)
/* editor in a box */
/* Initiate multiline editor using buffer edscreen, in a box at sx,sy;
edscreen is a buffer which must contain at least (lines*wid+lines) bytes;
The editor will assume it is set up as an array of <lines> strings,
each <wid> long; return special keys which aren't handled internally;
*/
{
char ch;
int a,b;
int i,j,n,retcd,_retcd;
int x,y,xx;
char *blank;
int inbox,inclear,savetrim;
char *lptr, *cptr, *lcptr, *tcptr, *bcptr;
blank=(char *)calloc(1,wid+1);
blank[0]=0;
pad(blank,wid);
_retcd=0;
inbox=inclear=insert=FALSE;
savetrim=trimblanks;
trimblanks=FALSE;
redraw(edscreen,sx,sy,wid,lines);
x=*px;
y=*py; /* x and y are relative--(0,0) is upper l.h. corner of box */
colx=coly=24;
do {
gotoxy(5,24);
cprintf("Row: %3d Column: %3d ",y+1,x+1);
gotoxy(45,24);
if (inbox) cprintf("<in box>");
else if (inclear) cprintf("<in clr>");
else cprintf(" ");
lptr=edscreen+y*wid+y; /* pointer to current line (line y) */
retcd=getstring(sx,sy+y,&x,lptr,wid);
cptr=lptr+x; /* pointer to char at cursor pos */
switch (retcd) {
case 0 :
case 1 :
x=0;
case 6 :
if (y<lines-1) y++;
else {
_retcd = retcd;
retcd = 8;
}
break;
case 3 :
if (y>0) y--;
else {
_retcd = retcd;
retcd = 8;
}
break;
case 11 : /* F1 */
do_help();
break;
case 16 : /* F6 */
box = get_boxchar();
break;
case 24 : /* Home */
y = 0;
x = 0;
break;
case 9 : /* PgUp */
y = 0;
break;
case 10: /* PgDn */
y = lines-1;
break;
case 17: /* F7 or */
case 25: /* ctrl-b (box) */
if (! inbox) {
/* save cursor position */
a=x; /* offset */
b=y;
inbox = TRUE;
}
/* already in box-- draw it */
else {
/* draw horizontal pieces */
bcptr=edscreen+y*wid+y+min(a,x);
tcptr=edscreen+b*wid+b+min(a,x);
for (i=min(a,x)+1;i<max(a,x);i++) {
*(++bcptr)=box->bh;
*(++tcptr)=box->bh;
}
/* draw vertical pieces */
bcptr=edscreen+min(y,b)*wid+min(y,b)+a;
tcptr=edscreen+min(y,b)*wid+min(y,b)+x;
for (i=min(b,y); i<=max(b,y)-1; i++) {
*bcptr=box->bv;
*tcptr=box->bv;
bcptr += wid + 1;
tcptr += wid + 1;
}
/* add corners */
*(edscreen+min(b,y)*wid+min(b,y)+min(a,x))=box->bul;
*(edscreen+max(b,y)*wid+max(b,y)+min(a,x))=box->bll;
*(edscreen+min(b,y)*wid+min(b,y)+max(a,x))=box->bur;
*(edscreen+max(b,y)*wid+max(b,y)+max(a,x))=box->blr;
inbox = FALSE;
x=a;
y=b;
redraw(edscreen,sx,sy,wid,lines);
}
break;
case 18: /* F8 or */
case 26: /* ctrl-u (box clear) */
if (! inclear) {
/* save cursor position */
a=x; /* offset */
b=y;
inclear = TRUE;
}
/* already in clear-- clear it */
else {
/* clear horizontal pieces */
bcptr=edscreen+y*wid+y+min(a,x);
tcptr=edscreen+b*wid+b+min(a,x);
for (i=min(a,x)+1;i<max(a,x);i++) {
*(++bcptr)=' ';
*(++tcptr)=' ';
}
/* clear vertical pieces */
bcptr=edscreen+min(y,b)*wid+min(y,b)+a;
tcptr=edscreen+min(y,b)*wid+min(y,b)+x;
for (i=min(b,y); i<=max(b,y)-1; i++) {
*bcptr=' ';
*tcptr=' ';
bcptr += wid + 1;
tcptr += wid + 1;
}
/* clear corners */
*(edscreen+min(b,y)*wid+min(b,y)+min(a,x))=' ';
*(edscreen+max(b,y)*wid+max(b,y)+min(a,x))=' ';
*(edscreen+min(b,y)*wid+min(b,y)+max(a,x))=' ';
*(edscreen+max(b,y)*wid+max(b,y)+max(a,x))=' ';
inclear = FALSE;
x=a;
y=b;
redraw(edscreen,sx,sy,wid,lines);
}
break;
case 19: /* F9 - draw horizontal line */
lcptr = cptr - 1; /* char to left of current pos */
tcptr = edscreen+(y-1)*wid+(y-1)+x; /* char above current */
bcptr = edscreen+(y+1)*wid+(y+1)+x; /* char below current */
/* fix up left hand connection if necessary */
if (*cptr==box->bh || *cptr==box->bc) { /* erasing a line? */
if (*lcptr==box->bul) *lcptr=box->bv;
else if (*lcptr==box->blvc) *lcptr=box->bv;
else if (*lcptr==box->blvc) *lcptr=box->bv;
else if (*lcptr==box->bhc) *lcptr=box->bur;
else if (*lcptr==box->bhlc) *lcptr=box->blr;
else if (*lcptr==box->bc) *lcptr=box->brvc;
}
else { /* adding a line? */
if (*lcptr==box->bv) {
if ((*(tcptr-1)==box->bv || *(tcptr-1)==box->bc
|| *(tcptr-1)==box->blvc)
&& (*(bcptr-1)==box->bv || *(bcptr-1)==box->bc
|| *(bcptr-1)==box->blvc))
*lcptr=box->blvc;
else if (*(tcptr-1)==box->bv || *(tcptr-1)==box->bc)
*lcptr=box->bll;
else if (*(bcptr-1)==box->bv || *(bcptr-1)==box->bc)
*lcptr=box->bul;
}
else if (*lcptr==box->bur) *lcptr=box->bhc;
else if (*lcptr==box->blr) *lcptr=box->bhlc;
else if (*lcptr==box->brvc) *lcptr=box->bc;
}
for (i=x; i<wid; i++) {
if (*cptr==box->bv) *cptr=box->bc;
else if (*cptr==box->bh) *cptr=' ';
else if (*cptr==box->brvc) *cptr=box->bv;
else if (*cptr==box->blvc) *cptr=box->bv;
else if (*cptr==box->bc) *cptr=box->bv;
else if (*cptr==box->bhlc) *cptr=box->bv;
else if (*cptr==box->bhc) *cptr=box->bv;
else *cptr=box->bh;
cptr++;
}
redraw(edscreen,sx,sy,wid,lines);
break;
case 20: /* F10 - draw vertical line */
lcptr = cptr - 1; /* char to left of current pos */
tcptr = edscreen+(y-1)*wid+(y-1)+x; /* char above current */
bcptr = edscreen+(y+1)*wid+(y+1)+x; /* char below current */
/* fix up upper connection if necessary */
if (*cptr==box->bv || *cptr==box->bc) { /* erasing a line? */
if (*tcptr==box->bur || *tcptr==box->bul
|| *tcptr==box->bhc) *tcptr=box->bh;
else if (*tcptr==box->blvc) *tcptr=box->bll;
else if (*tcptr==box->brvc) *tcptr=box->blr;
else if (*tcptr==box->bc) *tcptr=box->bhlc;
}
else { /* adding a line? */
if (*tcptr==box->bh) {
if ((*(tcptr-1)==box->bh || *(tcptr-1)==box->bc
|| *(tcptr-1)==box->bhc) &&
(*(tcptr+1)==box->bh || *(tcptr-1)==box->bc
|| *(tcptr+1)==box->bhc))
*tcptr=box->bhc;
else if (*(tcptr-1)==box->bh || *(tcptr-1)==box->bc)
*tcptr=box->bur;
else if (*(tcptr+1)==box->bv || *(tcptr+1)==box->bc)
*tcptr=box->bul;
}
else if (*tcptr==box->bll) *tcptr=box->blvc;
else if (*tcptr==box->blr) *tcptr=box->brvc;
else if (*tcptr==box->bhc) *tcptr=box->bc;
}
for (i=y; i<lines; i++) {
if (*cptr==box->bh) *cptr=box->bc;
else if (*cptr==box->bv) *cptr=' ';
else if (*cptr==box->bc) *cptr=box->bh;
else if (*cptr==box->blvc) *cptr=box->bh;
else if (*cptr==box->brvc) *cptr=box->bh;
else if (*cptr==box->bhlc) *cptr=box->bh;
else if (*cptr==box->bhc) *cptr=box->bh;
else *cptr=box->bv;
cptr += (wid + 1);
}
redraw(edscreen,sx,sy,wid,lines);
break;
case 21: /* ctrl-y */
for (i=y; i<lines-1; i++)
strcpy(edscreen+i*wid+i,edscreen+(i+1)*wid+i+1);
strcpy(edscreen+(lines-1)*wid+lines-1,blank);
redraw(edscreen,sx,sy,wid,lines);
break;
case 22: /* ctrl-z */
gotoxy(10,24);
clreol();
cprintf("Zap entire screen -- you sure (Y/N)?");
ch=getch();
ch=toupper(ch);
if (ch == 'Y') {
for (i=0; i<lines; i++) {
strcpy(edscreen+i*wid+i,blank);
}
y=1;
x=0;
redraw(edscreen,sx,sy,wid,lines);
}
else {
gotoxy(10,24);
clreol();
}
break;
case 23: /* ctrl-n */
for (i=lines-1; i>y; i--) strcpy(edscreen+i*wid+i,
edscreen+(i-1)*wid+i-1);
*(edscreen+y*wid+y+x)=0; /* cut orig line short */
if (y<lines-1) {
strdel(edscreen+(y+1)*wid+y+1,0,x);
pad(edscreen+y*wid+y,wid);
y++;
x=0;
}
redraw(edscreen,sx,sy,wid,lines);
break;
default: /* any other special keys */
_retcd=retcd;
retcd=8;
break;
} /* switch retcd */
}
while ((retcd != 7) && (retcd != 8));
gotoxy(1,24);
clreol();
colx=0;
coly=0;
trimblanks=savetrim;
if (trimblanks==TRUE)
for (i=0; i<lines; i++) trim(edscreen+i*wid+i); /* trim blanks */
*px = x; /* return position in box when leaving */
*py = y;
return(_retcd);
} /* edit */