]> andersk Git - moira.git/blame - clients/userreg/display.c
when guessing kbd layout to tell user where the delete key is, check for
[moira.git] / clients / userreg / display.c
CommitLineData
989a2c2c 1/*
2 * $Source$
3 * $Author$
4 * $Locker$
5 * $Header$
7189310c 6 *
7 * (c) Copyright 1988 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, please see the file
9 * <mit-copyright.h>.
989a2c2c 10 */
11
12#ifndef lint
13static char *rcsid_display_c = "$Header$";
14#endif lint
15
7189310c 16#include <mit-copyright.h>
989a2c2c 17#include <stdio.h>
18#include <curses.h>
19#include <sys/time.h>
20#include "userreg.h"
21
22#define DESC_WIDTH 18
a2b4a2ee 23#define HEADER "*** Athena User Account Registration ***"
aa6d3350 24#if defined(vax) || defined(ultrix)
56a47022 25#define HELP " Press the key above RETURN to delete a character. Press Ctrl-C to start over."
94464a85 26#endif
759f815b 27#ifndef HELP
a2b4a2ee 28#define HELP " Press backspace to delete a character. Press Ctrl-C to start over."
94464a85 29#endif
989a2c2c 30#define BORDER_CHAR '-'
31#define MIN_COLS 80
32#define MIN_LINES 24
33
34WINDOW * displayw, *queryw;
35WINDOW * dataw, *helpw;
36WINDOW * fnamew, *midw, *lnamew, *idw, *loginw;
37
38/* Set up the windows and subwindows on the display */
39setup_display () {
40 FILE * freopen ();
41
42 initscr (); /* Start up curses */
989a2c2c 43
44 if (COLS < MIN_COLS || LINES < MIN_LINES) {
45 fprintf (stderr, "Screen must be at least %d x %d\n", MIN_LINES, MIN_COLS);
46 exit (1);
47 }
48
94464a85 49 noecho (); /* And the tty input */
50 raw ();
51 freopen ("/dev/null", "w", stderr);/* Toss the standard error output */
52
989a2c2c 53 /* Make sure the place is clean */
54 clear ();
55
56 /* Set up the top-level windows */
57 /* First line is the header */
58 displayw = subwin (stdscr, 12, 0, 2, 0);/* Lines 2-13 */
59 scrollok (displayw, TRUE);
60
61 queryw = subwin (stdscr, 1, 0, 15, 0);/* Line 15 */
62 scrollok (queryw, TRUE);
63
64 dataw = subwin (stdscr, 5, 0, 17, 0);/* Lines 17-21 */
65
66 /* Set up the data windows */
67 fnamew = subwin (stdscr, 1, 0, 17, DESC_WIDTH);
68 midw = subwin (stdscr, 1, 0, 18, DESC_WIDTH);
69 lnamew = subwin (stdscr, 1, 0, 19, DESC_WIDTH);
70 idw = subwin (stdscr, 1, 0, 20, DESC_WIDTH);
71 loginw = subwin (stdscr, 1, 0, 21, DESC_WIDTH);
72
73}
74
75/* Clear and restore the display */
76reset_display () {
77 clear ();
78
79 /* Put back the borders */
80 make_border (1);
81 make_border (14);
82 make_border (16);
83 make_border (22);
84
85
86 /* Put in the window dressing */
87 wmove (dataw, 0, 0);
88 waddstr (dataw, "First Name:\n");
89 waddstr (dataw, "Middle Initial:\n");
4127ae1e 90 waddstr (dataw, "Family Name:\n");
989a2c2c 91 waddstr (dataw, "MIT ID #:\n\n");
92 waddstr (dataw, "Username:\n");
93 wclrtoeol (dataw);
94
95 /* Set up the header */
96 mvaddstr (0, (COLS - strlen (HEADER)) / 2, HEADER);
97 mvaddstr (23, 0, HELP);
98
99 /* Put it all up */
100 refresh ();
101}
102
103
104/* Make a one-line border on line l of stdscr */
105make_border (l)
106int l;
107{
108 int i;
109
110 move (l, 0);
111 for (i = 0; i < COLS - 1; i++) {
112 addch (BORDER_CHAR);
113 }
114}
115
116/* This replaces several "useful" display functions in the old userreg */
117redisp () {
118 mvwprintw (fnamew, 0, 0, "%-24s", user.u_first);
e6b3a349 119 wrefresh(fnamew);
989a2c2c 120 mvwprintw (midw, 0, 0, "%-24s", user.u_mid_init);
e6b3a349 121 wrefresh(midw);
989a2c2c 122 mvwprintw (lnamew, 0, 0, "%-24s", user.u_last);
e6b3a349 123 wrefresh(lnamew);
989a2c2c 124 mvwprintw (idw, 0, 0, "%-24s", typed_mit_id);
e6b3a349 125 wrefresh(idw);
989a2c2c 126 mvwprintw (loginw, 0, 0, "%-24s", user.u_login);
e6b3a349 127 wrefresh(loginw);
989a2c2c 128}
129
130
131/* Input and input_no_echo exist only to save on retyping */
4127ae1e 132input (prompt, buf, maxsize, timeout, emptyok)
989a2c2c 133char *prompt;
134char *buf;
4127ae1e 135int maxsize, timeout, emptyok;
989a2c2c 136{
4127ae1e 137 query_user (prompt, buf, maxsize, timeout, TRUE, emptyok, TRUE);
989a2c2c 138}
139
140input_no_echo (prompt, buf, maxsize, timeout)
141char *prompt;
142char *buf;
143int maxsize, timeout;
144{
4127ae1e 145 query_user (prompt, buf, maxsize, timeout, FALSE, FALSE, TRUE);
989a2c2c 146}
147
148
4127ae1e 149/* make the user press any key to continue */
150wait_for_user ()
151{
152 char buf[BUFSIZ];
153
154 redisp();
155 query_user ("Press RETURN or ENTER to continue", buf, 1,
156 15 * 60, FALSE, TRUE, FALSE);
157}
158
989a2c2c 159
160/* Gets input through the query buffer */
161/* Exit(1)'s on read errors */
162/* Signals SIGALRM after 'timeout' seconds */
4127ae1e 163query_user (prompt, buf, maxsize, timeout, echop, emptyok, valuep)
989a2c2c 164char *prompt;
165char *buf;
166int maxsize, timeout;
e6b3a349 167int echop, emptyok, valuep;
989a2c2c 168{
8b2d95d4 169 int c;
989a2c2c 170 int i;
171 struct itimerval it;
172
173retry:
174 /* Set up interval timer */
175 it.it_interval.tv_sec = 0;
176 it.it_interval.tv_usec = 0;
177 it.it_value.tv_sec = timeout;
178 it.it_value.tv_usec = 0;
179 setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
180
181 /* Erase the query window and put up a prompt */
182 werase (queryw);
183 mvwaddstr (queryw, 0, 0, prompt);
184 waddch (queryw, ' '); /* Put in a space, as Blox does */
185 wrefresh (queryw);
186
187 i = 0;
e6b3a349 188 while ((c = getchar ()) != '\r' && c != '\n') {
989a2c2c 189 switch (c) {
190 case '\025': /* Ctl-U */
191 goto retry;
989a2c2c 192 case EOF:
193 /* We're in raw mode, so EOF means disaster */
194 exit(1);
195 break;
56a47022 196 delchar:
989a2c2c 197 case '\177': /* Delete */
198 case '\010': /* Backspace */
199 if (i) {
200 i--;
201 if (echop) {
202 wmove (queryw, queryw -> _cury, queryw -> _curx - 1);
203 wclrtoeol (queryw);
204 wrefresh (queryw);
205 }
206 }
207 break;
208 case '\003': /* Ctrl-C */
8556c987 209 clear();
210 restore_display();
211 exit(0);
989a2c2c 212 break;
213 default:
214 if (c >= ' ') { /* Ignore all other control chars */
215 buf[i++] = c;
216 if (echop) {
217 waddch (queryw, c);
218 wrefresh (queryw);
219 }
220 }
221 break;
222 }
4127ae1e 223 if (valuep && i >= maxsize) {
56a47022 224 wfeep();
989a2c2c 225 wprintw (displayw,
226 "You are not allowed to type more than %d characters for this answer.\n",
56a47022 227 maxsize-1);
989a2c2c 228 wrefresh (displayw);
56a47022 229 goto delchar;
989a2c2c 230 }
231 }
232
4127ae1e 233 if (i == 0) {
234 if (emptyok && valuep &&
235 (askyn("Do you really want this field left blank (y/n)? ") == NO))
236 goto retry;
237 if (!emptyok) {
238 wprintw(displayw, "You must enter something here.\n");
239 wrefresh(displayw);
240 goto retry;
241 }
242 }
989a2c2c 243
244
245 /* Input is complete so disable interval timer. */
246 it.it_interval.tv_sec = 0;
247 it.it_interval.tv_usec = 0;
248 it.it_value.tv_sec = 0;
249 it.it_value.tv_usec = 0;
250 setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
251
252 buf[i] = '\0'; /* Put a null on the end */
253
254 werase (queryw); /* Clean up the query window */
255 wrefresh (queryw);
256
257 return; /* And get out of here. */
258}
259
260int
261askyn(prompt)
262 char *prompt;
263{
264 int ypos, xpos;
265 int answer;
266 struct itimerval it;
8b2d95d4 267 int c;
989a2c2c 268
269 start:
270 werase (queryw);
271 mvwaddstr (queryw, 0, 0, prompt);
272 wrefresh (queryw);
273
274 xpos = queryw->_curx;
275 ypos = queryw->_cury;
276 answer = 2; /* No answer. */
277
278 /* Reset interval timer for y/n question. */
279 it.it_interval.tv_sec = 0;
280 it.it_interval.tv_usec = 0;
281 it.it_value.tv_sec = YN_TIMEOUT;
282 it.it_value.tv_usec = 0;
283 setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
284
e6b3a349 285 while ((c = getchar ()) != '\r' && c != '\n') { /* Wait for CR. */
989a2c2c 286 switch (c) {
287 case 'n': /* No. */
288 case 'N':
289 wmove(queryw, ypos, xpos);
290 wclrtoeol(queryw);
291 waddstr(queryw, "no");
292 wrefresh(queryw);
293 answer = NO;
294 continue;
295 case 'y': /* Yes. */
296 case 'Y':
297 wmove(queryw, ypos, xpos);
298 wclrtoeol(queryw);
299 waddstr(queryw, "yes");
300 wrefresh(queryw);
301 answer = YES;
302 continue;
303 case '\177': /* Delete */
304 case '\010': /* Backspace */
305 case '\025': /* Ctl-U */
306 wmove(queryw, ypos, xpos);
307 wclrtoeol(queryw);
308 wrefresh(queryw);
309 answer = 2; /* No answer. */
310 break;
311 case EOF:
312 /* We're in raw mode, so EOF means disaster */
313 exit(1);
314 break;
315 case '\003': /* Ctrl-C */
8556c987 316 clear();
317 restore_display();
318 exit(0);
989a2c2c 319 break;
320 default: /* Ignore everything else. */
321 break;
322 }
323 }
324
325 if (answer == 2) /* No answer. */
326 { display_text_line(0);
327 display_text_line("Please answer y or n.");
328 goto start;
329 }
330
331 return(answer);
332}
333
334/* Display_text_line puts up a line of text in the display window */
335/* Special case: if line is 0, clear the display area */
336display_text_line (line)
337char *line;
338{
339 if (line) {
a2b4a2ee 340 waddstr (displayw, line);
341 waddch (displayw, '\n');
342 } else {
343 werase (displayw);
989a2c2c 344 }
345 wrefresh (displayw);
346}
347
a2b4a2ee 348/* Display_text displays a canned message from a file. The string
349 * will get imbedded in any %s's in the text.
350 */
351display_text(filename, string)
989a2c2c 352char *filename;
a2b4a2ee 353char *string;
989a2c2c 354{
355 FILE * fp;
a2b4a2ee 356 char buf[100], buf1[110];
989a2c2c 357
358 werase (displayw);
359 if ((fp = fopen (filename, "r")) == NULL) {
360 wprintw (displayw, "Can't open file %s for reading.\n", filename);
361 return;
362 }
363
364 while (fgets (buf, 100, fp)) {
a2b4a2ee 365 /* get rid of the newline */
366 buf[strlen (buf) - 1] = 0;
367 sprintf(buf1, buf, string);
368 waddstr(displayw, buf1);
369 waddch(displayw, '\n');
989a2c2c 370 }
371
a2b4a2ee 372 wrefresh(displayw);
989a2c2c 373 fclose (fp);
374}
375
376/* Clear_display wipes the display and turns off curses */
377restore_display()
378{
379 clear();
380 refresh();
381 noraw();
382 echo();
383 endwin();
384}
385
386timer_on()
387{
388 struct itimerval it;
389
390 it.it_interval.tv_sec = 0;
391 it.it_interval.tv_usec = 0;
392 it.it_value.tv_sec = TIMER_TIMEOUT;
393 it.it_value.tv_usec = 0;
394 setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
395}
396
397timer_off()
398{
399 struct itimerval it;
400
401 it.it_interval.tv_sec = 0;
402 it.it_interval.tv_usec = 0;
403 it.it_value.tv_sec = 0;
404 it.it_value.tv_usec = 0;
405 setitimer (ITIMER_REAL, &it, (struct itimerval *) 0);
406}
407
4127ae1e 408
409wfeep()
410{
411 char buf = '\007';
412 write(1, &buf, 1);
413}
This page took 0.137955 seconds and 5 git commands to generate.