📄 frm_driver.c
字号:
assert(buf && blen >= 0); while ((p > buf) && !ISBLANK(p[-1])) p--; return (p);}/* Set this to 1 to use the div_t version. This is a good idea if your compiler has an intrinsic div() support. Unfortunately GNU-C has it not yet. N.B.: This only works if form->curcol follows immediately form->currow and both are of type int.*/#define USE_DIV_T (0)/*---------------------------------------------------------------------------| Facility : libnform| Function : static void Adjust_Cursor_Position(| FORM * form, const char * pos)|| Description : Set current row and column of the form to values| corresponding to the buffer position.|| Return Values : -+--------------------------------------------------------------------------*/INLINE static voidAdjust_Cursor_Position(FORM *form, const FIELD_CELL *pos){ FIELD *field; int idx; field = form->current; assert(pos >= field->buf && field->dcols > 0); idx = (int)(pos - field->buf);#if USE_DIV_T *((div_t *) & (form->currow)) = div(idx, field->dcols);#else form->currow = idx / field->dcols; form->curcol = idx - field->cols * form->currow;#endif if (field->drows < form->currow) form->currow = 0;}/*---------------------------------------------------------------------------| Facility : libnform| Function : static void Buffer_To_Window(| const FIELD * field,| WINDOW * win)|| Description : Copy the buffer to the window. If it is a multi-line| field, the buffer is split to the lines of the| window without any editing.|| Return Values : -+--------------------------------------------------------------------------*/static voidBuffer_To_Window(const FIELD *field, WINDOW *win){ int width, height; int y, x; int len; int row; FIELD_CELL *pBuffer; assert(win && field); getyx(win, y, x); width = getmaxx(win); height = getmaxy(win); for (row = 0, pBuffer = field->buf; row < height; row++, pBuffer += width) { if ((len = (int)(After_End_Of_Data(pBuffer, width) - pBuffer)) > 0) { wmove(win, row, 0); myADDNSTR(win, pBuffer, len); } } wmove(win, y, x);}/*---------------------------------------------------------------------------| Facility : libnform| Function : static void Window_To_Buffer(| WINDOW * win,| FIELD * field)|| Description : Copy the content of the window into the buffer.| The multiple lines of a window are simply| concatenated into the buffer. Pad characters in| the window will be replaced by blanks in the buffer.|| Return Values : -+--------------------------------------------------------------------------*/static voidWindow_To_Buffer(WINDOW *win, FIELD *field){ int pad; int len = 0; FIELD_CELL *p; int row, height; assert(win && field && field->buf); pad = field->pad; p = field->buf; height = getmaxy(win); for (row = 0; (row < height) && (row < field->drows); row++) { wmove(win, row, 0); len += myINNSTR(win, p + len, field->dcols); } p[len] = myZEROS; /* replace visual padding character by blanks in buffer */ if (pad != C_BLANK) { int i; for (i = 0; i < len; i++, p++) { if ((unsigned long)CharOf(*p) == ChCharOf(pad)#if USE_WIDEC_SUPPORT && p->chars[1] == 0#endif && AttrOf(*p) == ChAttrOf(pad)) *p = myBLANK; } }}/*---------------------------------------------------------------------------| Facility : libnform| Function : static void Synchronize_Buffer(FORM * form)|| Description : If there was a change, copy the content of the| window into the buffer, so the buffer is synchronized| with the windows content. We have to indicate that the| buffer needs validation due to the change.|| Return Values : -+--------------------------------------------------------------------------*/INLINE static voidSynchronize_Buffer(FORM *form){ if (form->status & _WINDOW_MODIFIED) { form->status &= ~_WINDOW_MODIFIED; form->status |= _FCHECK_REQUIRED; Window_To_Buffer(form->w, form->current); wmove(form->w, form->currow, form->curcol); }}/*---------------------------------------------------------------------------| Facility : libnform| Function : static bool Field_Grown( FIELD *field, int amount)|| Description : This function is called for growable dynamic fields| only. It has to increase the buffers and to allocate| a new window for this field.| This function has the side effect to set a new| field-buffer pointer, the dcols and drows values| as well as a new current Window for the field.|| Return Values : TRUE - field successfully increased| FALSE - there was some error+--------------------------------------------------------------------------*/static boolField_Grown(FIELD *field, int amount){ bool result = FALSE; if (field && Growable(field)) { bool single_line_field = Single_Line_Field(field); int old_buflen = Buffer_Length(field); int new_buflen; int old_dcols = field->dcols; int old_drows = field->drows; FIELD_CELL *oldbuf = field->buf; FIELD_CELL *newbuf; int growth; FORM *form = field->form; bool need_visual_update = ((form != (FORM *)0) && (form->status & _POSTED) && (form->current == field)); if (need_visual_update) Synchronize_Buffer(form); if (single_line_field) { growth = field->cols * amount; if (field->maxgrow) growth = Minimum(field->maxgrow - field->dcols, growth); field->dcols += growth; if (field->dcols == field->maxgrow) field->status &= ~_MAY_GROW; } else { growth = (field->rows + field->nrow) * amount; if (field->maxgrow) growth = Minimum(field->maxgrow - field->drows, growth); field->drows += growth; if (field->drows == field->maxgrow) field->status &= ~_MAY_GROW; } /* drows, dcols changed, so we get really the new buffer length */ new_buflen = Buffer_Length(field); newbuf = (FIELD_CELL *)malloc(Total_Buffer_Size(field)); if (!newbuf) { /* restore to previous state */ field->dcols = old_dcols; field->drows = old_drows; if ((single_line_field && (field->dcols != field->maxgrow)) || (!single_line_field && (field->drows != field->maxgrow))) field->status |= _MAY_GROW; } else { /* Copy all the buffers. This is the reason why we can't just use * realloc(). */ int i, j; FIELD_CELL *old_bp; FIELD_CELL *new_bp; result = TRUE; /* allow sharing of recovery on failure */ field->buf = newbuf; for (i = 0; i <= field->nbuf; i++) { new_bp = Address_Of_Nth_Buffer(field, i); old_bp = oldbuf + i * (1 + old_buflen); for (j = 0; j < old_buflen; ++j) new_bp[j] = old_bp[j]; while (j < new_buflen) new_bp[j++] = myBLANK; new_bp[new_buflen] = myZEROS; }#if USE_WIDEC_SUPPORT if (wresize(field->working, 1, Buffer_Length(field) + 1) == ERR) result = FALSE;#endif if (need_visual_update && result) { WINDOW *new_window = newpad(field->drows, field->dcols); if (new_window != 0) { assert(form != (FORM *)0); if (form->w) delwin(form->w); form->w = new_window; Set_Field_Window_Attributes(field, form->w); werase(form->w); Buffer_To_Window(field, form->w); untouchwin(form->w); wmove(form->w, form->currow, form->curcol); } else result = FALSE; } if (result) { free(oldbuf); /* reflect changes in linked fields */ if (field != field->link) { FIELD *linked_field; for (linked_field = field->link; linked_field != field; linked_field = linked_field->link) { linked_field->buf = field->buf; linked_field->drows = field->drows; linked_field->dcols = field->dcols; } } } else { /* restore old state */ field->dcols = old_dcols; field->drows = old_drows; field->buf = oldbuf; if ((single_line_field && (field->dcols != field->maxgrow)) || (!single_line_field && (field->drows != field->maxgrow))) field->status |= _MAY_GROW; free(newbuf); } } } return (result);}/*---------------------------------------------------------------------------| Facility : libnform| Function : int _nc_Position_Form_Cursor(FORM * form)|| Description : Position the cursor in the window for the current| field to be in sync. with the currow and curcol| values.|| Return Values : E_OK - success| E_BAD_ARGUMENT - invalid form pointer| E_SYSTEM_ERROR - form has no current field or| field-window+--------------------------------------------------------------------------*/NCURSES_EXPORT(int)_nc_Position_Form_Cursor(FORM *form){ FIELD *field; WINDOW *formwin; if (!form) return (E_BAD_ARGUMENT); if (!form->w || !form->current) return (E_SYSTEM_ERROR); field = form->current; formwin = Get_Form_Window(form); wmove(form->w, form->currow, form->curcol); if (Has_Invisible_Parts(field)) { /* in this case fieldwin isn't derived from formwin, so we have to move the cursor in formwin by hand... */ wmove(formwin, field->frow + form->currow - form->toprow, field->fcol + form->curcol - form->begincol); wcursyncup(formwin); } else wcursyncup(form->w); return (E_OK);}/*---------------------------------------------------------------------------| Facility : libnform| Function : int _nc_Refresh_Current_Field(FORM * form)|| Description : Propagate the changes in the fields window to the| window of the form.|| Return Values : E_OK - on success| E_BAD_ARGUMENT - invalid form pointer| E_SYSTEM_ERROR - general error+--------------------------------------------------------------------------*/NCURSES_EXPORT(int)_nc_Refresh_Current_Field(FORM *form){ WINDOW *formwin; FIELD *field; T((T_CALLED("_nc_Refresh_Current_Field(%p)"), form)); if (!form) RETURN(E_BAD_ARGUMENT); if (!form->w || !form->current) RETURN(E_SYSTEM_ERROR); field = form->current; formwin = Get_Form_Window(form); if (field->opts & O_PUBLIC) { if (Is_Scroll_Field(field)) { /* Again, in this case the fieldwin isn't derived from formwin, so we have to perform a copy operation. */ if (Single_Line_Field(field)) { /* horizontal scrolling */ if (form->curcol < form->begincol) form->begincol = form->curcol; else { if (form->curcol >= (form->begincol + field->cols)) form->begincol = form->curcol - field->cols + 1; } copywin(form->w, formwin, 0, form->begincol, field->frow, field->fcol, field->frow, field->cols + field->fcol - 1, 0); } else { /* A multi-line, i.e. vertical scrolling field */ int row_after_bottom, first_modified_row, first_unmodified_row; if (field->drows > field->rows) { row_after_bottom = form->toprow + field->rows; if (form->currow < form->toprow) { form->toprow = form->currow;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -