/****************************************************************************
- * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. *
+ * Copyright (c) 1998-2007,2008 Free Software Foundation, Inc. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the *
#include "form.priv.h"
-MODULE_ID("$Id: frm_driver.c,v 1.71 2005/10/01 19:42:40 tom Exp $")
+MODULE_ID("$Id: frm_driver.c,v 1.87 2008/07/12 21:24:07 tom Exp $")
/*----------------------------------------------------------------------------
This is the core module of the form library. It contains the majority
static int
fix_wchnstr(WINDOW *w, cchar_t *s, int n)
{
+ int x;
+
win_wchnstr(w, s, n);
+ /*
+ * This function is used to extract the text only from the window.
+ * Strip attributes and color from the string so they will not be added
+ * back when copying the string to the window.
+ */
+ for (x = 0; x < n; ++x)
+ {
+ RemAttr(s[x], A_ATTRIBUTES);
+ SetPair(s[x], 0);
+ }
return n;
}
|
| Return Values : Pointer to first non-blank position in buffer
+--------------------------------------------------------------------------*/
-INLINE static FIELD_CELL *
+NCURSES_INLINE static FIELD_CELL *
Get_Start_Of_Data(FIELD_CELL *buf, int blen)
{
FIELD_CELL *p = buf;
| Return Values : Pointer to position after last non-blank position in
| buffer.
+--------------------------------------------------------------------------*/
-INLINE static FIELD_CELL *
+NCURSES_INLINE static FIELD_CELL *
After_End_Of_Data(FIELD_CELL *buf, int blen)
{
FIELD_CELL *p = &buf[blen];
|
| Return Values : Pointer to first whitespace character in buffer.
+--------------------------------------------------------------------------*/
-INLINE static FIELD_CELL *
+NCURSES_INLINE static FIELD_CELL *
Get_First_Whitespace_Character(FIELD_CELL *buf, int blen)
{
FIELD_CELL *p = buf;
| Return Values : Pointer to position after last whitespace character in
| buffer.
+--------------------------------------------------------------------------*/
-INLINE static FIELD_CELL *
+NCURSES_INLINE static FIELD_CELL *
After_Last_Whitespace_Character(FIELD_CELL *buf, int blen)
{
FIELD_CELL *p = &buf[blen];
|
| Return Values : -
+--------------------------------------------------------------------------*/
-INLINE static void
+NCURSES_INLINE static void
Adjust_Cursor_Position(FORM *form, const FIELD_CELL *pos)
{
FIELD *field;
#if USE_WIDEC_SUPPORT
&& p->chars[1] == 0
#endif
- && AttrOf(*p) == ChAttrOf(pad))
+ )
*p = myBLANK;
}
}
|
| Return Values : -
+--------------------------------------------------------------------------*/
-INLINE static void
+NCURSES_INLINE static void
Synchronize_Buffer(FORM *form)
{
if (form->status & _WINDOW_MODIFIED)
result = TRUE; /* allow sharing of recovery on failure */
+ T((T_CREATE("fieldcell %p"), newbuf));
field->buf = newbuf;
for (i = 0; i <= field->nbuf; i++)
{
new_bp[new_buflen] = myZEROS;
}
-#if USE_WIDEC_SUPPORT
+#if USE_WIDEC_SUPPORT && NCURSES_EXT_FUNCS
if (wresize(field->working, 1, Buffer_Length(field) + 1) == ERR)
result = FALSE;
#endif
return (result);
}
+#ifdef NCURSES_MOUSE_VERSION
+/*---------------------------------------------------------------------------
+| Facility : libnform
+| Function : int Field_encloses(FIELD *field, int ry, int rx)
+|
+| Description : Check if the given coordinates lie within the given field.
+|
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form pointer
+| E_SYSTEM_ERROR - form has no current field or
+| field-window
++--------------------------------------------------------------------------*/
+static int
+Field_encloses(FIELD *field, int ry, int rx)
+{
+ T((T_CALLED("Field_encloses(%p)"), field));
+ if (field != 0
+ && field->frow <= ry
+ && (field->frow + field->rows) > ry
+ && field->fcol <= rx
+ && (field->fcol + field->cols) > rx)
+ {
+ RETURN(E_OK);
+ }
+ RETURN(E_INVALID_FIELD);
+}
+#endif
+
/*---------------------------------------------------------------------------
| Facility : libnform
| Function : int _nc_Position_Form_Cursor(FORM * form)
if (field->opts & O_VISIBLE)
Set_Field_Window_Attributes(field, win);
else
- wattrset(win, getattrs(fwin));
+ wattrset(win, WINDOW_ATTRS(fwin));
werase(win);
}
|
| Return Values : E_OK - success
| E_BAD_ARGUMENT - invalid field pointer
+| E_CURRENT - field is the current one
| E_SYSTEM_ERROR - some severe basic error
+--------------------------------------------------------------------------*/
NCURSES_EXPORT(int)
|
| Description : Make the newfield the new current field.
|
-| Return Values : E_OK - success
-| E_BAD_ARGUMENT - invalid form or field pointer
-| E_SYSTEM_ERROR - some severe basic error
+| Return Values : E_OK - success
+| E_BAD_ARGUMENT - invalid form or field pointer
+| E_SYSTEM_ERROR - some severe basic error
+| E_NOT_CONNECTED - no fields are connected to the form
+--------------------------------------------------------------------------*/
NCURSES_EXPORT(int)
_nc_Set_Current_Field(FORM *form, FIELD *newfield)
| Return Values : TRUE - there is enough space
| FALSE - there is not enough space
+--------------------------------------------------------------------------*/
-INLINE static bool
+NCURSES_INLINE static bool
Is_There_Room_For_A_Line(FORM *form)
{
FIELD *field = form->current;
| Return Values : TRUE - there is room
| FALSE - there is not enough room (line full)
+--------------------------------------------------------------------------*/
-INLINE static bool
+NCURSES_INLINE static bool
Is_There_Room_For_A_Char_In_Line(FORM *form)
{
int last_char_in_line;
* automatically (given the proper options). But we cannot eat the
* keystroke to back over the wrapping point, since that would put the
* cursor past the end of the form field. In this case, just delete the
- * character at the end of the field.
+ * character at the end of the field.
*/
if (form->currow == this_row && this_row > 0)
{
|
| Return Values : Pointer to the next field.
+--------------------------------------------------------------------------*/
-INLINE static FIELD *
+NCURSES_INLINE static FIELD *
Next_Field_On_Page(FIELD *field)
{
FORM *form = field->form;
|
| Return Values : Pointer to the previous field.
+--------------------------------------------------------------------------*/
-INLINE static FIELD *
+NCURSES_INLINE static FIELD *
Previous_Field_On_Page(FIELD *field)
{
FORM *form = field->form;
|
| Return Values : Pointer to the next field.
+--------------------------------------------------------------------------*/
-INLINE static FIELD *
+NCURSES_INLINE static FIELD *
Sorted_Next_Field(FIELD *field)
{
FIELD *field_on_page = field;
|
| Return Values : Pointer to the previous field.
+--------------------------------------------------------------------------*/
-INLINE static FIELD *
+NCURSES_INLINE static FIELD *
Sorted_Previous_Field(FIELD *field)
{
FIELD *field_on_page = field;
|
| Return Values : Pointer to left neighbor field.
+--------------------------------------------------------------------------*/
-INLINE static FIELD *
+NCURSES_INLINE static FIELD *
Left_Neighbor_Field(FIELD *field)
{
FIELD *field_on_page = field;
|
| Return Values : Pointer to right neighbor field.
+--------------------------------------------------------------------------*/
-INLINE static FIELD *
+NCURSES_INLINE static FIELD *
Right_Neighbor_Field(FIELD *field)
{
FIELD *field_on_page = field;
|
| Return Values : E_OK - success
| != E_OK - error from subordinate call
+| E_BAD_ARGUMENT - invalid field pointer
+| E_SYSTEM_ERROR - some severe basic error
+--------------------------------------------------------------------------*/
NCURSES_EXPORT(int)
_nc_Set_Form_Page(FORM *form, int page, FIELD *field)
|
| Return Values : The next page number
+--------------------------------------------------------------------------*/
-INLINE static int
+NCURSES_INLINE static int
Next_Page_Number(const FORM *form)
{
return (form->curpage + 1) % form->maxpage;
|
| Return Values : The previous page number
+--------------------------------------------------------------------------*/
-INLINE static int
+NCURSES_INLINE static int
Previous_Page_Number(const FORM *form)
{
return (form->curpage != 0 ? form->curpage - 1 : form->maxpage - 1);
| Description : Enter character c into at the current position of the
| current field of the form.
|
-| Return Values : E_OK -
-| E_REQUEST_DENIED -
+| Return Values : E_OK - success
+| E_REQUEST_DENIED - driver could not process the request
| E_SYSTEM_ERROR -
+--------------------------------------------------------------------------*/
static int
FIELD *field = form->current;
int result = E_REQUEST_DENIED;
- T((T_CALLED("Data_Entry(%p,%s)"), form, _tracechtype(c)));
+ T((T_CALLED("Data_Entry(%p,%s)"), form, _tracechtype((chtype)c)));
if ((field->opts & O_EDIT)
#if FIX_FORM_INACTIVE_BUG
&& (field->opts & O_ACTIVE)
| E_INVALID_FIELD - field contents are invalid
| E_BAD_STATE - called from inside a hook routine
| E_REQUEST_DENIED - request failed
+| E_NOT_CONNECTED - no fields are connected to the form
| E_UNKNOWN_COMMAND - command not known
+--------------------------------------------------------------------------*/
NCURSES_EXPORT(int)
NULL /* Choice Request is generic */
};
size_t nMethods = (sizeof(Generic_Methods) / sizeof(Generic_Methods[0]));
- size_t method = ((BI->keycode & ID_Mask) >> ID_Shft) & 0xffff;
+ size_t method = (BI->keycode >> ID_Shft) & 0xffff; /* see ID_Mask */
if ((method >= nMethods) || !(BI->cmd))
res = E_SYSTEM_ERROR;
res = (BI->cmd) (form);
}
}
+#ifdef NCURSES_MOUSE_VERSION
+ else if (KEY_MOUSE == c)
+ {
+ MEVENT event;
+ WINDOW *win = form->win ? form->win : stdscr;
+ WINDOW *sub = form->sub ? form->sub : win;
+
+ getmouse(&event);
+ if ((event.bstate & (BUTTON1_CLICKED |
+ BUTTON1_DOUBLE_CLICKED |
+ BUTTON1_TRIPLE_CLICKED))
+ && wenclose(win, event.y, event.x))
+ { /* we react only if the click was in the userwin, that means
+ * inside the form display area or at the decoration window.
+ */
+ int ry = event.y, rx = event.x; /* screen coordinates */
+
+ res = E_REQUEST_DENIED;
+ if (mouse_trafo(&ry, &rx, FALSE))
+ { /* rx, ry are now "curses" coordinates */
+ if (ry < sub->_begy)
+ { /* we clicked above the display region; this is
+ * interpreted as "scroll up" request
+ */
+ if (event.bstate & BUTTON1_CLICKED)
+ res = form_driver(form, REQ_PREV_FIELD);
+ else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
+ res = form_driver(form, REQ_PREV_PAGE);
+ else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
+ res = form_driver(form, REQ_FIRST_FIELD);
+ }
+ else if (ry > sub->_begy + sub->_maxy)
+ { /* we clicked below the display region; this is
+ * interpreted as "scroll down" request
+ */
+ if (event.bstate & BUTTON1_CLICKED)
+ res = form_driver(form, REQ_NEXT_FIELD);
+ else if (event.bstate & BUTTON1_DOUBLE_CLICKED)
+ res = form_driver(form, REQ_NEXT_PAGE);
+ else if (event.bstate & BUTTON1_TRIPLE_CLICKED)
+ res = form_driver(form, REQ_LAST_FIELD);
+ }
+ else if (wenclose(sub, event.y, event.x))
+ { /* Inside the area we try to find the hit item */
+ int i;
+
+ ry = event.y;
+ rx = event.x;
+ if (wmouse_trafo(sub, &ry, &rx, FALSE))
+ {
+ int min_field = form->page[form->curpage].pmin;
+ int max_field = form->page[form->curpage].pmax;
+
+ for (i = min_field; i <= max_field; ++i)
+ {
+ FIELD *field = form->field[i];
+
+ if (Field_Is_Selectable(field)
+ && Field_encloses(field, ry, rx) == E_OK)
+ {
+ res = _nc_Set_Current_Field(form, field);
+ if (res == E_OK)
+ res = _nc_Position_Form_Cursor(form);
+ if (res == E_OK
+ && (event.bstate & BUTTON1_DOUBLE_CLICKED))
+ res = E_UNKNOWN_COMMAND;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ res = E_REQUEST_DENIED;
+ }
+#endif /* NCURSES_MOUSE_VERSION */
else if (!(c & (~(int)MAX_REGULAR_CHARACTER)))
{
/*
wclear(field->working);
mvwaddstr(field->working, 0, 0, value);
- if ((widevalue = (FIELD_CELL *)calloc(len, sizeof(FIELD_CELL))) == 0)
+ if ((widevalue = typeCalloc(FIELD_CELL, len + 1)) == 0)
{
RETURN(E_SYSTEM_ERROR);
}
init_mb(state);
next = _nc_wcrtomb(0, data[n].chars[0], &state);
if (!isEILSEQ(next))
- {
- if (next != 0)
- need += next;
- }
+ need += next;
}
}
{
wclear(field->working);
mvwadd_wchnstr(field->working, 0, 0, data, size);
- mvwinnstr(field->working, 0, 0, result, (int)need + 1);
+ mvwinnstr(field->working, 0, 0, result, (int)need);
}
#else
result = Address_Of_Nth_Buffer(field, buffer);