1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2002-2006 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
48 const char *inputhelp
[] = {
49 "UP/DOWN/LEFT/RIGHT - position cursor",
50 " CTRL-A - move cursor to the beginning of line",
51 " CTRL-E - move cursor to the end of line",
52 " CTRL-B - move cursor to previous word",
53 " CTRL-W - move cursor to next word",
54 " CTRL-X - delete word under cursor",
55 " CTRL-K - delete from cursor to end of line",
56 " CTRL-U - clear entire input field",
57 " BACKSPACE - delete previous character",
58 " ESCAPE - quit without changes",
59 " ENTER - quit with changes",
63 static bool validate_pgn_tag_name(int c
, const void *arg
)
65 if (!isalnum(c
) && c
!= '_')
71 static bool validate_pgn_date(int c
, const void *arg
)
73 if (!isdigit(c
) && c
!= '.' && c
!= '?')
79 static bool validate_pgn_round(int c
, const void *arg
)
81 if (!isdigit(c
) && c
!= '.' && c
!= '-' && c
!= '?')
88 * This function prompts for input. The init argument is the initial value.
89 * The lines argument is how many lines the field is. If zero, then it is
90 * dynamically determined based on the init argument or INPUT_WIDTH if init is
93 * The reset argument is whether pressing ESC returns the initial value or
96 * The extra_help argument is an extra line of help prompt normally used with
97 * the custom_func argument. The custom_func argument is a pointer to a
98 * function of type void which takes one pointer-to-void argument. This
99 * function is called when the ckey argument is pressed.
101 * The type argument is the type of validation for the input defined in
102 * common.h. Remaining arguments are values for the type argument. See
103 * field_type(3X) for validation types.
105 * FIXME form validation is buggy (integers).
107 char *get_input(const char *title
, const char *init
, int lines
, int reset
,
108 const char *extra_help
, char *(*custom_func
)(void *), void *arg
,
109 chtype ckey
, int type
, ...)
118 static char dst
[MAX_PGN_LINE_LEN
];
121 FIELDTYPE
*TYPE_PGN_TAG_NAME
;
122 FIELDTYPE
*TYPE_PGN_DATE
;
123 FIELDTYPE
*TYPE_PGN_ROUND
;
126 bzero(dst
, sizeof(dst
));
129 width
= (len
+ 4 > INPUT_WIDTH
&& len
+ 4 < COLS
- 2) ?
130 len
+ 4 : INPUT_WIDTH
;
132 fields
[0] = new_field((lines
) ? lines
: sizeof(dst
) / width
+ 1,
133 width
- 2, 0, 0, 0, 0);
136 field_opts_off(fields
[0], O_STATIC
);
138 TYPE_PGN_TAG_NAME
= new_fieldtype(NULL
, validate_pgn_tag_name
);
139 TYPE_PGN_DATE
= new_fieldtype(NULL
, validate_pgn_date
);
140 TYPE_PGN_ROUND
= new_fieldtype(NULL
, validate_pgn_round
);
145 case FIELD_TYPE_PGN_ROUND
:
146 set_field_type(fields
[0], TYPE_PGN_ROUND
);
148 case FIELD_TYPE_PGN_DATE
:
149 set_field_type(fields
[0], TYPE_PGN_DATE
);
151 case FIELD_TYPE_PGN_TAG_NAME
:
152 set_field_type(fields
[0], TYPE_PGN_TAG_NAME
);
154 case FIELD_TYPE_ALNUM
:
155 set_field_type(fields
[0], TYPE_ALNUM
, va_arg(ap
, int));
157 case FIELD_TYPE_ALPHA
:
158 set_field_type(fields
[0], TYPE_ALPHA
, va_arg(ap
, int));
160 case FIELD_TYPE_ENUM
:
161 set_field_type(fields
[0], TYPE_ENUM
, va_arg(ap
, char **),
162 va_arg(ap
, int), va_arg(ap
, int));
164 case FIELD_TYPE_INTEGER
:
165 set_field_type(fields
[0], TYPE_INTEGER
, va_arg(ap
, int),
166 va_arg(ap
, long), va_arg(ap
, long));
168 case FIELD_TYPE_NUMERIC
:
169 set_field_type(fields
[0], TYPE_NUMERIC
, va_arg(ap
, int),
170 va_arg(ap
, double), va_arg(ap
, double));
172 case FIELD_TYPE_REGEXP
:
173 set_field_type(fields
[0], TYPE_REGEXP
, va_arg(ap
, char *));
175 case FIELD_TYPE_IPV4
:
176 set_field_type(fields
[0], TYPE_IPV4
);
185 set_field_buffer(fields
[0], 0, init
);
187 field_opts_off(fields
[0], O_BLANK
|O_AUTOSKIP
);
189 form
= new_form(fields
);
190 form_opts_off(form
, O_BS_OVERLOAD
);
192 scale_form(form
, &y
, &x
);
194 win
= newwin((extra_help
) ? y
+ 5 : y
+ 4, x
+ 2,
195 CALCPOSY(((extra_help
) ? y
+ 5 : y
+ 4)), CALCPOSX(x
));
196 set_form_win(form
, win
);
197 swin
= derwin(win
, y
, x
, 2, 1);
198 set_form_sub(form
, swin
);
205 panel
= new_panel(win
);
206 wbkgd(win
, CP_INPUT_WINDOW
);
207 draw_window_title(win
, title
, width
, CP_INPUT_TITLE
, CP_INPUT_BORDER
);
210 draw_prompt(win
, y
+ 2, width
, extra_help
, CP_INPUT_PROMPT
);
212 draw_prompt(win
, (extra_help
) ? y
+ 3 : y
+ 2, width
, INPUT_HELP_PROMPT
,
215 form_driver(form
, REQ_END_FIELD
);
225 if (c
== ckey
&& custom_func
) {
226 form_driver(form
, REQ_VALIDATION
);
228 if ((tmp
= custom_func(arg
)) != NULL
) {
229 set_field_buffer(fields
[0], 0, tmp
);
230 form_driver(form
, REQ_END_LINE
);
238 form_driver(form
, REQ_DEL_WORD
);
241 form_driver(form
, REQ_PREV_WORD
);
244 form_driver(form
, REQ_NEXT_WORD
);
247 form_driver(form
, REQ_BEG_LINE
);
250 form_driver(form
, REQ_END_LINE
);
253 form_driver(form
, REQ_CLR_EOL
);
256 form_driver(form
, REQ_CLR_FIELD
);
259 help(INPUT_HELP_TITLE
, ANYKEY
, inputhelp
);
262 form_driver(form
, REQ_LEFT_CHAR
);
265 form_driver(form
, REQ_RIGHT_CHAR
);
268 form_driver(form
, REQ_UP_CHAR
);
271 form_driver(form
, REQ_DOWN_CHAR
);
275 form_driver(form
, REQ_DEL_PREV
);
285 form_driver(form
, (c
& A_CHARTEXT
));
286 form_driver(form
, REQ_VALIDATION
);
298 set_field_buffer(fields
[0], 0, init
);
301 form_driver(form
, REQ_VALIDATION
);
302 tmp
= trim(field_buffer(fields
[0], 0));
304 /* Remove multiple whitespace. Happens on a multiline field. */
306 for (i
= 0, n
= 0; i
< strlen(tmp
); i
++) {
307 if (isspace(tmp
[i
]) && isspace(tmp
[i
+ 1]))
318 dst
[sizeof(dst
) - 1] = 0;
324 for (i
= 0; fields
[i
]; i
++)
325 free_field(fields
[i
]);
330 free_fieldtype(TYPE_PGN_TAG_NAME
);
331 free_fieldtype(TYPE_PGN_DATE
);
332 free_fieldtype(TYPE_PGN_ROUND
);
337 return (dst
[0]) ? dst
: NULL
;