|
|
1.1 root 1: /*
2: * Screen driver functions connected with wgetLoc().
3: */
4: #include <scn.h>
5: #include <longfield.h>
6:
7: #define CTRL(c) (c - '@')
8: WINDOW *errWindow = NULL;
9: static int errSw; /* clear errWindow at next stdscn input */
10: static needsTouch; /* needs touchwin at next stdscn input */
11: static savC; /* exit char for recursion */
12:
13: /*
14: * loc.field may be a char * or a char **
15: * return the char *.
16: */
17: static char *
18: fieldPtr(f) register loc *f;
19: {
20: return ((f->flags & LONGFIELD) ? *((char **)f->field) : f->field);
21: }
22:
23: static void
24: longField(f) loc *f;
25: {
26: register loc *l; /* tmp area pointer */
27: register char *q, *new;
28: WINDOW *w;
29: char **p, **d;
30: int j, len, same;
31:
32: if (NULL == (w = newwin(8, 80, 0, 0)))
33: fatal("Cannot open subwindow");
34:
35: touchwin(w);
36: p = (char **)f->field;
37: d = (char **)f->Default;
38: same = (*p == *d); /* is field == default */
39:
40: /* zero work fields */
41: for (l = longfield_locs; NULL != (q = l->field); l++) {
42: l->help = f->help;
43: memset(q, '\0', l->len);
44: }
45:
46: /* move in defaults */
47: if (NULL != (new = *d)) {
48: for (l = longfield_locs; NULL != (q = l->field); l++) {
49: for (j = 0; *new && (j < l->len); j++)
50: *q++ = *new++;
51: }
52: free(*p);
53: }
54:
55: wscnDriv(w, longfield_data, longfield_locs);
56:
57: for (len = 1, l = longfield_locs; NULL != (q = l->field); l++)
58: len += strlen(q);
59:
60: *p = new = alloc(len);
61: if (same)
62: *d = new;
63:
64: for (l = longfield_locs; NULL != (q = l->field); l++)
65: strcat(new, q);
66:
67: delwin(w);
68: }
69:
70: /*
71: * Show any error.
72: */
73: void
74: showError(s)
75: char *s;
76: {
77: char work[80];
78:
79: if (NULL == errWindow)
80: fatal("No error window");
81: sprintf(work, "Error: %r", &s);
82: wmove(errWindow, 0, 0);
83: wstandout(errWindow);
84: waddstr(errWindow, work);
85: wstandend(errWindow);
86: wrefresh(errWindow);
87: errSw = 1;
88: }
89:
90: /*
91: * Show a help message if one exists.
92: */
93: showHelp(msg)
94: char *msg;
95: {
96: if (NULL != errWindow) {
97: wmove(errWindow, 1, 0);
98: wclrtoeol(errWindow);
99: if (NULL != msg) {
100: wmove(errWindow, 1, 0);
101: waddstr(errWindow, msg);
102: }
103: wrefresh(errWindow);
104: }
105: }
106:
107: /*
108: * Get a char from screen, Erase error window if not clear.
109: */
110: static
111: wgetChr(w) register WINDOW *w;
112: {
113: register c;
114:
115: if (needsTouch) {
116: needsTouch = 0;
117: if (stdscr == w) {
118: touchwin(w);
119: wrefresh(w);
120: }
121: }
122:
123: c = wgetch(w);
124:
125: if (errSw) {
126: wmove(errWindow, 0, 0);
127: wclrtoeol(errWindow);
128: wrefresh(errWindow);
129: errSw = 0;
130: }
131: return (c);
132: }
133:
134:
135: /*
136: * if sw == 0: Display a fields default copy to field, then get it.
137: * if sw == 1: Display field's default.
138: * if sw == 2: Display field.
139: */
140: static
141: wgetLoc(w, f, sw) register WINDOW *w; register loc *f; int sw;
142: {
143: int got, /* number of chars processed */
144: c, /* current char */
145: y, x, /* cursor loc */
146: i, /* pos in Default field */
147: state; /* 1 == ESC sequence in process */
148: char *field, *def;
149:
150: wmove(w, y = f->row, x = f->col);
151:
152: /*
153: * LONGFIELD is defined as 4
154: */
155: switch ((f->flags & LONGFIELD) | sw) {
156: case 6: /* display long field */
157: def = *((char **)f->field); /* we have ptr to ptr */
158: break;
159:
160: case 4: /* get long field */
161: wstandout(w); /* remind user which */
162:
163: case 5: /* display long field default */
164: def = *((char **)f->Default); /* we have ptr to ptr */
165: break;
166:
167: case 2: /* display short field */
168: def = f->field;
169: break;
170:
171: case 1: /* display short field default */
172: def = f->Default;
173: break;
174:
175: case 0: /* get short field */
176: def = f->Default;
177: field = f->field;
178:
179: /* copy Default into field and zero fill */
180: for (got = i = 0; got <= f->len; got++) {
181: if (c = def[i])
182: i++;
183: field[got] = c;
184: }
185: }
186:
187: /* display whatever */
188: if (NULL == def)
189: def = "";
190: for (got = i = 0; got < f->len; got++) {
191: if (c = def[i]) {
192: i++;
193: waddch(w, c);
194: }
195: else
196: waddch(w, ' ');
197: }
198:
199: if (f->flags & LONGFIELD)
200: wstandend(w);
201:
202: refresh();
203:
204: if (sw || (f->flags & READONLY)) /* display or read only */
205: return (0);
206:
207: if (f->flags & LONGFIELD) {
208: longField(f); /* this calls wgetLoc indirectly */
209:
210: wmove(w, y, x);
211: field = *((char **)f->field);
212: for (got = 0; got < f->len; got++) {
213: if (c = *field) {
214: field++;
215: waddch(w, c);
216: }
217: else
218: waddch(w, ' ');
219: }
220:
221: /*
222: * Doing touchwin here makes a wierd flashing
223: * when there are many long fields.
224: * Set a switch instead.
225: */
226: needsTouch = 1;
227: wrefresh(w);
228: return(savC); /* return the last thing returned by wgetLoc */
229: }
230:
231: showHelp(f->help);
232:
233: wmove(w, y, x);
234:
235: for (state = got = 0; got < f->len; ) {
236: wrefresh(w);
237: c = wgetChr(w);
238: /*
239: * Up Arrow key is esc [ A
240: * on some systems and
241: * esc A on others.
242: */
243: if (state) { /* got an escape */
244: switch (c) {
245: case '[':
246: continue;
247: case 'A':
248: c = CTRL('P');
249: break;
250: case 'B':
251: c = CTRL('N');
252: break;
253: case 'C':
254: c = CTRL('F');
255: break;
256: case 'D':
257: c = CTRL('B');
258: break;
259: }
260: state = 0;
261: }
262:
263: switch (c) {
264: case CTRL('['):
265: state = 1;
266: continue;
267: case '\r': /* close out line */
268: case '\n':
269: field[got] = '\0';
270: for (; got < f->len; got++)
271: waddch(w, ' ');
272: continue;
273: case '\b': /* backspace */
274: if (!got)
275: continue;
276: got--;
277: wmove(w, y, --x);
278: case CTRL('D'):
279: case 127: /* delete key */
280: if (!field[got])
281: continue;
282: for (i = got; c = field[i] = field[i + 1]; i++)
283: waddch(w, c);
284: waddch(w, ' ');
285:
286: wmove(w, y, x);
287: continue;
288: case CTRL('B'): /* back one char */
289: if (!got)
290: continue;
291: wmove(w, y, --x);
292: got--;
293: continue;
294: case CTRL('P'): /* go to previous field */
295: case '\t': /* go to next field with verify */
296: case CTRL('N'): /* go to next field */
297: case CTRL('Z'): /* end of screen */
298: wrefresh(w);
299: return (c);
300: case CTRL('C'): /* Give user a chance to kill */
301: userCtlc();
302: continue;
303: case CTRL('A'): /* beginning of line */
304: wmove(w, y = f->row, x = f->col);
305: got = 0;
306: continue;
307: case CTRL('E'): /* end of line */
308: while (field[got]) {
309: got++;
310: x++;
311: }
312: while (got >= f->len) { /* don't trigger end of field */
313: got--;
314: x--;
315: }
316: wmove(w, y, x);
317: continue;
318: case CTRL('F'): /* forward one char */
319: if (!(c = field[got]))
320: continue;
321: default:
322: waddch(w, c);
323: x++;
324: field[got++] = c;
325: c = 0;
326: }
327: }
328: field[got] = '\0';
329: wrefresh(w);
330: return (c);
331: }
332:
333: /*
334: * Show all default items.
335: */
336: void
337: wshowDefs(w, data, fields) WINDOW *w; backGrnd *data; loc *fields;
338: {
339: register loc *f;
340:
341: wshowBak(w, data);
342:
343: for (f = fields; NULL != f->field; f++)
344: wgetLoc(w, f, 1);
345: }
346:
347: /*
348: * Print background and get all fields.
349: */
350: void
351: wscnDriv(w, data, fields) WINDOW *w; backGrnd *data; loc *fields;
352: {
353: wclear(w);
354: wshowBak(w, data);
355: wgetAll(w, fields);
356: }
357:
358: /*
359: * Get all fields on a given screen.
360: * allow emacs style navagation.
361: */
362: void
363: wgetAll(w, fields) WINDOW *w; loc *fields;
364: {
365: register loc *f;
366: char c;
367:
368: for (c = 0; c != CTRL('Z'); ) {
369: for (f = fields; (c != CTRL('Z')) && (NULL != f->field); f++) {
370: switch (c = wgetLoc(w, f, 0)) {
371: case CTRL('Z'):
372: if (w != stdscr) {
373: savC = c;
374: return;
375: }
376: break;
377: case CTRL('N'):
378: /* at end down with true field */
379: if ((f[1].field == NULL) && (w != stdscr)) {
380: savC = c;
381: return;
382: }
383: break;
384: case CTRL('P'):
385: for (;;) {
386: if (f == fields) { /* wrap */
387: /* back out of true field */
388: if (w != stdscr) {
389: savC = c;
390: return;
391: }
392: while (NULL != f->field)
393: f++;
394: }
395: if (!((--f)->flags & READONLY))
396: --f;
397: break;
398: }
399: break;
400: default:
401: switch ((*f->verify)(fieldPtr(f))) {
402: case -2:
403: savC = ' ';
404: return;
405: case -1:
406: if (f->skipf) {
407: f += f->skipf;
408: break;
409: }
410: case 0:
411: f--;
412: break;
413: }
414: }
415: }
416: }
417:
418: /* verify all fields */
419: for (f = fields; NULL != f->field; f++) {
420: switch ((*f->verify)(fieldPtr(f))) {
421: case -2:
422: return;
423: case -1:
424: if (f->skipf) {
425: f += f->skipf;
426: break;
427: }
428: case 0:
429: c = wgetLoc(w, f, 0);
430: f--;
431: break;
432: }
433: }
434: }
435:
436: /*
437: * Get a field by field location.
438: */
439: wgetField(w, table, field) WINDOW *w; loc *table; char *field;
440: {
441: register loc *f;
442:
443: for (f = table; NULL != f->field; f++)
444: if (field == fieldPtr(f))
445: return (wgetLoc(w, f, 0));
446: fatal("Invalid use of getField");
447: }
448:
449: /*
450: * Put a field by field location.
451: */
452: void
453: wputField(w, table, field) WINDOW *w; loc *table; char *field;
454: {
455: register loc *f;
456:
457: for (f = table; NULL != f->field; f++)
458: if (field == fieldPtr(f)) {
459: wgetLoc(w, f, 2);
460: return;
461: }
462: fatal("Invalid use of putField");
463: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.