📄 cflib.c
字号:
/***************************************************************************** * * C F O R M S . C * --------------- * * Description: * * Included functions: * * Misc functions * -------------- * cforms_end - Stop CForms * cforms_init - Initiate CForms * cforms_refresh - Refresh the CForms screen. * cforms_system - Call the operating system * * Picture functions * ----------------- * pic_call - Call picture * pic_clear - Clear all fields for picture * pic_leave - Leave current picture * picture - Get picture with name * * Field functions * --------------- * field - Get field with name * fld_isempty - Check if field is empty * fld_first - Find first field of picture * fld_next - Find next field for picture * fld_previous - Find previous field for picture * fld_left - Find left field * fld_right - Find right field * fld_up - Find field above current * fld_down - Find field below current * fld_set - Set value for field * fld_nset - Set value for field but max n chars * fld_get - Get value of field * fld_len - Return length of field * fld_name - Return name of field * fld_ismodified - Return true if field has been modified since fld_set * fld_sattr - Set attributes for field. * fld_cattr - Clear attributes for field. * fld_touch - Make field not modified * * General functions * ----------------- * message - Give message (line 24) * strequ - Compqare two strings, but case insensitive * * Local functions * --------------- * hdl_field - This is the head function for cforms * getraw - Get raw key * draw_picture - Draw picture with fields * draw_field - Draw field. * check_int - Checkfunction for integer fields * check_alnum - -''- alphanumeric fields * check_char - -''- character fields * adjust_right - Adjust string to right * generate_event - Raise event and call event functions and handle * if field is moved. * raw_event - Raise event and call event functions * * Global variables: * none * * Revision: * Ver Date By Reason * --- ---- -- ------ * 1.00 900629 Lars Berntzon Created * ****************************************************************************/ #ifndef lintstatic volatile char sccs_id[] = "@(#) cflib.c,v 1.23 1993/07/21 01:15:18 lasse Exp";#endif#include "config.h"#include "cforms.h"#define KEY_CTRL(c) (toupper(c) - 'A' + 1)#ifndef ACS_ULCORNER#define ACS_ULCORNER '+'#endif#ifndef ACS_LLCORNER#define ACS_LLCORNER '+'#endif#ifndef ACS_URCORNER#define ACS_URCORNER '+'#endif#ifndef ACS_LRCORNER#define ACS_LRCORNER '+'#endif#ifndef ACS_HLINE#define ACS_HLINE '-'#endif#ifndef ACS_VLINE#define ACS_VLINE '|'#endif /* G l o b a l v a r i a b l e s */struct global _cf_globals; /* Current field and picture */ /* L o c a l v a r i a b l e s */#ifdef SIGNAL_INTstatic int sigcatch(int sig);#elsestatic void sigcatch(int sig);#endifstatic int _message(const char *fmt, va_list arg);static int check_int(int *ch, char *txt, int *pos, int len);static int check_alnum(int *ch, char *txt, int *pos, int len);static int check_char(int *ch, char *txt, int *pos, int len);static int draw_picture(struct picture *pic);static void draw_field(struct field *fld);static void move_to_field(struct field *fld);static int hdl_field(struct field *fld);static int adjust_right(char *txt, int len);static void debug(char *fmt, ...);static int generate_event(int ev_type, int ev_spec, int ev_code);static int raw_event(int ev_type, int ev_spec, int ev_code);static struct picture *pstack[200];static int pstackp = 0;static int cforms_inited = FALSE;/****************************************************************************** * * C F O R M S _ I N I T * --------------------- * Description: * Initialize cforms. (currently only initscr). * *****************************************************************************/intcforms_init(void){ int pic, fld; int m; cforms_inited = TRUE; signal(SIGINT, sigcatch); if (initscr() == NULL) { return FAIL; } keypad(stdscr,TRUE); /* * Save picture pointer for every field. */ for(m = 0; _cf_modules[m] != NULL; m++) { for(pic = 0; pic < _cf_modules[m]->n_pictures; pic++) { for(fld = 0; fld < _cf_modules[m]->picture[pic].n_fields; fld++) { _cf_modules[m]->picture[pic].field[fld].picture = &_cf_modules[m]->picture[pic]; } } } raw(); noecho(); /* * Set up some default keys for field editing. */ _cf_globals.bs = '\b'; _cf_globals.del1 = 'D' & 0x1F; _cf_globals.del2 = 127; _cf_globals.kill = 'K' & 0x1F; _cf_globals.clear = 'U' & 0x1F; return OK;}/****************************************************************************** * * C F O R M S _ E N D * ------------------- * * Description: * Turns off cforms. * *****************************************************************************/intcforms_end(void){ cforms_inited = FALSE; move(23, 1); refresh(); endwin(); return OK;}/****************************************************************************** * * C F O R M S _ R E F R E S H * --------------------------- * * Description: * Refresh the CForms application window. * *****************************************************************************/voidcforms_refresh(void){ int i; clear(); for(i = 0; i < pstackp; i++) { debug("drawing picture %d", i); draw_picture(pstack[i]); } generate_event(EVENT_REFRESH, 0, 0);}/******************************************************************************* * * C F O R M S _ S Y S T E M * ------------------------- * * * Description: * Execute an operating system command from CForms without destroying * the screen. * * * Input: * command - OS command to execute. * * Return: * Integer return value from system command. * ******************************************************************************/intcforms_system(const char *command, const char *prompt){ int result; char ch; if (command == NULL) { return 0; } /* * Clean the picture. */ clear(); refresh(); endwin(); putenv("IFS= \t\n"); /* Make system() a bit more secure */ result = system(command); if (prompt != NULL) { write(1, prompt, strlen(prompt)); while(read(0, &ch, 1) == 1 && ch != '\n') ; } initscr(); keypad(stdscr,TRUE); cforms_refresh(); return result;}/******************************************************************************* * * P I C _ C A L L * --------------- * * * Description: * This is the entry point for application into CForms * * Input: * pic - Picture to call * field_name - Name of field to start at, (NULL means first field). * * Global: * _cf_globals.picture - Is set up to point to this picture * ******************************************************************************/intpic_call(struct picture *pic, const char *field_name){ struct global old_globals = _cf_globals; if (cforms_inited == FALSE) { fprintf(stderr, "** CForms not initialized **\n"); return FAIL; } if (pic == NULL) return FAIL; _cf_globals.picture = pic; _cf_globals.field = NULL; /* * Keep track of how pictures are stacked in case of a refresh * is orderded from keyboard. */ pstack[pstackp++] = pic; /* * Paint the new picture. */ draw_picture(pic); /* * The event draw is special in that it is only valid for pictures. */ generate_event(EVENT_DRAW, 0, 0); /* * If field is still not set in EVENT_DRAW, go to proper one. */ if (_cf_globals.field == NULL) { if (field_name) move_to_field(field(field_name)); else move_to_field(fld_first()); } /* * Make sure there really exists a field to move to in * picture. */ if (_cf_globals.field != NULL) { while(_cf_globals.leave_picture == FALSE) { hdl_field(_cf_globals.field); } generate_event(EVENT_EXIT, 0, 0); } /* * Redraw the picture picture that was active before * this one was called and make that old one active again. */ _cf_globals = old_globals; if (_cf_globals.picture) { draw_picture(_cf_globals.picture); generate_event(EVENT_REFRESH, 0, 0); } pstackp--; return OK;}/******************************************************************************* * * P I C T U R E * ------------- * * Description: * Finds a picture with name as described by arguments in printf format. * ******************************************************************************/struct picture *picture(const char *fmt, ...){ static char pic_name[100]; va_list arg; int i; int m; va_start(arg, fmt); vsprintf(pic_name, fmt, arg); va_end(arg); /* * Loop through all modules and their pictures * to find name. */ for(m = 0; _cf_modules[m] != 0; m++) { for(i = 0; i < _cf_modules[m]->n_pictures; i++) { if (strequ(pic_name, _cf_modules[m]->picture[i].name) == 0) { return &_cf_modules[m]->picture[i]; } } } return NULL;}/******************************************************************************* * * P I C _ L E A V E * ----------------- * * Description: * Leave picture uppon exit of current event. * ******************************************************************************/intpic_leave(void){ _cf_globals.leave_picture = TRUE; return OK;}/******************************************************************************* * * P I C _ C L E A R * ----------------- * * Description: * Clear all field of picture 'pic'. * ******************************************************************************/intpic_clear(struct picture *pic){ int i, n; if (pic == NULL) pic = _cf_globals.picture; if (pic == NULL) return FAIL; for(i = 0; i < pic->n_fields; i++) { pic->field[i].data[0] = 0; } if (_cf_globals.picture == pic) { for(i = 0; i < pic->n_fields; i++) { move(pic->field[i].pos.y + pic->y, pic->field[i].pos.x + pic->x); for(n = 0; n < pic->field[i].len; n++) { addch(' '); } } } return OK;}/******************************************************************************* * * H D L _ F I E L D * ----------------- * * Description: * Handles the intput of one field. When ever a event is generated * this function returns to pic_call which should handle the results * of this event. Also when a field is moved this function will return. * * Arguments: * fld - Pointer to field to handle. * ******************************************************************************/static inthdl_field(struct field *fld){ int (*check_p)(); int x, y, ch, i, pos = 0; struct field *tmp_fld; move((y = fld->pos.y) + fld->picture->y, (x = fld->pos.x) + fld->picture->x); /* * Setup which function to handle key input to field. */ switch(fld->type & FLD_TYPE) { case FLD_CHAR: check_p = check_char; break; case FLD_ALNUM: check_p = check_alnum; break; case FLD_INT: check_p = check_int; break; default: message("Illegal field type, probably a bug in CForms"); } /* * Pad field with spaces after null. */ i = strlen(fld->data); memset(fld->data + i, ' ', fld->len - i); fld->data[fld->len] = 0; /* * Handle keys pressed by user. */ while (refresh(), (ch = getch()) != EOF) { message_nr(""); /* * Second try to generated an event for the key pressed. */ if (generate_event(EVENT_KEY, KEY_ANY, ch)) { break; } /* * Second try to generated an event for the key pressed. */ else if (generate_event(EVENT_KEY, ch, ch)) { break; } /* * If CTRL-W then do refresh. */ else if (ch == KEY_CTRL('w')) { cforms_refresh(); } /* * If newline adjust the field if it should be. */ else if (ch == '\n') { if (fld->type & FLD_RIGHT) { adjust_right(fld->data, fld->len); } } /* * Move one pos left. */ else if (ch == KEY_LEFT) { if (pos <= 0 || (fld->flags & FLD_PROTECTED)) { if (generate_event(EVENT_PREVIOUS, 0, 0)) { break; } else if (tmp_fld = fld_left(_cf_globals.field)) { move_to_field(tmp_fld); break; } else message("Can't move left"); } else { pos--; } } /* * Move one pos right. */ else if (ch == KEY_RIGHT) { if (pos >= fld->len - 1 || (fld->flags & FLD_PROTECTED)) { if (generate_event(EVENT_NEXT, 0, 0)) { break; } else if (tmp_fld = fld_right(_cf_globals.field)) { move_to_field(tmp_fld); break; } else message("Can't move right"); } else { pos++; } } /* * From here on data in the field is actually modified, * unless if protected in case it is not allowed. */ else if (fld->flags & FLD_PROTECTED) { message("No input allowed"); } /* * Backspace. */ else if (ch == _cf_globals.bs) { if (pos > 0) { for(i = pos; i < fld->len; i++) { fld->data[i - 1] = fld->data[i]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -