📄 winp.c
字号:
/* CXL - Copyright (c) 1987-1989 by Mike Smedley - All Rights Reserved */
/* WINP.C - winpbeg() defines a window input form record
winpdef() defines a window input field record
winpread() reads all defined input fields for current form */
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "cxldef.h"
#include "cxlkey.h"
#include "cxlstr.h"
#include "cxlvid.h"
#include "cxlwin.h"
/* function prototypes */
static void adv_column(struct _form_t *cform,int col);
static void after_edit(struct _form_t *cform);
static void back_space(struct _form_t *cform);
static void beg_pos(struct _form_t *cform);
static void call_func(void (*func)(void));
static void check_format(char *format,int *lenfld,int *lenbuf,
int *decpos);
static void check_redisp(struct _form_t *cform);
static int closest_column(struct _form_t *cform,
struct _field_t *field);
static int cond_update(struct _form_t *cform);
static void deci_left(struct _form_t *cform,char *start);
static void deci_right(struct _form_t *cform,char *start);
static void del_char(struct _form_t *cform);
static void del_field(struct _form_t *cform,char *start,int high);
static void del_left_word(struct _form_t *cform);
static void del_rest(struct _form_t *cform);
static void del_word(struct _form_t *cform);
static void disp_char(struct _form_t *cform,int ch,int advance);
static void disp_field(struct _form_t *cform,char *start,int high);
static void down_field(struct _form_t *cform);
static void end_line(struct _form_t *cform);
static void end_pos(struct _form_t *cform);
static struct _field_t *first_rec(struct _form_t *cform);
static void free_fields(struct _form_t *cform);
static int goto_field(struct _form_t *cform,int which);
static void insert_char(struct _form_t *cform);
static struct _field_t *last_rec(struct _form_t *cform);
static void next_fchar(struct _form_t *cform);
static void next_pos(struct _form_t *cform);
static struct _field_t *next_rec(struct _form_t *cform);
static void next_word(struct _form_t *cform);
static void prev_fchar(struct _form_t *cform);
static void prev_pos(struct _form_t *cform);
static struct _field_t *prev_rec(struct _form_t *cform);
static void prev_word(struct _form_t *cform);
static void restore_field(struct _form_t *cform,int high);
static void set_term_key(struct _form_t *cform,unsigned xch);
static void up_field(struct _form_t *cform);
static int validate_field(struct _form_t *cform);
/* field movement definitions */
#define FLD_FR 0
#define FLD_LS 1
#define FLD_PR 2
#define FLD_NR 3
#define FLD_UP 4
#define FLD_DN 5
/* array of function pointers to some of the field movement functions */
static struct _field_t *(*funcs[6])(struct _form_t *) =
{ first_rec,last_rec,prev_rec,next_rec };
/*---------------------------------------------------------------------------*/
int winpbeg(int fieldattr,int textattr)
{
struct _form_t *form;
/* check for active window */
if(!_winfo.total) return(_winfo.errno=W_NOACTIVE);
/* allocate space for new input form record */
if((form=malloc(sizeof(struct _form_t)))==NULL)
return(_winfo.errno=W_ALLOCERR);
/* add new form record to linked list */
if(_winfo.active->form!=NULL)
_winfo.active->form->next=form;
form->prev=_winfo.active->form;
form->next=NULL;
_winfo.active->form=form;
/* adjust attributes if monochrome mapping is on */
textattr=mapattr(textattr);
fieldattr=_vinfo.mapattr?revsattr(textattr):fieldattr;
/* save info in new form record */
form->field = NULL;
form->getkey = NULL;
form->termkey = NULL;
form->decimal =
form->insert = OFF;
form->textattr = textattr;
form->fieldattr = fieldattr;
/* return with no error */
return(_winfo.errno=W_NOERROR);
}
/*---------------------------------------------------------------------------*/
int winpdef(int wrow,int wcol,char *str,char *format,int fconv,int mode,
int (*validate) (char *),int help)
{
int lenbuf,lenfld,decpos;
char *buf;
struct _field_t *field;
/* check and see if winpbeg() was called */
if(_winfo.active->form==NULL) return(_winfo.errno=W_NOFRMBEG);
/* try to set cursor coordinates - check for active window */
if(wgotoxy(wrow,wcol)) return(_winfo.errno);
/* get length of input field and syntax check format string */
check_format(format,&lenfld,&lenbuf,&decpos);
if(!lenbuf) return(_winfo.errno=W_INVFORMT);
/* if field is in update mode, adjust input */
/* string size to match "size" of input buffer */
if(mode) strsetsz(str,lenbuf);
/* allocate space for buffer */
if((buf=malloc(lenbuf+1))==NULL) return(_winfo.errno=W_ALLOCERR);
/* allocate space for new input field record */
if((field=malloc(sizeof(struct _field_t)))==NULL)
return(_winfo.errno=W_ALLOCERR);
/* add new record to linked list */
if(_winfo.active->form->field!=NULL)
_winfo.active->form->field->next=field;
field->prev=_winfo.active->form->field;
field->next=NULL;
_winfo.active->form->field=field;
/* if not updating, then initialize receiving string to spaces */
if(!mode) {
memset(str,' ',lenbuf);
*(str+lenbuf)='\0';
}
/* initialize temp buffer to string contents */
strcpy(buf,str);
/* save input field record */
field->wrow = wrow;
field->wcol = wcol;
field->str = str;
field->buf = buf;
field->format = format;
field->fconv = fconv;
field->mode = mode;
field->validate = validate;
field->lenfld = lenfld;
field->lenfmt = strlen(format);
field->lenbuf = lenbuf;
field->decpos = decpos;
field->help = help;
field->redisp = OFF;
field->before =
field->after = NULL;
/* set current field pointer to new field record */
_winfo.active->form->cfield=field;
/* if numeric field, format accordingly */
if(fconv=='9') deci_right(_winfo.active->form,buf+lenbuf);
/* display input field */
disp_field(_winfo.active->form,NULL,0);
/* return with no error */
return(_winfo.errno=W_NOERROR);
}
/*---------------------------------------------------------------------------*/
int winpread(void)
{
struct _form_t *cform;
struct _field_t *cfield,*temp;
char *p;
int valid,ch,edit,done;
unsigned int xch;
/* check for active window */
if(!_winfo.total) return(_winfo.errno=W_NOACTIVE);
/* abbreviate pointer to current form */
cform=_winfo.active->form;
/* check and see if winpbeg() was called */
if(cform==NULL) return(_winfo.errno=W_NOFRMBEG);
/* check for defined input fields */
if(cform->field==NULL) return(_winfo.errno=W_NOINPDEF);
/* go to 1st position of first field */
cform->cfield=first_rec(cform);
beg_pos(cform);
/* set help category to 1st field's help category */
_winfo.help=cform->cfield->help;
/* call 1st field's before function */
call_func(cform->cfield->before);
/* if conditional update, then start cursor end of line */
edit=cond_update(cform);
/* initialize Insert mode to OFF */
cform->insert=OFF;
smcursor();
/* initially display field */
disp_field(cform,NULL,1);
for(;;) {
/* set cursor coordinates */
wgotoxy(cform->cwrow,cform->cwcol);
/* If alternate getkey function was provided, call it. */
/* Otherwise call the standard CXL getxch() function */
/* If alternate getkey function returned "done" flag, */
/* then set termination key variable and exit function */
if(cform->getkey!=NULL) {
done=NO;
xch=(*(cform->getkey))(&done);
if(done) {
set_term_key(cform,xch);
goto form_done;
}
}
else
xch=getxch();
/* test keypress */
switch(xch) {
case 0x011b: /* Esc */
/* if Esc checking is on, restore all fields to their */
/* original values, free input records, and exit */
if(_winfo.esc) {
after_edit(cform);
for(cform->cfield=cform->field;cform->cfield!=NULL;
cform->cfield=cform->cfield->prev)
restore_field(cform,0);
free_fields(cform);
set_term_key(cform,xch);
return(_winfo.errno=W_ESCPRESS);
}
break;
case 0x1c0a: /* Ctrl-Enter */
set_term_key(cform,xch);
goto form_done;
case 0x1c0d: /* Enter */
/* abbreviate pointer to current field */
cfield=cform->cfield;
/* if field is numeric, then format it so */
if(cfield->fconv=='9')
deci_right(cform,((cform->pbuf==cfield->buf)) ?
(cfield->buf+cfield->lenbuf) : cform->pbuf);
/* if we are at last field, validate it, */
/* then copy temp buffers to receiving */
/* buffers, free input records, and exit */
if(cform->cfield==last_rec(cform)) {
set_term_key(cform,xch);
form_done:
if(validate_field(cform)) break;
after_edit(cform);
cform->cfield=cform->field;
while(cform->cfield!=NULL) {
strcpy(cform->cfield->str,cform->cfield->buf);
cform->cfield=cform->cfield->prev;
}
free_fields(cform);
return(_winfo.errno=W_NOERROR);
}
/* fall through to Tab */
case 0x0f09: /* Tab */
/* if field is valid, display it, go */
/* to next field, first position. if */
/* conditional update feature is on, then */
/* position cursor at end of line */
if(!goto_field(cform,FLD_NR)) {
beg_pos(cform);
if((edit=cond_update(cform))==NO) continue;
}
break;
case 0x0e08: /* BackSpace */
/* if currently at 1st position of 1st field, ignore. */
/* otherwise, display a destructive backspace */
if(!( (cform->pbuf==cform->cfield->buf) &&
(cform->cfield==first_rec(cform)) )) back_space(cform);
break;
case 0x4700: /* Home */
/* go to first position in field */
beg_pos(cform);
break;
case 0x0f00: /* Shift-Tab */
/* if field is valid, display it, go to */
/* previous field, first position. if */
/* conditional update feature is on, then */
/* position cursor at end of line */
if(!goto_field(cform,FLD_PR)) {
beg_pos(cform);
if((edit=cond_update(cform))==NO) continue;
}
break;
case 0x4800: /* UpArrow */
/* if field is valid, display it, and */
/* move cursor up to previous field */
goto_field(cform,FLD_UP);
break;
case 0x4b00: /* LeftArrow */
/* go to previous position in field */
prev_pos(cform);
break;
case 0x4d00: /* RightArrow */
/* go to next position in field */
next_pos(cform);
break;
case 0x4f00: /* End */
/* go to last position in field */
end_line(cform);
break;
case 0x5000: /* DownArrow */
/* if field is valid, display it, and */
/* move cursor down to next field */
goto_field(cform,FLD_DN);
break;
case 0x5200: /* Ins */
/* toggle Insert mode */
if(cform->insert) {
cform->insert=OFF;
smcursor();
}
else {
cform->insert=ON;
lgcursor();
}
break;
case 0x5300: /* Del */
/* delete character under cursor */
del_char(cform);
break;
case 0x7500: /* Ctrl-End */
/* if field is valid, display it, then */
/* go to last position of last field */
if(!goto_field(cform,FLD_LS)) end_pos(cform);
break;
case 0x7700: /* Ctrl-Home */
/* if field is valid, display it, then */
/* go to first position of first field */
if(!goto_field(cform,FLD_FR)) beg_pos(cform);
break;
case 0x0e7f: /* Ctrl-BackSpace */
/* delete word to left of cursor */
del_left_word(cform);
break;
case 0x1312: /* Ctrl-R */
/* restore field to original contents */
restore_field(cform,1);
break;
case 0x1414: /* Ctrl-T */
/* delete word to right of cursor */
del_word(cform);
break;
case 0x1615: /* Ctrl-U */
/* delete from cursor to end of field */
del_field(cform,cform->pbuf,1);
break;
case 0x1519: /* Ctrl-Y */
/* delete from cursor to end of last field */
del_rest(cform);
break;
case 0x7300: /* Ctrl-LeftArrow */
/* move cursor to previous word to the left */
prev_word(cform);
break;
case 0x7400: /* Ctrl-RightArrow */
/* move cursor to next word to the right */
next_word(cform);
break;
case 0x342e: /* Period */
case 0x532e: /* Shift-Del (decimal) */
/* if field is numeric, right justify, space fill */
/* digits to the left of the decimal point, and */
/* move cursor to position after decimal point */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -