1/****************************************************************************
2 * Copyright 2018-2021,2024 Thomas E. Dickey                                *
3 * Copyright 1998-2016,2017 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/* $Id: form.priv.h,v 0.49 2024/02/24 12:17:31 tom Exp $ */
35
36#ifndef FORM_PRIV_H
37#define FORM_PRIV_H 1
38/* *INDENT-OFF*/
39#include "curses.priv.h"
40
41#define NCURSES_OPAQUE_FORM  0
42
43#include "mf_common.h"
44
45#if USE_WIDEC_SUPPORT
46#if HAVE_WCTYPE_H
47#include <wctype.h>
48#endif
49
50#define FIELD_CELL NCURSES_CH_T
51
52#define NCURSES_FIELD_INTERNALS char** expanded; WINDOW *working;
53#define NCURSES_FIELD_EXTENSION , (char **)0, (WINDOW *)0
54
55#else
56
57#define FIELD_CELL char
58
59#define NCURSES_FIELD_EXTENSION /* nothing */
60
61#endif
62
63#include "form.h"
64
65	/***********************
66	*   Default objects    *
67	***********************/
68extern FORM_EXPORT_VAR(FORM *)      _nc_Default_Form;
69extern FORM_EXPORT_VAR(FIELD *)     _nc_Default_Field;
70extern FORM_EXPORT_VAR(FIELDTYPE *) _nc_Default_FieldType;
71
72/* form  status values */
73#define _OVLMODE         (0x04U) /* Form is in overlay mode                */
74#define _WINDOW_MODIFIED (0x10U) /* Current field window has been modified */
75#define _FCHECK_REQUIRED (0x20U) /* Current field needs validation         */
76
77/* field status values */
78#define _CHANGED         (0x01U) /* Field has been changed                 */
79#define _NEWTOP          (0x02U) /* Vertical scrolling occurred            */
80#define _NEWPAGE         (0x04U) /* field begins new page of form          */
81#define _MAY_GROW        (0x08U) /* dynamic field may still grow           */
82
83/* fieldtype status values */
84#define _LINKED_TYPE     (0x01U) /* Type is a linked type                  */
85#define _HAS_ARGS        (0x02U) /* Type has arguments                     */
86#define _HAS_CHOICE      (0x04U) /* Type has choice methods                */
87#define _RESIDENT        (0x08U) /* Type is built-in                       */
88#define _GENERIC         (0x10U) /* A generic field type                   */
89
90/* This are the field options required to be a selectable field in field
91   navigation requests */
92#define O_SELECTABLE (O_ACTIVE | O_VISIBLE)
93
94/* If form is NULL replace form argument by default-form */
95#define Normalize_Form(form) \
96  ((form) = (form != 0) ? (form) : _nc_Default_Form)
97
98/* If field is NULL replace field argument by default-field */
99#define Normalize_Field(field) \
100  ((field) = (field != 0) ? (field) : _nc_Default_Field)
101
102#if NCURSES_SP_FUNCS
103#define Get_Form_Screen(form) \
104  ((form)->win ? _nc_screen_of((form->win)):CURRENT_SCREEN)
105#else
106#define Get_Form_Screen(form) CURRENT_SCREEN
107#endif
108
109/* Retrieve form's window */
110#define Get_Form_Window(form) \
111  ((form)->sub \
112   ? (form)->sub \
113   : ((form)->win \
114      ? (form)->win \
115      : StdScreen(Get_Form_Screen(form))))
116
117/* Calculate the size for a single buffer for this field */
118#define Buffer_Length(field) ((field)->drows * (field)->dcols)
119
120/* Calculate the total size of all buffers for this field */
121#define Total_Buffer_Size(field) \
122   ( (size_t)(Buffer_Length(field) + 1) * (size_t)(1+(field)->nbuf) * sizeof(FIELD_CELL) )
123
124/* Logic to determine whether or not a field is single lined */
125#define Single_Line_Field(field) \
126   (((field)->rows + (field)->nrow) == 1)
127
128#define Field_Has_Option(f,o)      ((((unsigned)(f)->opts) & o) != 0)
129
130/* Logic to determine whether or not a field is selectable */
131#define Field_Is_Selectable(f)     (((unsigned)((f)->opts) & O_SELECTABLE)==O_SELECTABLE)
132#define Field_Is_Not_Selectable(f) (((unsigned)((f)->opts) & O_SELECTABLE)!=O_SELECTABLE)
133
134typedef struct typearg
135  {
136    struct typearg *left;
137    struct typearg *right;
138  }
139TypeArgument;
140
141/* This is a dummy request code (normally invalid) to be used internally
142   with the form_driver() routine to position to the first active field
143   on the form
144*/
145#define FIRST_ACTIVE_MAGIC (-291056)
146
147#define ALL_FORM_OPTS  (                \
148			O_NL_OVERLOAD  |\
149			O_BS_OVERLOAD   )
150
151#define STD_FIELD_OPTS (Field_Options)( \
152			O_VISIBLE |\
153			O_ACTIVE  |\
154			O_PUBLIC  |\
155			O_EDIT    |\
156			O_WRAP    |\
157			O_BLANK   |\
158			O_AUTOSKIP|\
159			O_NULLOK  |\
160			O_PASSOK  |\
161			O_STATIC)
162
163#define ALL_FIELD_OPTS (Field_Options)( \
164			STD_FIELD_OPTS |\
165			O_DYNAMIC_JUSTIFY |\
166			O_NO_LEFT_STRIP |\
167			O_EDGE_INSERT_STAY |\
168			O_INPUT_LIMIT)
169
170#define C_BLANK ' '
171#define is_blank(c) ((c)==C_BLANK)
172
173#define C_ZEROS '\0'
174
175extern FORM_EXPORT(TypeArgument *) _nc_Make_Argument (const FIELDTYPE*, va_list*, int*);
176extern FORM_EXPORT(TypeArgument *) _nc_Copy_Argument (const FIELDTYPE*, const TypeArgument*, int*);
177extern FORM_EXPORT(void) _nc_Free_Argument (const FIELDTYPE*, TypeArgument*);
178extern FORM_EXPORT(bool) _nc_Copy_Type (FIELD*, FIELD const *);
179extern FORM_EXPORT(void) _nc_Free_Type (FIELD *);
180
181extern FORM_EXPORT(int) _nc_Synchronize_Attributes (FIELD*);
182extern FORM_EXPORT(int) _nc_Synchronize_Options (FIELD*, Field_Options);
183extern FORM_EXPORT(int) _nc_Set_Form_Page (FORM*, int, FIELD*);
184extern FORM_EXPORT(int) _nc_Refresh_Current_Field (FORM*);
185extern FORM_EXPORT(FIELD *) _nc_First_Active_Field (FORM*);
186extern FORM_EXPORT(bool) _nc_Internal_Validation (FORM*);
187extern FORM_EXPORT(int) _nc_Set_Current_Field (FORM*, FIELD*);
188extern FORM_EXPORT(int) _nc_Position_Form_Cursor (FORM*);
189extern FORM_EXPORT(void) _nc_Unset_Current_Field(FORM *form);
190
191#if NCURSES_INTEROP_FUNCS
192extern FORM_EXPORT(FIELDTYPE *) _nc_TYPE_INTEGER(void);
193extern FORM_EXPORT(FIELDTYPE *) _nc_TYPE_ALNUM(void);
194extern FORM_EXPORT(FIELDTYPE *) _nc_TYPE_ALPHA(void);
195extern FORM_EXPORT(FIELDTYPE *) _nc_TYPE_ENUM(void);
196extern FORM_EXPORT(FIELDTYPE *) _nc_TYPE_NUMERIC(void);
197extern FORM_EXPORT(FIELDTYPE *) _nc_TYPE_REGEXP(void);
198extern FORM_EXPORT(FIELDTYPE *) _nc_TYPE_IPV4(void);
199
200extern FORM_EXPORT(FIELDTYPE *)
201_nc_generic_fieldtype(bool (*const field_check) (FORM*,
202						 FIELD *,
203						 const void *),
204		      bool (*const char_check)  (int,
205						 FORM*,
206						 FIELD*,
207						 const void *),
208		      bool (*const next)(FORM*,FIELD*,const void*),
209		      bool (*const prev)(FORM*,FIELD*,const void*),
210		      void (*freecallback)(void*));
211extern FORM_EXPORT(int) _nc_set_generic_fieldtype(FIELD*, FIELDTYPE*, int (*)(void**));
212extern FORM_EXPORT(WINDOW*) _nc_form_cursor(const FORM* , int* , int* );
213
214#define INIT_FT_FUNC(func) {func}
215#else
216#define INIT_FT_FUNC(func) func
217#endif
218
219extern FORM_EXPORT(void) _nc_get_fieldbuffer(FORM*, FIELD*, FIELD_CELL*);
220
221#if USE_WIDEC_SUPPORT
222extern FORM_EXPORT(wchar_t *) _nc_Widen_String(char *, int *);
223#endif
224
225#ifdef TRACE
226
227#define returnField(code)	TRACE_RETURN1(code,field)
228#define returnFieldPtr(code)	TRACE_RETURN1(code,field_ptr)
229#define returnForm(code)	TRACE_RETURN1(code,form)
230#define returnFieldType(code)	TRACE_RETURN1(code,field_type)
231#define returnFormHook(code)	TRACE_RETURN1(code,form_hook)
232
233extern FORM_EXPORT(FIELD **)	    _nc_retrace_field_ptr (FIELD **);
234extern FORM_EXPORT(FIELD *)	    _nc_retrace_field (FIELD *);
235extern FORM_EXPORT(FIELDTYPE *)  _nc_retrace_field_type (FIELDTYPE *);
236extern FORM_EXPORT(FORM *)       _nc_retrace_form (FORM *);
237extern FORM_EXPORT(Form_Hook)    _nc_retrace_form_hook (Form_Hook);
238
239#else /* !TRACE */
240
241#define returnFieldPtr(code)	return code
242#define returnFieldType(code)	return code
243#define returnField(code)	return code
244#define returnForm(code)	return code
245#define returnFormHook(code)	return code
246
247#endif /* TRACE/!TRACE */
248
249/*
250 * Use Check_CTYPE_Field() to simplify FIELDTYPE's that use only the ccheck()
251 * function.
252 */
253#if USE_WIDEC_SUPPORT
254#define Check_CTYPE_Field(result, buffer, width, ccheck) \
255  while (*buffer && *buffer == ' ') \
256    buffer++; \
257  if (*buffer) \
258    { \
259      bool blank = FALSE; \
260      int len; \
261      int n; \
262      wchar_t *list = _nc_Widen_String((char *)buffer, &len); \
263      if (list != 0) \
264	{ \
265	  result = TRUE; \
266	  for (n = 0; n < len; ++n) \
267	    { \
268	      if (blank) \
269		{ \
270		  if (list[n] != ' ') \
271		    { \
272		      result = FALSE; \
273		      break; \
274		    } \
275		} \
276	      else if (list[n] == ' ') \
277		{ \
278		  blank = TRUE; \
279		  result = (n + 1 >= width); \
280		} \
281	      else if (!ccheck(list[n], NULL)) \
282		{ \
283		  result = FALSE; \
284		  break; \
285		} \
286	    } \
287	  free(list); \
288	} \
289    }
290#else
291#define Check_CTYPE_Field(result, buffer, width, ccheck) \
292  while (*buffer && *buffer == ' ') \
293    buffer++; \
294  if (*buffer) \
295    { \
296      unsigned char *s = buffer; \
297      int l = -1; \
298      while (*buffer && ccheck(*buffer, NULL)) \
299	buffer++; \
300      l = (int)(buffer - s); \
301      while (*buffer && *buffer == ' ') \
302	buffer++; \
303      result = ((*buffer || (l < width)) ? FALSE : TRUE); \
304    }
305#endif
306/* *INDENT-ON*/
307
308#endif /* FORM_PRIV_H */
309