home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name EDBASE -- Edit and return a user response.
- *
- * Synopsis error = edbase(pdata, pinitstr, pretstr, target_size,
- * pfield_control, pfinal_key, return_info,
- * set_cursor, write_rect);
- *
- * ED_ACTION error The returned status code.
- * void *pdata Pointer to data which will
- * be passed to return_info,
- * set_cursor, and write_rect.
- * const char *pinitstr The initial value of the
- * buffer.
- * char *pretstr The returned user response.
- * int target_size The maximum size of the
- * buffer, including the
- * trailing '\0'.
- * const ED_CONTROL Field display and editing
- * *pfield_control control structure.
- * KEY_SEQUENCE *pfinal_key Pointer to final keystroke
- * entered by user.
- * PED_RET_FUNC return_info Pointer to function which
- * will return cursor info.
- * PED_SET_FUNC set_cursor Pointer to function which
- * will set cursor state.
- * PED_WRITE_FUNC write_rect Pointer to function which
- * will write a rectangle of
- * screen data.
- *
- * Description EDBASE provides a flexible method for gathering
- * information from a screen field and returning the data
- * in a formatted text string.
- *
- * The field_control parameter is used to control where the
- * field is placed on the screen, how long the diplayed
- * buffer is, cursor size and general editing control.
- *
- * The text contained in pinitstr (if any) is used as an
- * initial value for the field, which the user will be
- * allowed to edit. The length of the text, including
- * the trailing '\0', is not allowed to grow longer than
- * target_size characters.
- *
- * EDBASE is responsible for positioning the cursor,
- * displaying the buffer, and formatting the buffer when it
- * is finally transmitted.
- *
- * Since EDBASE accepts pointers to functions which will
- * perform all physical screen I/O for it, it is intended
- * to be called via the macros EDFIELD and WNFIELD.
- * The EDFIELD macro provides pointers to functions which
- * perform their I/O on the screen itself, whereas WNFIELD
- * provides functions which perform their I/O on a window.
- *
- * Returns error EDFIELD returns:
- * ED_NO_ERROR - Data successfully returned.
- * ED_ILL_DIM - Field dimensions are illegal.
- * ED_NO_MEMORY - No memory for temporary storage.
- * ED_USER_ABORT - Editing aborted by user, no data
- * returned.
- * WNFIELD returns:
- * WN_NO_ERROR - Data successfully returned.
- * WN_ILL_DIM - Field dimensions are illegal.
- * WN_NO_MEMORY - No memory for temporary storage.
- * WN_BAD_WIN - *pdata points to a bad window structure.
- * WN_ILL_VALUE - Cursor dimensions are illegal.
- * ED_USER_ABORT - Editing aborted by user, no data
- * returned.
- * b_wnerr Unchanged if no error, otherwise
- * same value as error.
- *
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
- #include <butil.h>
- #include <bedit.h>
- #include <bstrings.h>
- #include <bvideo.h>
- #include <bwindow.h>
- #include <conio.h>
- #include <string.h>
- #include <stdio.h>
-
-
- int edbase(pdata, pinitstr, pretstr, target_size, pfield_control,
- pfinal_key, return_info, set_cursor, write_rect)
- void *pdata;
- const char *pinitstr;
- char *pretstr;
- int target_size;
- const ED_CONTROL *pfield_control;
- KEY_SEQUENCE *pfinal_key;
- PED_RET_FUNC return_info;
- PED_SET_FUNC set_cursor;
- PED_WRITE_FUNC write_rect;
- {
- int row, col;
- ED_BUFFER edit_buffer;
- int buffer_length;
- int field_width, field_height;
- int cur_edit_row, cur_edit_col;
- int fore_attr, back_attr;
- CUR_TYPE replace_curs, insert_curs;
- KEY_SEQUENCE found_keyseq;
- ED_KEY edit_key;
- ED_KEY *pedit_key;
- char fill_char;
- ED_ACTION edit_action;
- unsigned char beep_on, done;
- int final_action;
- int error_code;
- char *ptemp_buffer;
- int just_code;
- CUR_INFO info;
- int error;
- char *ptemp_string = NIL;
- int nul_index;
-
- field_height = pfield_control->dimensions.h;
- field_width = pfield_control->dimensions.w;
-
- error = return_info(pdata, &info, &(pfield_control->ul_corner),
- field_height, field_width);
- if (error)
- return(error);
-
- /* Set the initial field coordinates. */
- row = pfield_control->ul_corner.row;
- col = pfield_control->ul_corner.col;
-
- /* Default attributes are the existing attributes */
- /* if foreground and background are both zero. */
- if (pfield_control->attribute == 0)
- {
- fore_attr = -1;
- back_attr = -1;
- }
- else
- {
- fore_attr = uthinyb(pfield_control->attribute);
- back_attr = utlonyb(pfield_control->attribute);
- }
-
- if ((pfield_control->replace_cursor.high == -1) &&
- (pfield_control->replace_cursor.low == -1))
- {
- replace_curs = info.size;
- }
- else
- replace_curs = pfield_control->replace_cursor;
-
- if ((pfield_control->insert_cursor.high == -1) &&
- (pfield_control->insert_cursor.low == -1))
- {
- insert_curs = info.size;
- }
- else
- insert_curs = pfield_control->insert_cursor;
-
- /* Now initialize the edit buffer, edit_buffer. The */
- /* previous values are set to the same values as */
- /* the current values. The buffers are set to the */
- /* initial string, and length is the length of the */
- /* edit field. */
- buffer_length = field_width * field_height;
-
- edit_buffer.pbuffer = malloc(buffer_length);
- if (edit_buffer.pbuffer == NIL)
- return(ED_NO_MEMORY);
-
- memset(edit_buffer.pbuffer, ' ', buffer_length);
- edit_buffer.pbuffer[buffer_length - 1] = '\0';
-
- utuplim(buffer_length, target_size - 1);
-
- /* Set the edit buffer control flags so that */
- /* EDBUFFER will know what to do. */
- edit_buffer.control_flags = pfield_control->control_flags &
- (ED_INSERT_MODE | ED_WORD_WRAP);
-
- edit_buffer.buffer_size = buffer_length;
- edit_buffer.cursor_pos = 0;
- edit_buffer.attribute = utnybbyt(back_attr, fore_attr);
- edit_buffer.dimensions = pfield_control->dimensions;
-
- if (pinitstr != NIL)
- {
- /* If word wrap is specified, remove all leading */
- /* blanks from the buffer. */
- if ((pfield_control->control_flags & ED_WORD_WRAP) &&
- isspace(pinitstr[0]))
- {
- ptemp_string = malloc(strlen(pinitstr));
- if (ptemp_string == NIL)
- {
- free(edit_buffer.pbuffer);
- return(ED_NO_MEMORY);
- }
- strcpy(ptemp_string, pinitstr);
- stpcvt(ptemp_string, RLWHITE);
- pinitstr = ptemp_string;
- }
-
- if (strlen(pinitstr) <= buffer_length)
- edit_buffer.data_end = strlen(pinitstr);
- else
- edit_buffer.data_end = buffer_length;
- memmove(edit_buffer.pbuffer, pinitstr, edit_buffer.data_end);
- }
- else
- edit_buffer.data_end = 0;
-
- /* Begin by applying word wrapping to the buffer, */
- /* if requested. */
- if (pfield_control->control_flags & ED_WORD_WRAP)
- {
- edreduce(&edit_buffer);
- edwrap(&edit_buffer);
- }
-
- /* The main loop of EDBASE displays the current */
- /* buffer, and positions the cursor to the */
- /* appropriate position on the screen. The current */
- /* edit mode determines the size of the cursor. The */
- /* function KBPOLL returns the keystroke by polling */
- /* the keyboard. The address of the key control */
- /* function is passed to KBPOLL, and the address of */
- /* the edit buffer is passed as the function data. */
- /* The application key control function can */
- /* therefore inspect and alter the edit buffer if */
- /* it wishes. */
-
- beep_on = 0;
- done = 0;
-
- do
- {
- cur_edit_row = edit_buffer.cursor_pos / field_width;
- cur_edit_col = edit_buffer.cursor_pos -
- (field_width * cur_edit_row);
-
- /* Set the size & position of the cursor. */
- if (edit_buffer.control_flags & ED_INSERT_MODE)
- error = set_cursor(pdata, 0, &insert_curs,
- row + cur_edit_row, col + cur_edit_col);
- else
- error = set_cursor(pdata, 0, &replace_curs,
- row + cur_edit_row, col + cur_edit_col);
- if (error)
- {
- free(edit_buffer.pbuffer);
- if (ptemp_string != NIL)
- free(ptemp_string);
- return(error);
- }
-
- /* Display the data contained in the buffer. */
- write_rect(pdata, row, col,
- row + field_height - 1,
- col + field_width - 1,
- edit_buffer.pbuffer, fore_attr,
- back_attr, CHARS_ONLY);
-
- /* Now return the next keystroke. If it is not a */
- /* recognized edit key (that is, it does not appear */
- /* in the edit key list), the action code taken is */
- /* ED_ASCII (display as standard character), if the */
- /* character code is nonzero. All other keys are */
- /* ignored (ED_NULL). */
-
- while (!kbpoll(pfield_control->control_function, &edit_buffer,
- &found_keyseq, KB_REMOVE_KEY))
- ;
-
- pedit_key = edretkey(&found_keyseq);
-
- if (pedit_key == NIL)
- {
- edit_action = (found_keyseq.character_code ? ED_ASCII
- : ED_NULL);
- edit_key.key_sequence = found_keyseq;
- edit_key.edit_actions.num_actions = 1;
- edit_key.edit_actions.pactions = &edit_action;
- pedit_key = &edit_key;
- }
-
- final_action = edbuffer(&edit_buffer, pedit_key);
-
- /* If at the end of the buffer, check to see if */
- /* transmission should occur (ED_AUTOSKIP) or if */
- /* the system speaker should sound (ED_BEEP_END). */
- if (edit_buffer.cursor_pos == (buffer_length - 1))
- {
- if ((pfield_control->control_flags & ED_BEEP_END) != 0)
- beep_on = 1;
- if ((pfield_control->control_flags & ED_AUTOSKIP) != 0)
- {
- done = 1;
- error_code = ED_NO_ERROR;
- }
- }
-
- if (beep_on)
- {
- beep_on = 0;
- scttywrt('\a', 0);
- }
-
- switch (final_action)
- {
- case ED_ABORT:
- done = 1;
- error_code = ED_USER_ABORT;
- memset(edit_buffer.pbuffer, ' ', buffer_length);
- edit_buffer.data_end = strlen(pinitstr);
- utuplim(edit_buffer.data_end, buffer_length);
- memmove(edit_buffer.pbuffer, pinitstr,
- edit_buffer.data_end);
- break;
-
- case ED_ATTR:
- if (edit_buffer.attribute == 0)
- {
- fore_attr = -1;
- back_attr = -1;
- }
- else
- {
- fore_attr = uthinyb(edit_buffer.attribute);
- back_attr = utlonyb(edit_buffer.attribute);
- }
- break;
-
- case ED_UNDO:
- memset(edit_buffer.pbuffer, ' ', buffer_length);
- edit_buffer.cursor_pos = 0;
- edit_buffer.data_end = strlen(pinitstr);
- utuplim(edit_buffer.data_end, buffer_length - 1);
- memmove(edit_buffer.pbuffer, pinitstr,
- edit_buffer.data_end);
- edit_buffer.attribute = utnybbyt(back_attr, fore_attr);
- edit_buffer.control_flags = pfield_control->control_flags &
- (ED_INSERT_MODE | ED_WORD_WRAP);
- break;
-
- case ED_TRANSMIT:
- done = 1;
- error_code = ED_NO_ERROR;
- break;
- }
- }
- while (!done);
-
- if (pfield_control->control_flags & ED_WORD_WRAP)
- edreduce(&edit_buffer);
-
- if (pfinal_key != NIL)
- *pfinal_key = found_keyseq;
-
- utuplim(edit_buffer.data_end, target_size - 1);
- edit_buffer.pbuffer[edit_buffer.data_end] = '\0';
-
- /* Alter the buffer based on the control_flags */
- /* member of the pfield_control structure. The low */
- /* order byte is the conversion code to pass to */
- /* stpcvt(). The low order nybble of the high */
- /* order byte determines justification and fill */
- /* character. Note that if justification is */
- /* specified, blank fill is the default. Moreover, */
- /* left justification takes precendence over right */
- /* justification.
-
- if (error_code == ED_NO_ERROR) /* Only alter the buffer if */
- { /* normal transmission. */
-
- stpcvt(edit_buffer.pbuffer,
- pfield_control->control_flags & 0xff);
-
- /* Now justify the string if requested. Right */
- /* justification takes place within the entire edit */
- /* buffer field, but left justification just within */
- /* the string length. */
- if ((pfield_control->control_flags &
- (ED_LEFTJUST | ED_RIGHTJUST | ED_CENTERJUST)) != 0)
- {
- if ((pfield_control->control_flags & ED_ZERO_FILL) != 0)
- fill_char = '0';
- else
- fill_char = ' ';
-
- if ((pfield_control->control_flags & ED_LEFTJUST) != 0)
- just_code = -1;
- else
- if ((pfield_control->control_flags & ED_RIGHTJUST) != 0)
- just_code = 1;
- else
- just_code = 0;
-
- ptemp_buffer = malloc(buffer_length + 1);
- if (ptemp_buffer == NIL)
- {
- /* Error allocating temporary storage. */
- free(edit_buffer.pbuffer);
- if (ptemp_string != NIL)
- free(ptemp_string);
- return(ED_NO_MEMORY);
- }
- stpjust(ptemp_buffer, edit_buffer.pbuffer, fill_char,
- buffer_length, just_code);
- memmove(edit_buffer.pbuffer, ptemp_buffer, buffer_length + 1);
- free(ptemp_buffer);
- }
-
- }
- /* Now display any changes that were made to the */
- /* buffer. */
- nul_index = strlen(edit_buffer.pbuffer);
- memset(edit_buffer.pbuffer + nul_index, ' ',
- buffer_length - nul_index);
- write_rect(pdata, row, col,
- row + field_height - 1,
- col + field_width - 1,
- edit_buffer.pbuffer, fore_attr,
- back_attr, CHARS_ONLY);
- edit_buffer.pbuffer[nul_index] = '\0';
-
- /* Restore the original state of the cursor. */
- error = set_cursor(pdata, info.off, &info.size,
- info.row, info.col);
- if (error)
- {
- free(edit_buffer.pbuffer);
- if (ptemp_string != NIL)
- free(ptemp_string);
- return(error);
- }
-
- strcpy(pretstr, edit_buffer.pbuffer);
- free(edit_buffer.pbuffer);
- if (ptemp_string != NIL)
- free(ptemp_string);
-
- return(error_code);
- }