xref: /freebsd/contrib/ncurses/form/frm_data.c (revision 7937bfbc0ca53fe7cdd0d54414f9296e273a518e)
1 /****************************************************************************
2  * Copyright 2020,2021 Thomas E. Dickey                                     *
3  * Copyright 1998-2010,2013 Free Software Foundation, Inc.                  *
4  *                                                                          *
5  * Permission is hereby granted, free of charge, to any person obtaining a  *
6  * copy of this software and associated documentation files (the            *
7  * "Software"), to deal in the Software without restriction, including      *
8  * without limitation the rights to use, copy, modify, merge, publish,      *
9  * distribute, distribute with modifications, sublicense, and/or sell       *
10  * copies of the Software, and to permit persons to whom the Software is    *
11  * furnished to do so, subject to the following conditions:                 *
12  *                                                                          *
13  * The above copyright notice and this permission notice shall be included  *
14  * in all copies or substantial portions of the Software.                   *
15  *                                                                          *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23  *                                                                          *
24  * Except as contained in this notice, the name(s) of the above copyright   *
25  * holders shall not be used in advertising or otherwise to promote the     *
26  * sale, use or other dealings in this Software without prior written       *
27  * authorization.                                                           *
28  ****************************************************************************/
29 
30 /****************************************************************************
31  *   Author:  Juergen Pfeifer, 1995,1997                                    *
32  ****************************************************************************/
33 
34 #include "form.priv.h"
35 
36 MODULE_ID("$Id: frm_data.c,v 1.21 2021/06/17 21:11:08 tom Exp $")
37 
38 /*---------------------------------------------------------------------------
39 |   Facility      :  libnform
40 |   Function      :  bool data_behind(const FORM *form)
41 |
42 |   Description   :  Check for off-screen data behind. This is nearly trivial
43 |                    because the beginning of a field is fixed.
44 |
45 |   Return Values :  TRUE   - there are off-screen data behind
46 |                    FALSE  - there are no off-screen data behind
47 +--------------------------------------------------------------------------*/
48 FORM_EXPORT(bool)
49 data_behind(const FORM *form)
50 {
51   bool result = FALSE;
52 
53   T((T_CALLED("data_behind(%p)"), (const void *)form));
54 
55   if (form && (form->status & _POSTED) && form->current)
56     {
57       FIELD *field;
58 
59       field = form->current;
60       if (!Single_Line_Field(field))
61 	{
62 	  result = (form->toprow == 0) ? FALSE : TRUE;
63 	}
64       else
65 	{
66 	  result = (form->begincol == 0) ? FALSE : TRUE;
67 	}
68     }
69   returnBool(result);
70 }
71 
72 /*---------------------------------------------------------------------------
73 |   Facility      :  libnform
74 |   Function      :  static char * Only_Padding(
75 |                                    WINDOW *w,
76 |                                    int len,
77 |                                    int pad)
78 |
79 |   Description   :  Test if 'length' cells starting at the current position
80 |                    contain a padding character.
81 |
82 |   Return Values :  true if only padding cells are found
83 +--------------------------------------------------------------------------*/
84 NCURSES_INLINE static bool
85 Only_Padding(WINDOW *w, int len, int pad)
86 {
87   bool result = TRUE;
88   int y, x, j;
89   FIELD_CELL cell;
90 
91   getyx(w, y, x);
92   for (j = 0; j < len; ++j)
93     {
94       if (wmove(w, y, x + j) != ERR)
95 	{
96 #if USE_WIDEC_SUPPORT
97 	  if (win_wch(w, &cell) != ERR)
98 	    {
99 	      if ((chtype)CharOf(cell) != ChCharOf(pad)
100 		  || cell.chars[1] != 0)
101 		{
102 		  result = FALSE;
103 		  break;
104 		}
105 	    }
106 #else
107 	  cell = (FIELD_CELL)winch(w);
108 	  if (ChCharOf(cell) != ChCharOf(pad))
109 	    {
110 	      result = FALSE;
111 	      break;
112 	    }
113 #endif
114 	}
115       else
116 	{
117 	  /* if an error, return true: no non-padding text found */
118 	  break;
119 	}
120     }
121   /* no need to reset the cursor position; caller does this */
122   return result;
123 }
124 
125 /*---------------------------------------------------------------------------
126 |   Facility      :  libnform
127 |   Function      :  bool data_ahead(const FORM *form)
128 |
129 |   Description   :  Check for off-screen data ahead. This is more difficult
130 |                    because a dynamic field has a variable end.
131 |
132 |   Return Values :  TRUE   - there are off-screen data ahead
133 |                    FALSE  - there are no off-screen data ahead
134 +--------------------------------------------------------------------------*/
135 FORM_EXPORT(bool)
136 data_ahead(const FORM *form)
137 {
138   bool result = FALSE;
139 
140   T((T_CALLED("data_ahead(%p)"), (const void *)form));
141 
142   if (form && (form->status & _POSTED) && form->current)
143     {
144       FIELD *field;
145       bool cursor_moved = FALSE;
146       int pos;
147 
148       field = form->current;
149       assert(form->w);
150 
151       if (Single_Line_Field(field))
152 	{
153 	  pos = form->begincol + field->cols;
154 	  while (pos < field->dcols)
155 	    {
156 	      int check_len = field->dcols - pos;
157 
158 	      if (check_len >= field->cols)
159 		check_len = field->cols;
160 	      cursor_moved = TRUE;
161 	      wmove(form->w, 0, pos);
162 	      if (Only_Padding(form->w, check_len, field->pad))
163 		pos += field->cols;
164 	      else
165 		{
166 		  result = TRUE;
167 		  break;
168 		}
169 	    }
170 	}
171       else
172 	{
173 	  pos = form->toprow + field->rows;
174 	  while (pos < field->drows)
175 	    {
176 	      cursor_moved = TRUE;
177 	      wmove(form->w, pos, 0);
178 	      pos++;
179 	      if (!Only_Padding(form->w, field->cols, field->pad))
180 		{
181 		  result = TRUE;
182 		  break;
183 		}
184 	    }
185 	}
186 
187       if (cursor_moved)
188 	wmove(form->w, form->currow, form->curcol);
189     }
190   returnBool(result);
191 }
192 
193 /* frm_data.c ends here */
194