home *** CD-ROM | disk | FTP | other *** search
- /* ==( memo/inputt.c )== */
-
- /* ----------------------------------------------- */
- /* Pro-C Copyright (C) 1989 - 1990 Vestronix Inc. */
- /* Modification to this source is not supported */
- /* by Vestronix Inc. */
- /* All Rights Reserved */
- /* ----------------------------------------------- */
- /* Written JPK 1-May-89 */
- /* Modified Geo 12-Dec-89 See comments below */
- /* ----------------------------------------------- */
- /* %W% (%H% %T%) */
-
- /*
- * Modifications
- *
- * 16-Dec-89 JH - rewrite of input masks, bug fixes
- * 12-Dec-89 Geo - V2 version
- *
- */
-
- /*
- * Inputt.c contains the routines to implement text field input. These include
- * mask validation, character input and validation and field formatting for
- * display.
- */
- # include <stdio.h>
- # include <bench.h>
- # include "field.h"
- # include <time.h>
-
- # ifndef MIN
- # define MIN(a,b) (a > b ? b : a)
- # endif
- # ifndef MAX
- # define MAX(a,b) (a < b ? b : a)
- # endif
-
- char InvalidEntry[] = "Invalid data entry - Please retry";
-
- /*
- # define INDEBUG
- */
-
- /* Function prototypes */
- static PROTO (void init_field, (FIELD *, char *));
- static PROTO (void leave_field, (FIELD *));
- static PROTO (void build_display_buff, (FIELD *, char *));
- static PROTO (void int_disp_text, (FIELD *, int, char *));
- PROTO (int length_mask, (FIELD *));
- PROTO (char *home_field, (FIELD *, char *));
- static PROTO (char *end_field, (FIELD *, char *));
- static PROTO (char *backspace, (FIELD *, char *));
- static PROTO (char *forward, (FIELD *, char *));
- static PROTO (char *bleep_over_mask, (FIELD *, char *, int));
- static PROTO (char *del_text_char, (FIELD *, char *));
- static PROTO (void scroll_field_left, (FIELD *));
- static PROTO (void scroll_field_right, (void));
- static PROTO (void put_cursor, (FIELD *, int));
- static PROTO (void forward_cursor, (FIELD *));
- static PROTO (void back_cursor, (FIELD *));
- static PROTO (void home_cursor, (FIELD *));
- static PROTO (int check_char, (int *, char *, FIELD *));
- static PROTO (int realign_decimals, (FIELD *, char *));
- static PROTO (int set_negative_flag, (char *));
- static PROTO (void set_calculator_flag, (char *));
- static PROTO (void fill_mask, (int, char *));
- static PROTO (int text_mask, (FIELD *, char));
- static PROTO (int endinput, (int));
- static PROTO (void setcur_shape, (void));
-
- extern int instos; /* inchar.c */
-
- /* static variables */
- static char *field_buffer; /* internal field buffer */
- static char display_buff[MAX_MASK]; /* display buff, should alloc dynamically */
- static char *disp_buff_ptr; /*points to current screen start of display_buff*/
- static int end_display; /* TRUE if leaving a field, display buffer in full*/
- static int number_negative;
- static int calculator_flag;
- static int field_numeric;
- static char *save_buff;
-
- char *glob_mask; /* internal mask */
- int doing_memos = FALSE;
- int field_overflow = FALSE;
- int cursor_col; /* column of cursor , used again in memo.c */
- int homed_field = FALSE;
- int delete_key = FALSE;
-
- # ifdef MSDOS
- static int numlock_on;
- # endif
-
-
-
- # ifdef UNIX
- int input_wx(fld, va_alist)
- FIELD *fld;
- va_dcl
- # else
- int input_wx(FIELD *fld, int va_alist, ...)
- # endif
- {
- va_list ap;
- int key;
- int done = FALSE;
- int buff_len;
- static int prev_buff_len = 0;
-
-
- /* call the pre input function if it is defined */
- if (fld->f_pre)
- if ((*fld->f_pre)(fld) == FALSE)
- return(K_ESC);
-
- /* save the fbuff, if K_ESC is hit we'll restore the buffer to its
- * previous contents
- */
- if (!doing_memos && (buff_len = strlen(fld->fbuff)) != 0)
- {
- if (buff_len > prev_buff_len)
- {
- if (save_buff)
- free (save_buff);
- save_buff = (char *)alloc(buff_len + 1);
- prev_buff_len = buff_len;
- }
- else
- zerorec(save_buff, buff_len);
- bytecpy(save_buff, fld->fbuff, buff_len);
- }
-
- /* loop getting input until valid end key is pressed */
- while (TRUE)
- {
- if_bad_input:
- if (fld->f_input)
- ichar = (*fld->f_input)(fld);
-
- if (ichar == K_CR)
- {
- if (fld->f_val && (*fld->f_val)(fld) == FALSE)
- continue;
- break;
- }
- else if (ichar == K_ESC)
- {
- if (!doing_memos && buff_len)
- {
- zerorec(fld->fbuff, buff_len);
- bytecpy(fld->fbuff, save_buff, buff_len);
- }
- break;
- }
-
- # ifdef UNIX
- va_start(ap);
- key = va_arg(ap, int);
- # else
- va_start(ap, va_alist);
- key = va_alist;
- # endif
-
- while (key != 0)
- {
- if (ichar == key)
- {
- if (fld->f_val && (*fld->f_val)(fld) == FALSE)
- goto if_bad_input;
- done = TRUE;
- }
- key = va_arg(ap, int);
- }
- va_end(ap);
-
-
- /* check if field has over flowed before continuing */
- if (field_overflow)
- done = TRUE;
-
- /* if we're done, then we're done - and I don't mean maybe */
- if (done)
- break;
-
- }
- if (ichar != K_ESC)
- {
- /* post input function */
- if (fld->f_post)
- (*fld->f_post)(fld);
- }
-
- /* set ichar to the exitcode and return */
- return(ichar);
- }
-
-
-
- /*
- * Display a field by building the output string and displaying it.
- */
- void disp_text(field, attr)
- FIELD *field;
- int attr;
- {
- char *mask;
- int disp_length;
-
- if (field->fieldlen == 0 || !length_mask(field))
- return;
-
- mask = field->fmask;
- init_field(field, mask);
- end_display = TRUE;
-
- /* need a routine to build the display string from the mask and the
- * buffer. Then simply display the buffer.
- */
- build_display_buff(field, mask);
- disp_length = length_mask(field);
-
- # ifdef INDEBUG
- errmsg("disp_text(): frow %d fcol %d attr %d\n\t\tdisp_length %d buff '%s'", field->frow, field->fcol, attr, disp_length, disp_buff_ptr);
- # endif
- ndisp_w(field->frow, field->fcol, attr, disp_length, disp_buff_ptr);
- put_cursor(field, 0);
-
- leave_field(field);
- }
-
- /*
- * Return a formatted string, built from the fields contents and mask.
- * Same as disp_text but don't display it
- */
- char *fmt_text(field)
- FIELD *field;
- {
- char *mask;
-
- if (field->fieldlen == 0 || !length_mask(field))
- return("");
-
- mask = field->fmask;
- init_field(field, mask);
- end_display = TRUE;
-
- /* need a routine to build the display string from the mask and the
- * buffer. Then simply display the buffer.
- */
- build_display_buff(field, field->fmask);
-
- leave_field(field);
- return(disp_buff_ptr);
- }
-
-
- /*
- * Read in a text, numeric, date or memo field in from the keyboard
- */
- int text_input(field)
- FIELD *field;
- {
- char *mask;
- int c;
- int done = FALSE;
- int curstate;
- int field_negative;
-
- #ifdef MOUSE
-
- int mr, mc, mh, mw;
-
- abs_w(&mr, &mc, &mw, &mh);
- mouse_add_object(mr + field->frow, mc + field->fcol, mr + field->frow, mc + field->fcol + length_mask(field) - 1, 0, 0, "INPUT");
-
- #endif
-
- curstate = cursor(ON);
- setcur_shape();
-
- /* allocate new buffer for mask; allows for local modification
- */
- glob_mask= (char *)alloc(MAX(strlen(field->fmask), field->fieldlen)+1);
- strcpy(glob_mask, field->fmask);
- mask = glob_mask;
- # ifdef INDEBUG
- errmsg("text_input(): after alloc(): mask '%s'\n\t\tMAX length %d", mask, MAX(strlen(field->fmask), field->fieldlen));
- # endif
-
- init_field(field, mask);
-
- /* if strlen(mask) < fieldlen then
- * mask is filled up to fieldlen with the last occuring mask char
- * scrolling field with input up to fieldlen chars is created
- * else strlen(mask) > fieldlen then
- * input allowed up to fieldlen chars, extra mask ignored
- *
- * field->fieldlen controls length of field displayed on screen
- */
- if (field->ftype == F_TEXT && strlen(mask) != field->fieldlen)
- fill_mask(field->fieldlen, mask);
-
- field_negative = set_negative_flag(mask);
-
-
- /* this bit is gross but memos need it for the time being
- */
- if (!homed_field)
- mask = home_field(field, mask);
- else
- {
- int i, fx;
-
- for (homed_field = 0, fx = field->fx, field->fx = i = 0; i<fx; i++)
- mask = forward(field, mask);
- }
-
-
- /* have a case for all of the characters possible for input
- */
- while (TRUE)
- {
- mask = bleep_over_mask(field, mask, 1);
-
- int_disp_text(field, field->fattrib_on, glob_mask);
- c = inchar();
-
- switch (c)
- {
- #ifdef MOUSE
- case M_PRESS :
- if (!mouse_check_bounds())
- break;
- case M_RELEASE :
- {
- int dummy;
- if (mouse_row == w_nrows)
- mouse_click(&dummy, c);
- else if (mouse_click(&dummy, M_PRESS))
- {
- if (c == M_PRESS)
- {
- dummy = cursor_col + mc;
- if (mouse_col > dummy)
- while (mouse_col > dummy++)
- {
- if (dummy > (mc + field->fcol + strlen(field->fbuff)))
- break;
- unget_inchar(K_RIGHT);
- }
- else if (mouse_col < dummy)
- while (mouse_col < dummy--)
- unget_inchar(K_LEFT);
- }
- }
- }
- break;
- #endif
- case K_HOME :
- if ((field->fcontrol&NO_HOME_END) != NO_HOME_END && !field_numeric)
- {
- mask = home_field(field, mask);
- break;
- }
- else
- goto is_default;
-
- case K_END :
- if ((field->fcontrol&NO_HOME_END) != NO_HOME_END && !field_numeric)
- {
- mask = end_field(field, mask);
- break;
- }
- else
- goto is_default;
-
- case K_RIGHT :
- if (!*field_buffer || field_buffer == field->fbuff + field->fieldlen || (doing_memos && field->fx == field->fieldlen))
- done = TRUE;
- else if ((!calculator_flag && field_numeric) || !field_numeric)
- {
- mask = forward(field, mask);
- if (*field_buffer == '.' && field_numeric)
- {
- while (*mask != '.')
- {
- forward_cursor(field);
- field->fx++;
- mask++;
- }
- /* do once more past decimal position */
- /*
- forward_cursor(field);
- field->fx++;
- mask++;
- */
- # ifdef INDEBUG
- errmsg("K_RIGHT mask '%s' cursor_col '%d'", mask, cursor_col);
- # endif
- }
- }
- break;
-
- case K_LEFT :
- if (field_buffer != field->fbuff && !calculator_flag)
- {
- mask = backspace(field, mask);
- if (*field_buffer == '.' && !calculator_flag && field_numeric)
- {
- int tmp = (int)(strchr(field->fbuff, '.') - field->fbuff);
- mask = home_field(field, mask);
- while (tmp--)
- mask = forward(field, mask);
- # ifdef INDEBUG
- errmsg("K_LEFT mask '%s' cursor_col '%d'", mask, cursor_col);
- # endif
- }
- }
- else
- done = TRUE;
- break;
-
- case K_BS :
- if (field_buffer != field->fbuff)
- {
- if (calculator_flag && (*field_buffer == '.' || (strchr(mask, MASK_8) && strchr(field->fbuff, '.'))))
- forward_cursor(field); /* fake out */
- mask = backspace(field, mask);
- }
- else
- done = TRUE;
-
- case K_DEL :
- if (c == K_DEL)
- delete_key = TRUE;
- mask = del_text_char(field, mask);
- if (doing_memos && !strlen(field->fbuff))
- done = TRUE;
- delete_key = FALSE;
- break;
-
- case K_INS :
- instos ^= TRUE;
- setcur_shape();
- break;
-
- case K_F1 :
- help_msg(field->fhelp);
- break;
-
- case '-' :
- if (field_numeric && field_negative)
- {
- number_negative ^= TRUE;
- break;
- }
-
- case '.' :
- /* make sure it is not a fall thru */
- if (field_numeric && *mask != '.' && strchr(mask, '.') && c == '.')
- {
- /* move the data to the decimal */
- while (*mask != '.')
- {
- if (!calculator_flag)
- forward_cursor(field);
- field->fx++;
- mask++;
- }
- if (strchr(field_buffer, '.'))
- while(*field_buffer != '.')
- field_buffer++;
-
- if (calculator_flag)
- forward_cursor(field);
- }
-
- case K_UP :
- case K_F4 :
- case K_DOWN :
- case K_F3 :
-
- default :
- is_default:
- if (endinput(c))
- {
- done = TRUE;
- end_display = TRUE;
- break;
- }
-
- if (*mask)
- {
- if (!check_char(&c, mask, field))
- {
- do_bell();
- break;
- }
- if ((field_numeric && *field_buffer == '.' && c != '.') || (instos && strlen(field->fbuff) < field->fieldlen))
- move_text(field_buffer+1, field_buffer, strlen(field_buffer)-1);
- }
- else
- {
- if ((field->fcontrol&OVERFLOW_RETURN) == OVERFLOW_RETURN)
- {
- field_overflow = TRUE;
- break;
- }
- else if ((field->fcontrol&CONFIRM_NEEDED) != CONFIRM_NEEDED)
- {
- /* quit and return K_CR to application */
- done = TRUE;
- c = K_CR;
- break;
- }
-
- mask = backspace(field, mask);
- if (!check_char(&c, mask, field))
- {
- errmsg(InvalidEntry);
- mask = forward(field, mask);
- break;
- }
- }
- *field_buffer = (char) c;
- mask = forward(field, mask);
- if (!doing_memos && !*mask && (field->fcontrol&CONFIRM_NEEDED) != CONFIRM_NEEDED)
- /* last char in field, do overflow */
- field_overflow = TRUE;
- break;
- }
- if (done || field_overflow)
- {
- if (field_overflow)
- c = K_CR;
- break;
- }
- }
- if (field_numeric && !*field->fbuff)
- *field->fbuff = '0';
-
- disp_buff_ptr = display_buff;
- int_disp_text(field, field->fattrib_off, glob_mask);
-
- leave_field(field);
-
- # ifdef MOUSE
- mouse_delete_object(0, 0, "INPUT");
- # endif
- cursor(OFF);
- free(glob_mask);
- return(c);
- }
-
-
- /* static void init_field(FIELD *, char *)
- *
- * sets up all the variables to appropriate defaults.
- */
- static void init_field(field, mask)
- FIELD *field;
- char *mask;
- {
- end_display = FALSE;
- field_overflow = FALSE;
- number_negative = FALSE;
- field_numeric = FALSE;
- calculator_flag = FALSE;
- disp_buff_ptr = display_buff;
-
- if (field->ftype == F_NUMERIC)
- field_numeric = TRUE;
-
- if (input_type && field_numeric)
- set_calculator_flag(mask);
-
- if (field_numeric && *field->fbuff == '-')
- {
- /* increment the fbuff past the negative sign, it gets in the way */
- move_text(field->fbuff, field->fbuff+1, strlen(field->fbuff)-1);
- number_negative = TRUE;
- }
-
- clean_buffer(field);
-
- # ifdef INDEBUG
- errmsg("init_field(): mask '%s'\n\tfield->fbuff '%s'\n\tcursor_col %d", mask, field->fbuff, cursor_col);
- # endif
- }
-
-
- /*
- * undo things left by init_field
- */
- static void leave_field(field)
- FIELD *field;
- {
- if (number_negative)
- {
- move_text(field->fbuff+1, field->fbuff, strlen(field->fbuff)-1);
- *field->fbuff = '-';
- }
- # ifdef INDEBUG
- errmsg("leave_field(): field->fbuff '%s'", field->fbuff);
- # endif
- }
-
-
- /*
- * This routine takes the data buffer and together with the mask fills
- * the display buffer with the properly formatted data
- */
- static void build_display_buff(field, mask)
- FIELD *field;
- char *mask;
- {
- char *m = mask;
- char *b = field->fbuff;
- char *d = display_buff;
- char fill_char;
- int decimal_increment = 0;
- int save_decimal_inc = 0;
- int first = TRUE;
- char *last_num; /* store the position of the last digit so we can round it
- */
-
- byteset(d, HARDSPACE, MAX_MASK);
-
- if (field_numeric)
- save_decimal_inc = realign_decimals(field, m);
-
- if (calculator_flag || end_display)
- decimal_increment = save_decimal_inc;
-
- # ifdef INDEBUG
- errmsg("begin - build_display_buff(): field->fbuff '%s'\n\t\tmask '%s'\n\t\tdecimal_increment %d", b, m, decimal_increment);
- # endif
-
- while (*m)
- {
- if (*b == '.' && first && field_numeric && !calculator_flag && !end_display)
- {
- decimal_increment = save_decimal_inc;
- first = FALSE;
- }
-
- switch(text_mask(field, *m))
- {
- case TEMPLATE :
- switch (*m)
- {
- case MASK_YEAR :
- case MASK_MONTH :
- case MASK_DAY :
- case MASK_HOUR :
- case MASK_MINUTE :
- case MASK_SECOND :
- case MASK_WEEKDAY :
- case MASK_DAY_SUFFIX :
- if (field->ftype == F_DATE || field->ftype == F_TIME)
- *d++ = ( *b ? *b++ : *m);
- break;
-
- case MASK_8 :
- case MASK_z :
- case MASK_Z :
- last_num = d; /* allow fall through */
-
- case MASK_I :
- case MASK_C :
- case MASK_c :
- case MASK_P :
- case MASK_p :
- case MASK_Q :
- case MASK_A :
- case MASK_a :
- case MASK_B :
- case MASK_x :
- case MASK_X :
- case MASK_Y :
- *d++ = (*b && !decimal_increment ? *b : HARDSPACE);
- if (!decimal_increment)
- b++;
- if (decimal_increment)
- decimal_increment--;
- break;
-
- case MASK_9 :
- last_num = d;
- if (end_display)
- fill_char = '0';
- else
- fill_char = HARDSPACE;
-
- *d++ = ( *b && !decimal_increment ? *b : fill_char);
- if (!decimal_increment)
- b++;
- if (decimal_increment)
- decimal_increment--;
- break;
-
- case MASK_MONEY :
- last_num = d;
- *d++ = ( *b && !decimal_increment ? *b : DOLLAR_SIGN);
- if (!decimal_increment)
- b++;
- if (decimal_increment)
- decimal_increment--;
- break;
-
- case '.' :
- *d++ = '.';
- if (*b && *b != '.')
- *display_buff = '?';
- b++;
- break;
-
- case '(' :
- case ')' :
- case '-' :
- if (field_numeric && number_negative)
- *d++ = *m;
- else
- *d++ = HARDSPACE;
- break;
-
- default :
- *d++ = HARDSPACE;
- break;
- }
- break;
-
- case PASSWORD :
- *d++ = ( *b++ ? '*' : HARDSPACE);
- break;
-
- case FILL :
- if (*m == ',' && *(d-1) == HARDSPACE)
- *d++ = HARDSPACE;
- else if (*m == ',' && *(d-1) == DOLLAR_SIGN)
- *d++ = DOLLAR_SIGN;
- else
- *d++ = *m;
-
- case SPECIAL :
- default :
- break;
- }
- m++;
- }
-
- # ifdef INDEBUG
- errmsg("middle - build_disp_buff(): display_buff '%s'", display_buff);
- # endif
-
- /* round of the decimal portion */
- if (field_numeric && *b && isdigit(*b) && *b >= '5')
- {
- while (last_num != display_buff)
- {
- if (*last_num < '9')
- break;
- if (*last_num == '9' && *(last_num-1) == '9')
- *last_num-- = '0';
- else if (*last_num == '9')
- {
- *last_num-- = '0';
- if (*last_num == '.')
- last_num--;
- else
- break;
- }
- }
- *last_num += 1;
- }
-
- *d = '\0';
- # ifdef INDEBUG
- errmsg("end - build_disp_buff(): field->fbuff '%s' display_buff '%s'", field->fbuff, display_buff);
- # endif
- }
-
-
- /*
- * disp_text for internal use only
- */
- static void int_disp_text(field, attr, mask)
- FIELD *field;
- int attr;
- char *mask;
- {
- int disp_length;
-
- /* need a routine to build the display string from the mask and the
- * buffer. Then simply display the buffer.
- */
- build_display_buff(field, mask);
- disp_length = length_mask(field);
-
- # ifdef INDEBUG
- errmsg("int_disp_text(): display_buff '%s'\n\t\tdisp_length %d", disp_buff_ptr, disp_length);
- # endif
-
- ndisp_w(field->frow, field->fcol, attr, disp_length, disp_buff_ptr);
- put_cursor(field, 0);
- }
-
-
- /*
- * This routine calculates the character length of a mask
- * it ignores MASK_SPECIAL chars
- */
- int length_mask(field)
- FIELD *field;
- {
- char *m;
- int msk_count = 0;
-
- for (m = field->fmask; *m; m++)
- {
- switch(text_mask(field, *m))
- {
- case PASSWORD :
- case TEMPLATE :
- case FILL :
- msk_count++;
- default :
- break;
- }
- }
- return(msk_count);
- }
-
-
- /*
- * This routine moves the cursor to the beginning of the field
- */
- char *home_field(field, mask)
- FIELD *field;
- char *mask;
- {
- field_buffer = field->fbuff;
- field->fx = 0;
- mask = glob_mask;
- disp_buff_ptr = display_buff;
- cursor_col = field->fcol;
-
- if (calculator_flag && strlen(field->fbuff))
- while(*field_buffer && *field_buffer != '.' && *mask && field->fx < field->fieldlen)
- mask = forward(field, mask);
-
- home_cursor(field);
-
- # ifdef INDEBUG
- errmsg("home_field(): mask '%s'\n\tfield_buffer '%s'\n\tcursor_col %d", mask, field_buffer, cursor_col);
- # endif
- return(mask);
- }
-
-
- /*
- * This routine moves the cursor to the end of the field
- */
- static char *end_field(field, mask)
- FIELD *field;
- char *mask;
- {
- field_buffer = field->fbuff;
- field->fx = 0;
- mask = glob_mask;
- disp_buff_ptr = display_buff;
- home_cursor(field);
-
- while(*field_buffer && *mask && field->fx < field->fieldlen)
- mask = forward(field, mask);
-
- return(mask);
- }
-
-
- /*
- * This routine moves the cursor back one position
- */
- static char *backspace(field, mask)
- FIELD *field;
- char *mask;
- {
- field_buffer--;
- mask--;
- if (field->fx > 1)
- field->fx--;
-
- mask = bleep_over_mask(field, mask, 0);
-
- /* scroll the text if possible */
- if ( cursor_col - field->fcol == 0)
- scroll_field_right();
- else
- {
- if ((field_buffer == field->fbuff + field->fieldlen - 1) && (cursor_col != field->fcol + field->fieldlen - 1))
- back_cursor(field);
- else if ( *(mask+1) && ((calculator_flag && strchr(field->fbuff, '.')) || !calculator_flag))
- back_cursor(field);
- }
-
- return(mask);
- }
-
-
- /*
- * This routine moves the cursor forward one space
- */
- static char *forward(field, mask)
- FIELD *field;
- char *mask;
- {
- field_buffer++;
- field->fx++;
-
- mask = bleep_over_mask(field, mask, 1);
- mask++;
-
- /* if at end of display space do not move cursor,
- * scroll through field_buffer
- */
- if ( cursor_col - field->fcol + 1 >= length_mask(field))
- scroll_field_left(field);
- else if ( cursor_col - field->fcol +1 < length_mask(field))
- {
- if ((calculator_flag && !strchr(field_buffer, '.') && strchr(field->fbuff, '.')) || !field_numeric || !input_type)
- forward_cursor(field);
- }
-
- return(mask);
- }
-
-
- /*
- * moves over special mask chars that cannot be inputted into
- * parameter direction - 0 = left
- * 1 = right
- */
- static char *bleep_over_mask(field, mask, direction)
- FIELD *field;
- char *mask;
- int direction;
- {
- while (*mask)
- {
- int done = FALSE;
-
- switch (text_mask(field, *mask))
- {
- case FILL :
- if ((!input_type && field_numeric) || !field_numeric)
- {
- if (direction)
- forward_cursor(field);
- else
- back_cursor(field);
- }
-
- case SPECIAL :
- if (direction)
- mask++;
- else
- mask--;
- break;
-
- default :
- switch(*mask)
- {
- case '(' :
- case '-' :
- if (field_numeric && !calculator_flag && *(mask+1))
- {
- if (direction)
- forward_cursor(field);
- else
- back_cursor(field);
- }
- case ')' :
- if (field_numeric)
- {
- if (direction)
- mask++;
- else
- mask--;
- }
- break;
- default :
- done = TRUE;
- break;
- }
- break;
- }
- if (done)
- break;
- }
- # ifdef INDEBUG
- errmsg("bleep_over_mask(): mask '%s'\n\tcursor_col %d", mask, cursor_col);
- # endif
-
- return(mask);
- }
-
-
- /*
- * This routine deletes a character from the buffer
- */
- static char *del_text_char(field, mask)
- FIELD *field;
- char *mask;
- {
-
- int tmp_len;
-
- tmp_len = field->fieldlen - (field_buffer - field->fbuff) - 1;
- if (tmp_len < 0)
- tmp_len = 0;
-
- if (*field_buffer)
- {
- char tmp = *field_buffer;
-
- if (tmp_len)
- move_text(field_buffer, field_buffer+1, tmp_len);
- field_buffer[tmp_len] = '\0';
-
- if (tmp == '.' && field_numeric && !delete_key)
- mask = end_field(field, mask);
- }
- return(mask);
- }
-
-
- /*
- * The next two routines handle the scrolling. We have the display buffer
- * and a pointer to it. We increment and decrement the pointer to the
- * start of the display buffer and then display the buffer from the start
- * of the pointer
- */
-
- static void scroll_field_left(field)
- FIELD *field;
- {
- if (*disp_buff_ptr && strlen(disp_buff_ptr) > length_mask(field))
- disp_buff_ptr++;
- }
-
- static void scroll_field_right()
- {
- if (*disp_buff_ptr && disp_buff_ptr != display_buff)
- disp_buff_ptr--;
- }
-
-
-
- /*
- * The next 4 routines handle the cursor position. We keep the cursor
- * column in a static variable so that moving the cursor becomes
- * an elementary task, so long as the cursor_col variable does not
- * get screwed up.
- */
-
- static void put_cursor(field, pos)
- FIELD *field;
- int pos;
- {
- if (pos)
- cursor_col = pos + field->fcol;
- moveto_w(field->frow, cursor_col);
- }
-
- static void forward_cursor(field)
- FIELD *field;
- {
- cursor_col++;
- moveto_w(field->frow, cursor_col);
- }
-
- static void back_cursor(field)
- FIELD *field;
- {
- cursor_col--;
- moveto_w(field->frow, cursor_col);
- }
-
- static void home_cursor(field)
- FIELD *field;
- {
- cursor_col = field->fcol;
-
- if (calculator_flag)
- {
- char *tmp;
-
- if (tmp = strchr(glob_mask, '.'))
- cursor_col += (int)(tmp - glob_mask) - 1;
- else
- {
- tmp = (char *)(glob_mask + length_mask(field) - 1);
- if (*tmp == ')' || *tmp == '-')
- tmp--;
- cursor_col += (int)(tmp - glob_mask);
- }
- }
- # ifdef INDEBUG
- errmsg("home_cursor(): cursor_col = %d", cursor_col);
- # endif
- moveto_w(field->frow, cursor_col);
- }
-
-
- /*
- * Check that an input character is valid by looking at the current mask
- * character.
- */
- static int check_char(c, mask, field)
- int *c;
- char *mask;
- FIELD *field;
- {
- if (*mask == MASK_I && !iscntrl(*c))
- return(TRUE);
- else if (!isprint(*c))
- return(FALSE);
-
- switch(*mask)
- {
- case MASK_c : /* alphanumeric _ - convert to lower case */
- if (isupper(*c))
- *c = tolower(*c);
- return(isalpha(*c) || isdigit(*c) || *c == '_');
-
- case MASK_P : /* alphanumeric _ and space - convert to upper case */
- if (islower(*c))
- *c = toupper(*c);
-
- case MASK_p : /* alphanumeric _ and space */
- return(isalpha(*c) || isdigit(*c) || *c == '_' || isspace(*c));
-
- case MASK_Q : /* alphanumeric _ and space - convert to lower case */
- if (isupper(*c))
- *c = tolower(*c);
- return(isalpha(*c) || isdigit(*c) || *c == '_' || isspace(*c));
-
- case MASK_A : /* alphabetic and space - convert to upper case */
- if (islower(*c))
- *c = toupper(*c);
-
- case MASK_a : /* alphabetic and space - ^ fall through */
- return(isalpha(*c) || isspace(*c));
-
- case MASK_B : /* alphabetic and space - convert to lower case */
- if (isupper(*c))
- *c = tolower(*c);
- return(isalpha(*c) || isspace(*c));
-
- case MASK_C : /* alphabetic - convert to lower case */
- if (isupper(*c))
- *c = tolower(*c);
- return(isalpha(*c));
-
- case MASK_8 : /* numeric or decimal place */
- return(isdigit(*c) || (*c == '.' && !strchr(field->fbuff, '.')));
-
- case MASK_MONEY : /* numeric */
- case MASK_9 :
- case MASK_Z :
- case MASK_z :
- return(isdigit(*c));
-
- case MASK_AT :
- return(TRUE);
-
- case MASK_PSWD :
- return(!(*c == HARDSPACE));
-
- case '.' :
- return(*c == '.');
-
- case MASK_YEAR :
- case MASK_MONTH :
- case MASK_DAY :
- case MASK_HOUR :
- case MASK_MINUTE :
- case MASK_SECOND :
- case MASK_WEEKDAY :
- case MASK_DAY_SUFFIX :
- return(isdigit(*c));
-
- case MASK_Y : /* any character - convert to lower case */
- if (isupper(*c))
- *c = tolower(*c);
- return(TRUE);
-
- case MASK_X : /* any character - convert to upper case */
- if (islower(*c))
- *c = toupper(*c);
-
- case MASK_x : /* any character - ^ fall through */
- default:
- return(TRUE);
-
- }
- }
-
-
- static int realign_decimals(field, mask)
- FIELD *field;
- char *mask;
- {
- int buf_count= 0;
- int msk_count= 0;
- int move_amount = 0;
- char *m = mask;
-
- if (*field->fbuff)
- {
- char *tmp1;
-
- if (strchr(mask, MASK_8))
- buf_count = strlen(field->fbuff);
- else if (tmp1 = strchr(field->fbuff, '.'))
- buf_count = (int)(tmp1 - field->fbuff);
- else if (end_display)
- {
- int space_count = 0;
-
- for (tmp1 = field->fbuff; *tmp1 && *tmp1 != ' '; tmp1++);
- for (space_count = 0; *tmp1 && *tmp1 == ' '; tmp1++, space_count++);
-
- buf_count = strlen(field->fbuff) - space_count;
- }
- else if (input_type)
- buf_count = strlen(field->fbuff);
- else
- buf_count = 0;
- }
-
- while (*m)
- {
- int done = FALSE;
-
- switch (text_mask(field, *m))
- {
- case TEMPLATE :
- if (*m == '.')
- done = TRUE;
- else if (*m != '-' && *m != ')' && *m != '(')
- msk_count++;
- break;
- case FILL :
- if (*m == '*' && *(m-1) == '*')
- msk_count++;
- default :
- break;
- }
- if (done)
- break;
- m++;
- }
-
- # ifdef INDEBUG
- errmsg("realign_decimals(): msk_count %d buf_count %d", msk_count, buf_count);
- # endif
-
- if (input_type || buf_count)
- move_amount = msk_count - buf_count;
- else if (*field->fbuff == '.')
- move_amount = msk_count;
-
- return(move_amount > 0 ? move_amount : 0);
- }
-
-
- static int set_negative_flag(mask)
- char *mask;
- {
- # ifdef MSDOS
- /* set numlock flag */
- numlock_on = FALSE;
- if (*mask == '&')
- {
- numlock_on = TRUE;
- mask++;
- }
- # endif
-
- /* set the negative flags */
- return(*mask == '-' || *mask == '(' || *(mask + strlen(mask) -1) == '-' );
- }
-
-
- /*
- * determine whether the mask is suitable for calculator style of input
- */
- static void set_calculator_flag(mask)
- char *mask;
- {
- char *tmp;
-
- calculator_flag = TRUE;
-
- for(tmp = mask; *tmp; tmp++)
- if (*tmp != MASK_9 &&
- *tmp != MASK_Z &&
- *tmp != MASK_z &&
- *tmp != MASK_8 &&
- *tmp != MASK_MONEY &&
- *tmp != ',' &&
- *tmp != '.' &&
- *tmp != '-' &&
- *tmp != '(' &&
- *tmp != ')' )
- calculator_flag = FALSE;
-
- # ifdef INDEBUG
- errmsg("set_calculator_flag(): calculator_flag = %d", calculator_flag);
- # endif
- }
-
-
- void clean_buffer(field)
- FIELD *field;
- {
- char *b = field->fbuff;
- int i;
-
- for (i=0; i<field->fieldlen; i++, b++)
- if (!*b || (field_numeric && *b == ' '))
- byteset(b, '\0', field->fieldlen - i);
-
- if (calculator_flag)
- {
- if (!strcmp(field->fbuff, "0"))
- *field->fbuff = '\0';
- while (*field->fbuff && *field->fbuff == '0') /* no leading zeros */
- move_text(field->fbuff, field->fbuff+1, strlen(field->fbuff) - 1);
- }
-
- # ifdef INDEBUG
- errmsg("clean_buffer(): field->fbuff = '%s'", field->fbuff);
- # endif
- }
-
-
- /* static void fill_mask(int, char *)
- *
- * fills the mask with the last occuring mask char to the length of
- * field->fieldlen. There should be enough space in mask; it was alloc'd
- * in the calling routine.
- */
- static void fill_mask(fieldlen, mask)
- int fieldlen;
- char *mask;
- {
- char *m = mask;
- char msk_sav;
- int i;
-
- if ((i = strlen(m)) < fieldlen)
- {
- m += i-1;
- msk_sav = *m++;
- byteset(m, msk_sav, fieldlen - i);
- }
- *(mask + fieldlen) = '\0';
-
- # ifdef INDEBUG
- errmsg("fill_mask(): mask = '%s'", mask);
- # endif
- }
-
-
-
- /*
- * Check a character against all the valid mask characters for a text type
- * of field
- */
- static int text_mask(fld, c)
- FIELD *fld;
- char c;
- {
- static int special = FALSE;
-
- /* check if c is a valid mask character */
- if (fld->ftype == F_NUMERIC)
- {
- switch (c)
- {
- case MASK_8 :
- case MASK_MONEY :
- case MASK_9 :
- case MASK_Z :
- case MASK_z :
- return(special ? FILL : TEMPLATE);
- case MASK_SPECIAL :
- special ^= TRUE;
- return(SPECIAL);
- default :
- switch (c)
- {
- case '.' :
- case '-' :
- case '(' :
- case ')' :
- return(TEMPLATE);
- default :
- return(FILL);
- }
- }
- }
- else if (fld->ftype == F_TEXT)
- {
- switch (c)
- {
- case MASK_I :
- case MASK_C :
- case MASK_c :
- case MASK_x :
- case MASK_X :
- case MASK_Y :
- case MASK_P :
- case MASK_p :
- case MASK_Q :
- case MASK_a :
- case MASK_A :
- case MASK_B :
- case MASK_8 :
- case MASK_MONEY :
- case MASK_9 :
- case MASK_Z :
- case MASK_z :
- case MASK_AT :
- return(special ? FILL : TEMPLATE);
- case MASK_PSWD :
- return(special ? FILL : PASSWORD);
- case MASK_SPECIAL :
- special ^= TRUE;
- return(SPECIAL);
- default :
- return(FILL);
- }
- }
- else /* F_DATE or F_TIME */
- {
- switch (c)
- {
- case MASK_YEAR :
- case MASK_MONTH :
- case MASK_DAY :
- case MASK_HOUR :
- case MASK_MINUTE :
- case MASK_SECOND :
- case MASK_WEEKDAY :
- case MASK_DAY_SUFFIX :
- return(special ? FILL : TEMPLATE);
- case MASK_SPECIAL :
- special ^= TRUE;
- return(SPECIAL);
- default :
- return(FILL);
- }
- }
- }
-
-
- /*
- * Test to see if a character is a end of input character
- */
- static int endinput(c)
- int c;
- {
- switch (c)
- {
- case K_CR :
- case K_ESC :
- case K_UP :
- case K_DOWN :
- case K_RIGHT :
- case K_LEFT :
- case K_PGUP :
- case K_PGDN :
- case K_HOME :
- case K_END :
- case K_TAB :
- case K_F1 :
- case K_F2 :
- case K_F3 :
- case K_F4 :
- case K_F5 :
- case K_F6 :
- case K_F7 :
- case K_F8 :
- case K_F9 :
- case K_F10 :
- return TRUE;
-
- default:
- return FALSE;
- }
- }
-
- /*
- * Set the cursor shape.
- */
- # ifdef MSDOS
- # include "../win/dos/pregs.h"
- # endif
-
- /* keep in os dependent code */
- static void setcur_shape()
- {
- # ifdef MSDOS
-
- RegStorage;
- unsigned int cursor_size;
-
- /* set instos for inchar() and set the shape of the cursor */
- cursor_size = (instos ? 0x0106 : 0x0607);
-
- Regs_ah = 0x01;
- Regs_cx = cursor_size;
- Video();
-
- # endif
- }
-
- /*
- * Move specified amount of text to destination from source. Do the move
- * intelligently by checking which memory location is greater.
- * (from GEO.)
- */
- void move_text(dest, src, cnt)
- char *dest;
- char *src;
- int cnt;
- {
- int i;
- if (src == NULL || dest == NULL)
- return;
- if (src == dest)
- return;
- if (src < dest)
- /* Move up */
- for (i = cnt; i >= 0; i--)
- *(dest+i) = *(src+i);
- else
- /* Move down */
- for (i = 0; i <= cnt; i++)
- *(dest+i) = *(src+i);
- }