]> andersk Git - moira.git/blob - clients/userreg/display.c
when guessing kbd layout to tell user where the delete key is, check for
[moira.git] / clients / userreg / display.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Locker$
5  *      $Header$
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>.
10  */
11
12 #ifndef lint
13 static char *rcsid_display_c = "$Header$";
14 #endif  lint
15
16 #include <mit-copyright.h>
17 #include <stdio.h>
18 #include <curses.h>
19 #include <sys/time.h>
20 #include "userreg.h"
21
22 #define DESC_WIDTH 18
23 #define HEADER "*** Athena User Account Registration ***"
24 #if defined(vax) || defined(ultrix)
25 #define HELP   " Press the key above RETURN to delete a character.  Press Ctrl-C to start over."
26 #endif
27 #ifndef HELP
28 #define HELP   "    Press backspace to delete a character.  Press Ctrl-C to start over."
29 #endif
30 #define BORDER_CHAR '-'
31 #define MIN_COLS 80
32 #define MIN_LINES 24
33
34 WINDOW * displayw, *queryw;
35 WINDOW * dataw, *helpw;
36 WINDOW * fnamew, *midw, *lnamew, *idw, *loginw;
37
38 /* Set up the windows and subwindows on the display */
39 setup_display () {
40   FILE * freopen ();
41
42   initscr ();                   /* Start up curses */
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
49   noecho ();                    /* And the tty input */
50   raw ();
51   freopen ("/dev/null", "w", stderr);/* Toss the standard error output */
52
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 */
76 reset_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");
90   waddstr (dataw, "Family Name:\n");
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 */
105 make_border (l)
106 int   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 */
117 redisp () {
118   mvwprintw (fnamew, 0, 0, "%-24s", user.u_first);
119   wrefresh(fnamew);
120   mvwprintw (midw, 0, 0, "%-24s", user.u_mid_init);
121   wrefresh(midw);
122   mvwprintw (lnamew, 0, 0, "%-24s", user.u_last);
123   wrefresh(lnamew);
124   mvwprintw (idw, 0, 0, "%-24s", typed_mit_id);
125   wrefresh(idw);
126   mvwprintw (loginw, 0, 0, "%-24s", user.u_login);
127   wrefresh(loginw);
128 }
129
130
131 /* Input and input_no_echo exist only to save on retyping */
132 input (prompt, buf, maxsize, timeout, emptyok)
133 char *prompt;
134 char *buf;
135 int   maxsize, timeout, emptyok;
136 {
137   query_user (prompt, buf, maxsize, timeout, TRUE, emptyok, TRUE);
138 }
139
140 input_no_echo (prompt, buf, maxsize, timeout)
141 char *prompt;
142 char *buf;
143 int   maxsize, timeout;
144 {
145   query_user (prompt, buf, maxsize, timeout, FALSE, FALSE, TRUE);
146 }
147
148
149 /* make the user press any key to continue */
150 wait_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
159
160 /* Gets input through the query buffer */
161 /* Exit(1)'s on read errors */
162 /* Signals SIGALRM after 'timeout' seconds */
163 query_user (prompt, buf, maxsize, timeout, echop, emptyok, valuep)
164 char *prompt;
165 char *buf;
166 int   maxsize, timeout;
167 int echop, emptyok, valuep;
168 {
169   int  c;
170   int   i;
171   struct itimerval it;
172
173 retry:
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;
188   while ((c = getchar ()) != '\r' && c != '\n') {
189    switch (c) {
190      case '\025':               /* Ctl-U */
191         goto retry;
192       case EOF:
193         /* We're in raw mode, so EOF means disaster */
194         exit(1);
195         break;
196     delchar:
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 */
209         clear();
210         restore_display();
211         exit(0);
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     }
223     if (valuep && i >= maxsize) {
224       wfeep();
225       wprintw (displayw,
226   "You are not allowed to type more than %d characters for this answer.\n",
227           maxsize-1);
228       wrefresh (displayw);
229       goto delchar;
230     }
231  }
232
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   }
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
260 int
261 askyn(prompt)
262      char *prompt;
263 {
264   int ypos, xpos;
265   int answer;
266   struct itimerval it;
267   int c;
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     
285   while ((c = getchar ()) != '\r' && c != '\n') {       /* Wait for CR. */
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 */
316         clear();
317         restore_display();
318         exit(0);
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 */
336 display_text_line (line)
337 char *line;
338 {
339   if (line) {
340       waddstr (displayw, line);
341       waddch (displayw, '\n');
342   } else {
343       werase (displayw);
344   }
345   wrefresh (displayw);
346 }
347
348 /* Display_text displays a canned message from a file.  The string
349  * will get imbedded in any %s's in the text.
350  */
351 display_text(filename, string)
352 char *filename;
353 char *string;
354 {
355   FILE * fp;
356   char  buf[100], buf1[110];
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)) {
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');
370   }
371
372   wrefresh(displayw);
373   fclose (fp);
374 }
375
376 /* Clear_display wipes the display and turns off curses */
377 restore_display()
378 {
379   clear();
380   refresh();
381   noraw();
382   echo();
383   endwin();
384 }
385
386 timer_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
397 timer_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
408
409 wfeep()
410 {
411     char buf = '\007';
412     write(1, &buf, 1);
413 }
This page took 0.210974 seconds and 5 git commands to generate.