Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / gtx / frame.c
blob620be0a3b9f356e0f7bc8ea198d627adb1a86a7c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
10 #include <afsconfig.h>
11 #include <afs/param.h>
12 #include <afs/stds.h>
14 #ifdef AFS_HPUX_ENV
15 #include <sys/types.h>
16 #endif
17 #include <lwp.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #ifdef HAVE_STDINT_H
22 #include <stdint.h>
23 #endif
24 #include "gtxobjects.h"
25 #include "gtxwindows.h"
26 #include "gtxcurseswin.h"
27 #include "gtxinput.h"
28 #include "gtxkeymap.h"
29 #include "gtxframe.h"
31 static struct keymap_map *recursiveMap = 0;
32 static char menubuffer[1024]; /*Buffer for menu selections */
33 int gtxframe_exitValue = 0; /*Program exit value */
35 int
36 gtxframe_CtrlUCmd(void *aparam, void *arock)
38 struct gwin *awindow = (struct gwin *) aparam;
39 struct gtx_frame *tframe;
41 tframe = awindow->w_frame;
42 if (!tframe->defaultLine)
43 return -1;
44 *(tframe->defaultLine) = 0;
45 return 0;
48 int
49 gtxframe_CtrlHCmd(void *aparam, void *arock)
51 struct gwin *awindow = (struct gwin *) aparam;
53 struct gtx_frame *tframe;
54 char *tp;
55 int pos;
57 tframe = awindow->w_frame;
58 if (!(tp = tframe->defaultLine))
59 return -1;
60 pos = strlen(tp);
61 if (pos == 0)
62 return 0; /* rubout at the end of the line */
63 tp[pos - 1] = 0;
64 return 0;
67 int
68 gtxframe_RecursiveEndCmd(void *aparam, void *arock)
70 struct gwin *awindow = (struct gwin *) aparam;
72 struct gtx_frame *tframe;
74 tframe = awindow->w_frame;
75 tframe->flags |= GTXFRAME_RECURSIVEEND;
76 tframe->flags &= ~GTXFRAME_RECURSIVEERR;
77 return 0;
80 int
81 gtxframe_RecursiveErrCmd(void *aparam, void *arock)
83 struct gwin *awindow = (struct gwin *) aparam;
85 struct gtx_frame *tframe;
87 tframe = awindow->w_frame;
88 tframe->flags |= GTXFRAME_RECURSIVEEND;
89 tframe->flags |= GTXFRAME_RECURSIVEERR;
90 return 0;
93 int
94 gtxframe_SelfInsertCmd(void *aparam, void *rockparam)
96 struct gwin *awindow = (struct gwin *) aparam;
98 int arock = (intptr_t)rockparam;
100 struct gtx_frame *tframe;
101 int pos;
102 char *tp;
104 tframe = awindow->w_frame;
105 if (!(tp = tframe->defaultLine))
106 return -1;
107 pos = strlen(tp);
108 tp[pos] = arock; /* arock has char to insert */
109 tp[pos + 1] = 0; /* null-terminate it, too */
110 return 0;
113 /* save map, setup recursive map and install it */
114 static int
115 SaveMap(struct gtx_frame *aframe)
117 char tstring[2];
118 int i;
120 if (!recursiveMap) {
121 /* setup recursive edit map if not previously done */
122 recursiveMap = keymap_Create();
123 keymap_BindToString(recursiveMap, "\010", gtxframe_CtrlHCmd, NULL,
124 NULL);
125 keymap_BindToString(recursiveMap, "\177", gtxframe_CtrlHCmd, NULL,
126 NULL);
127 keymap_BindToString(recursiveMap, "\025", gtxframe_CtrlUCmd, NULL,
128 NULL);
129 keymap_BindToString(recursiveMap, "\033", gtxframe_RecursiveEndCmd,
130 NULL, NULL);
131 keymap_BindToString(recursiveMap, "\015", gtxframe_RecursiveEndCmd,
132 NULL, NULL);
133 keymap_BindToString(recursiveMap, "\012", gtxframe_RecursiveEndCmd,
134 NULL, NULL);
135 keymap_BindToString(recursiveMap, "\003", gtxframe_RecursiveErrCmd,
136 NULL, NULL);
137 keymap_BindToString(recursiveMap, "\007", gtxframe_RecursiveErrCmd,
138 NULL, NULL);
140 for (i = 040; i < 0177; i++) {
141 tstring[0] = i;
142 tstring[1] = 0;
143 keymap_BindToString(recursiveMap, tstring, gtxframe_SelfInsertCmd,
144 NULL, (void *)(intptr_t)i);
147 aframe->savemap = aframe->keymap;
148 aframe->keymap = recursiveMap;
149 keymap_InitState(aframe->keystate, aframe->keymap);
150 return 0;
153 /* Restore map to previous value */
154 static int
155 RestoreMap(struct gtx_frame *aframe)
157 aframe->keymap = aframe->savemap;
158 aframe->savemap = (struct keymap_map *)0;
159 keymap_InitState(aframe->keystate, aframe->keymap);
160 return 0;
164 gtxframe_SetFrame(struct gwin *awin, struct gtx_frame *aframe)
166 if (awin->w_frame) {
167 /* Unthread this frame */
168 awin->w_frame->window = NULL;
170 awin->w_frame = aframe;
171 aframe->window = awin; /* Set frame's window ptr */
172 return 0;
175 struct gtx_frame *
176 gtxframe_GetFrame(struct gwin *awin)
178 return awin->w_frame;
181 /* Add a menu string to display list */
183 gtxframe_AddMenu(struct gtx_frame *aframe, char *alabel, char *astring)
185 struct gtxframe_menu *tmenu;
187 if (aframe->menus)
188 for (tmenu = aframe->menus; tmenu; tmenu = tmenu->next) {
189 if (strcmp(alabel, tmenu->name) == 0)
190 break;
191 } else
192 tmenu = (struct gtxframe_menu *)0;
193 if (!tmenu) {
194 /* Handle everything but the command string, which is handled by the
195 * common-case code below */
196 tmenu = (struct gtxframe_menu *)malloc(sizeof(*tmenu));
197 if (tmenu == (struct gtxframe_menu *)0)
198 return (-1);
199 memset(tmenu, 0, sizeof(*tmenu));
200 tmenu->next = aframe->menus;
201 aframe->menus = tmenu;
202 tmenu->name = gtx_CopyString(alabel);
206 * Common case: redo the string labels. Note: at this point, tmenu
207 * points to a valid menu.
209 if (tmenu->cmdString)
210 free(tmenu->cmdString);
211 tmenu->cmdString = gtx_CopyString(astring);
212 return 0;
215 /* Delete a given menu from a frame*/
217 gtxframe_DeleteMenu(struct gtx_frame *aframe, char *alabel)
219 struct gtxframe_menu *tm, **lm;
221 for (lm = &aframe->menus, tm = *lm; tm; lm = &tm->next, tm = *lm) {
222 if (strcmp(alabel, tm->name) == 0) {
223 /* found it, remove and return success */
224 *lm = tm->next; /* unthread from list */
225 free(tm->name);
226 free(tm->cmdString);
227 free(tm);
228 return (0);
231 return (-1); /* failed to find entry to delete */
234 /* Function to remove all known menus */
236 gtxframe_ClearMenus(struct gtx_frame *aframe)
239 struct gtxframe_menu *tm, *nm;
241 if (aframe->menus != (struct gtxframe_menu *)0) {
242 for (tm = aframe->menus; tm; tm = nm) {
243 nm = tm->next;
244 free(tm->name);
245 free(tm->cmdString);
246 free(tm);
250 aframe->menus = (struct gtxframe_menu *)0;
251 return 0;
255 gtxframe_AskForString(struct gtx_frame *aframe, char *aprompt,
256 char *adefault, char *aresult, int aresultSize)
258 int code;
259 char *tp;
261 /* Ensure recursive-edit map is initialized */
262 SaveMap(aframe);
264 /* Set up display */
265 if (aframe->promptLine)
266 free(aframe->promptLine);
267 if (aframe->defaultLine)
268 free(aframe->defaultLine);
269 aframe->promptLine = gtx_CopyString(aprompt);
270 tp = aframe->defaultLine = (char *)malloc(1024);
271 if (tp == NULL)
272 return (-1);
273 if (adefault)
274 strcpy(tp, adefault);
275 else
276 *tp = 0;
278 /* Do recursive edit */
279 gtx_InputServer(aframe->window);
280 tp = aframe->defaultLine; /* In case command reallocated it */
282 /* Back from recursive edit, check out what's happened */
283 if (aframe->flags & GTXFRAME_RECURSIVEERR) {
284 code = -1;
285 goto done;
287 code = strlen(tp);
288 if (code + 1 > aresultSize) {
289 code = -2;
290 goto done;
292 strcpy(aresult, tp);
293 code = 0;
295 /* Fall through to cleanup and return code */
296 done:
297 RestoreMap(aframe);
298 if (aframe->promptLine)
299 free(aframe->promptLine);
300 if (aframe->defaultLine)
301 free(aframe->defaultLine);
302 aframe->defaultLine = aframe->promptLine = NULL;
303 if (code)
304 gtxframe_DisplayString(aframe, "[Aborted]");
305 return (code);
309 gtxframe_DisplayString(struct gtx_frame *aframe, char *amsgLine)
311 if (aframe->messageLine)
312 free(aframe->messageLine);
313 aframe->messageLine = gtx_CopyString(amsgLine);
314 return 0;
317 /* Called by input processor to try to clear the dude */
319 gtxframe_ClearMessageLine(struct gtx_frame *aframe)
321 /* If we haven't shown message long enough yet, just return */
322 if (aframe->flags & GTXFRAME_NEWDISPLAY)
323 return (0);
324 if (aframe->messageLine)
325 free(aframe->messageLine);
326 aframe->messageLine = NULL;
327 return (0);
330 static int
331 ShowMessageLine(struct gtx_frame *aframe)
333 struct gwin_strparams strparms;
334 struct gwin_sizeparams sizeparms;
335 char *tp;
337 if (!aframe->window)
338 return -1;
340 /* First, find window size */
341 WOP_GETDIMENSIONS(aframe->window, &sizeparms);
343 if (aframe->promptLine) {
344 memset(&strparms, 0, sizeof(strparms));
345 strparms.x = 0;
346 strparms.y = sizeparms.maxy - 1;
347 strparms.highlight = 1;
348 tp = strparms.s = (char *)malloc(1024);
349 strcpy(tp, aframe->promptLine);
350 strcat(tp, aframe->defaultLine);
351 WOP_DRAWSTRING(aframe->window, &strparms);
352 aframe->flags |= GTXFRAME_NEWDISPLAY;
353 } else if (aframe->messageLine) {
354 /* Otherwise we're visible, print the message at the bottom */
355 memset(&strparms, 0, sizeof(strparms));
356 strparms.highlight = 1;
357 strparms.x = 0;
358 strparms.y = sizeparms.maxy - 1;
359 strparms.s = aframe->messageLine;
360 WOP_DRAWSTRING(aframe->window, &strparms);
361 aframe->flags |= GTXFRAME_NEWDISPLAY;
363 return (0);
366 /* Exit function, returning whatever has been put in its argument */
368 gtxframe_ExitCmd(void *a_exitValuep, void *arock)
369 { /*gtxframe_ExitCmd */
371 int exitval; /*Value we've been asked to exit with */
373 /* This next call should be type independent! */
374 gator_cursesgwin_cleanup(&gator_basegwin);
376 exitval = *((int *)(a_exitValuep));
377 exit(exitval);
379 } /*gtxframe_ExitCmd */
381 struct gtx_frame *
382 gtxframe_Create(void)
384 struct gtx_frame *tframe;
385 struct keymap_map *newkeymap;
386 struct keymap_state *newkeystate;
389 * Allocate all the pieces first: frame, keymap, and key state.
391 tframe = (struct gtx_frame *)malloc(sizeof(struct gtx_frame));
392 if (tframe == (struct gtx_frame *)0) {
393 return ((struct gtx_frame *)0);
396 newkeymap = keymap_Create();
397 if (newkeymap == (struct keymap_map *)0) {
399 * Get rid of the frame before exiting.
401 free(tframe);
402 return ((struct gtx_frame *)0);
405 newkeystate = (struct keymap_state *)
406 malloc(sizeof(struct keymap_state));
407 if (newkeystate == (struct keymap_state *)0) {
409 * Get rid of the frame AND the keymap before exiting.
411 free(tframe);
412 free(newkeymap);
413 return ((struct gtx_frame *)0);
417 * Now that all the pieces exist, fill them in and stick them in
418 * the right places.
420 memset(tframe, 0, sizeof(struct gtx_frame));
421 tframe->keymap = newkeymap;
422 tframe->keystate = newkeystate;
423 keymap_InitState(tframe->keystate, tframe->keymap);
424 keymap_BindToString(tframe->keymap, "\003", gtxframe_ExitCmd, "ExitCmd",
425 (char *)(&gtxframe_exitValue));
428 * At this point, we return successfully.
430 return (tframe);
434 gtxframe_Delete(struct gtx_frame *aframe)
436 keymap_Delete(aframe->keymap);
437 free(aframe->keystate);
438 if (aframe->messageLine)
439 free(aframe->messageLine);
440 free(aframe);
441 return 0;
445 gtxframe_Display(struct gtx_frame *aframe, struct gwin *awm)
447 struct gtxframe_dlist *tlist;
448 struct gtxframe_menu *tm;
449 struct gwin_strparams strparms;
451 /* Run through the menus, displaying them on the top line */
452 *menubuffer = 0;
453 for (tm = aframe->menus; tm; tm = tm->next) {
454 strcat(menubuffer, tm->name);
455 strcat(menubuffer, ":");
456 strcat(menubuffer, tm->cmdString);
457 strcat(menubuffer, " ");
459 if (menubuffer[0] != 0) {
460 memset(&strparms, 0, sizeof(strparms));
461 strparms.x = 0;
462 strparms.y = 0;
463 strparms.s = menubuffer;
464 strparms.highlight = 1;
465 WOP_DRAWSTRING(awm, &strparms);
468 /* Run through the display list, displaying all objects */
469 for (tlist = aframe->display; tlist; tlist = tlist->next) {
470 OOP_DISPLAY(((struct onode *)(tlist->data)));
473 /* Finally, show the message line */
474 ShowMessageLine(awm->w_frame);
475 return (0);
478 /* Add an object to a window's display list */
480 gtxframe_AddToList(struct gtx_frame *aframe, struct onode *aobj)
482 struct gtxframe_dlist *tlist;
484 for (tlist = aframe->display; tlist; tlist = tlist->next) {
485 if (tlist->data == (char *)aobj) {
487 * Don't add the same thing twice.
489 return (-1);
494 * OK, it's not alreadyt there. Create a new list object, fill it
495 * in, and splice it on.
497 tlist = (struct gtxframe_dlist *)malloc(sizeof(struct gtxframe_dlist));
498 if (tlist == (struct gtxframe_dlist *)0)
499 return (-1);
500 tlist->data = (char *)aobj;
501 tlist->next = aframe->display;
502 aframe->display = tlist;
503 return (0);
506 /* Remove an object from a display list, if it is already there */
508 gtxframe_RemoveFromList(struct gtx_frame *aframe, struct onode *aobj)
510 struct gtxframe_dlist *tlist, **plist;
512 plist = &aframe->display;
513 for (tlist = *plist; tlist; plist = &tlist->next, tlist = *plist) {
514 if (tlist->data == (char *)aobj) {
515 *plist = tlist->next;
516 free(tlist);
517 return 0;
520 return (-1); /* Item not found */
523 /* Clear out everything on the display list for the given frame*/
525 gtxframe_ClearList(struct gtx_frame *aframe)
527 struct gtxframe_dlist *tlist, *nlist;
529 if (aframe->display != (struct gtxframe_dlist *)0) {
531 * Throw away each display list structure (we have at least
532 * one).
534 for (tlist = aframe->display; tlist; tlist = nlist) {
535 nlist = tlist->next;
536 free(tlist);
540 aframe->display = (struct gtxframe_dlist *)0;
541 return 0;