2 * Copyright 2000, International Business Machines Corporation and others.
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
11 #include <afsconfig.h>
12 #include <afs/param.h>
18 #include <sys/types.h>
31 #include "gtxobjects.h"
32 #include "gtxwindows.h"
33 #include "gtxcurseswin.h"
35 #include "gtxkeymap.h"
38 extern char *gtx_CopyString();
39 static struct keymap_map *recursiveMap = 0;
40 static char menubuffer[1024]; /*Buffer for menu selections */
41 int gtxframe_exitValue = 0; /*Program exit value */
43 gtxframe_CtrlUCmd(awindow, arock)
47 struct gtx_frame *tframe;
49 tframe = awindow->w_frame;
50 if (!tframe->defaultLine)
52 *(tframe->defaultLine) = 0;
56 gtxframe_CtrlHCmd(awindow, arock)
60 register struct gtx_frame *tframe;
64 tframe = awindow->w_frame;
65 if (!(tp = tframe->defaultLine))
69 return 0; /* rubout at the end of the line */
74 gtxframe_RecursiveEndCmd(awindow, arock)
76 register struct gwin *awindow;
78 register struct gtx_frame *tframe;
80 tframe = awindow->w_frame;
81 tframe->flags |= GTXFRAME_RECURSIVEEND;
82 tframe->flags &= ~GTXFRAME_RECURSIVEERR;
86 gtxframe_RecursiveErrCmd(awindow, arock)
88 register struct gwin *awindow;
90 register struct gtx_frame *tframe;
92 tframe = awindow->w_frame;
93 tframe->flags |= GTXFRAME_RECURSIVEEND;
94 tframe->flags |= GTXFRAME_RECURSIVEERR;
98 gtxframe_SelfInsertCmd(awindow, arock)
100 struct gwin *awindow;
102 register struct gtx_frame *tframe;
106 tframe = awindow->w_frame;
107 if (!(tp = tframe->defaultLine))
110 tp[pos] = arock; /* arock has char to insert */
111 tp[pos + 1] = 0; /* null-terminate it, too */
115 /* save map, setup recursive map and install it */
118 register struct gtx_frame *aframe;
124 /* setup recursive edit map if not previously done */
125 recursiveMap = keymap_Create();
126 keymap_BindToString(recursiveMap, "\010", gtxframe_CtrlHCmd, NULL,
128 keymap_BindToString(recursiveMap, "\177", gtxframe_CtrlHCmd, NULL,
130 keymap_BindToString(recursiveMap, "\025", gtxframe_CtrlUCmd, NULL,
132 keymap_BindToString(recursiveMap, "\033", gtxframe_RecursiveEndCmd,
134 keymap_BindToString(recursiveMap, "\015", gtxframe_RecursiveEndCmd,
136 keymap_BindToString(recursiveMap, "\012", gtxframe_RecursiveEndCmd,
138 keymap_BindToString(recursiveMap, "\003", gtxframe_RecursiveErrCmd,
140 keymap_BindToString(recursiveMap, "\007", gtxframe_RecursiveErrCmd,
143 for (i = 040; i < 0177; i++) {
146 keymap_BindToString(recursiveMap, tstring, gtxframe_SelfInsertCmd,
150 aframe->savemap = aframe->keymap;
151 aframe->keymap = recursiveMap;
152 keymap_InitState(aframe->keystate, aframe->keymap);
156 /* Restore map to previous value */
159 register struct gtx_frame *aframe;
161 aframe->keymap = aframe->savemap;
162 aframe->savemap = (struct keymap_map *)0;
163 keymap_InitState(aframe->keystate, aframe->keymap);
167 gtxframe_SetFrame(awin, aframe)
168 struct gtx_frame *aframe;
172 /* Unthread this frame */
173 awin->w_frame->window = NULL;
175 awin->w_frame = aframe;
176 aframe->window = awin; /* Set frame's window ptr */
181 gtxframe_GetFrame(awin)
184 return awin->w_frame;
187 /* Add a menu string to display list */
188 gtxframe_AddMenu(aframe, alabel, astring)
191 struct gtx_frame *aframe;
193 register struct gtxframe_menu *tmenu;
196 for (tmenu = aframe->menus; tmenu; tmenu = tmenu->next) {
197 if (strcmp(alabel, tmenu->name) == 0)
200 tmenu = (struct gtxframe_menu *)0;
202 /* Handle everything but the command string, which is handled by the
203 * common-case code below */
204 tmenu = (struct gtxframe_menu *)malloc(sizeof(*tmenu));
205 if (tmenu == (struct gtxframe_menu *)0)
207 memset(tmenu, 0, sizeof(*tmenu));
208 tmenu->next = aframe->menus;
209 aframe->menus = tmenu;
210 tmenu->name = gtx_CopyString(alabel);
214 * Common case: redo the string labels. Note: at this point, tmenu
215 * points to a valid menu.
217 if (tmenu->cmdString)
218 free(tmenu->cmdString);
219 tmenu->cmdString = gtx_CopyString(astring);
223 /* Delete a given menu from a frame*/
224 gtxframe_DeleteMenu(aframe, alabel)
225 struct gtx_frame *aframe;
228 register struct gtxframe_menu *tm, **lm;
230 for (lm = &aframe->menus, tm = *lm; tm; lm = &tm->next, tm = *lm) {
231 if (strcmp(alabel, tm->name) == 0) {
232 /* found it, remove and return success */
233 *lm = tm->next; /* unthread from list */
240 return (-1); /* failed to find entry to delete */
243 /* Function to remove all known menus */
244 gtxframe_ClearMenus(aframe)
245 struct gtx_frame *aframe;
248 register struct gtxframe_menu *tm, *nm;
250 if (aframe->menus != (struct gtxframe_menu *)0) {
251 for (tm = aframe->menus; tm; tm = nm) {
259 aframe->menus = (struct gtxframe_menu *)0;
263 gtxframe_AskForString(aframe, aprompt, adefault, aresult, aresultSize)
264 register struct gtx_frame *aframe;
273 /* Ensure recursive-edit map is initialized */
277 if (aframe->promptLine)
278 free(aframe->promptLine);
279 if (aframe->defaultLine)
280 free(aframe->defaultLine);
281 aframe->promptLine = gtx_CopyString(aprompt);
282 tp = aframe->defaultLine = (char *)malloc(1024);
286 strcpy(tp, adefault);
290 /* Do recursive edit */
291 gtx_InputServer(aframe->window);
292 tp = aframe->defaultLine; /* In case command reallocated it */
294 /* Back from recursive edit, check out what's happened */
295 if (aframe->flags & GTXFRAME_RECURSIVEERR) {
300 if (code + 1 > aresultSize) {
307 /* Fall through to cleanup and return code */
310 if (aframe->promptLine)
311 free(aframe->promptLine);
312 if (aframe->defaultLine)
313 free(aframe->defaultLine);
314 aframe->defaultLine = aframe->promptLine = NULL;
316 gtxframe_DisplayString(aframe, "[Aborted]");
320 gtxframe_DisplayString(aframe, amsgLine)
322 register struct gtx_frame *aframe;
324 if (aframe->messageLine)
325 free(aframe->messageLine);
326 aframe->messageLine = gtx_CopyString(amsgLine);
329 /* Called by input processor to try to clear the dude */
330 gtxframe_ClearMessageLine(aframe)
331 struct gtx_frame *aframe;
333 /* If we haven't shown message long enough yet, just return */
334 if (aframe->flags & GTXFRAME_NEWDISPLAY)
336 if (aframe->messageLine)
337 free(aframe->messageLine);
338 aframe->messageLine = NULL;
343 ShowMessageLine(aframe)
344 struct gtx_frame *aframe;
346 struct gwin_strparams strparms;
347 struct gwin_sizeparams sizeparms;
353 /* First, find window size */
354 WOP_GETDIMENSIONS(aframe->window, &sizeparms);
356 if (aframe->promptLine) {
357 memset(&strparms, 0, sizeof(strparms));
359 strparms.y = sizeparms.maxy - 1;
360 strparms.highlight = 1;
361 tp = strparms.s = (char *)malloc(1024);
362 strcpy(tp, aframe->promptLine);
363 strcat(tp, aframe->defaultLine);
364 WOP_DRAWSTRING(aframe->window, &strparms);
365 aframe->flags |= GTXFRAME_NEWDISPLAY;
366 } else if (aframe->messageLine) {
367 /* Otherwise we're visible, print the message at the bottom */
368 memset(&strparms, 0, sizeof(strparms));
369 strparms.highlight = 1;
371 strparms.y = sizeparms.maxy - 1;
372 strparms.s = aframe->messageLine;
373 WOP_DRAWSTRING(aframe->window, &strparms);
374 aframe->flags |= GTXFRAME_NEWDISPLAY;
379 /* Exit function, returning whatever has been put in its argument */
381 gtxframe_ExitCmd(a_exitValuep)
384 { /*gtxframe_ExitCmd */
386 int exitval; /*Value we've been asked to exit with */
388 /* This next call should be type independent! */
389 gator_cursesgwin_cleanup(&gator_basegwin);
391 exitval = *((int *)(a_exitValuep));
394 } /*gtxframe_ExitCmd */
399 struct gtx_frame *tframe;
400 struct keymap_map *newkeymap;
401 struct keymap_state *newkeystate;
404 * Allocate all the pieces first: frame, keymap, and key state.
406 tframe = (struct gtx_frame *)malloc(sizeof(struct gtx_frame));
407 if (tframe == (struct gtx_frame *)0) {
408 return ((struct gtx_frame *)0);
411 newkeymap = keymap_Create();
412 if (newkeymap == (struct keymap_map *)0) {
414 * Get rid of the frame before exiting.
417 return ((struct gtx_frame *)0);
420 newkeystate = (struct keymap_state *)
421 malloc(sizeof(struct keymap_state));
422 if (newkeystate == (struct keymap_state *)0) {
424 * Get rid of the frame AND the keymap before exiting.
428 return ((struct gtx_frame *)0);
432 * Now that all the pieces exist, fill them in and stick them in
435 memset(tframe, 0, sizeof(struct gtx_frame));
436 tframe->keymap = newkeymap;
437 tframe->keystate = newkeystate;
438 keymap_InitState(tframe->keystate, tframe->keymap);
439 keymap_BindToString(tframe->keymap, "\003", gtxframe_ExitCmd, "ExitCmd",
440 (char *)(>xframe_exitValue));
443 * At this point, we return successfully.
448 gtxframe_Delete(aframe)
449 register struct gtx_frame *aframe;
451 keymap_Delete(aframe->keymap);
452 free(aframe->keystate);
453 if (aframe->messageLine)
454 free(aframe->messageLine);
459 gtxframe_Display(aframe, awm)
461 register struct gtx_frame *aframe;
463 register struct gtxframe_dlist *tlist;
464 register struct gtxframe_menu *tm;
465 struct gwin_strparams strparms;
467 /* Run through the menus, displaying them on the top line */
469 for (tm = aframe->menus; tm; tm = tm->next) {
470 strcat(menubuffer, tm->name);
471 strcat(menubuffer, ":");
472 strcat(menubuffer, tm->cmdString);
473 strcat(menubuffer, " ");
475 if (menubuffer[0] != 0) {
476 memset(&strparms, 0, sizeof(strparms));
479 strparms.s = menubuffer;
480 strparms.highlight = 1;
481 WOP_DRAWSTRING(awm, &strparms);
484 /* Run through the display list, displaying all objects */
485 for (tlist = aframe->display; tlist; tlist = tlist->next) {
486 OOP_DISPLAY(((struct onode *)(tlist->data)));
489 /* Finally, show the message line */
490 ShowMessageLine(awm->w_frame);
494 /* Add an object to a window's display list */
495 gtxframe_AddToList(aframe, aobj)
497 register struct gtx_frame *aframe;
499 register struct gtxframe_dlist *tlist;
501 for (tlist = aframe->display; tlist; tlist = tlist->next) {
502 if (tlist->data == (char *)aobj) {
504 * Don't add the same thing twice.
511 * OK, it's not alreadyt there. Create a new list object, fill it
512 * in, and splice it on.
514 tlist = (struct gtxframe_dlist *)malloc(sizeof(struct gtxframe_dlist));
515 if (tlist == (struct gtxframe_dlist *)0)
517 tlist->data = (char *)aobj;
518 tlist->next = aframe->display;
519 aframe->display = tlist;
523 /* Remove an object from a display list, if it is already there */
524 gtxframe_RemoveFromList(aframe, aobj)
526 register struct gtx_frame *aframe;
528 register struct gtxframe_dlist *tlist, **plist;
530 plist = &aframe->display;
531 for (tlist = *plist; tlist; plist = &tlist->next, tlist = *plist) {
532 if (tlist->data == (char *)aobj) {
533 *plist = tlist->next;
538 return (-1); /* Item not found */
541 /* Clear out everything on the display list for the given frame*/
542 gtxframe_ClearList(aframe)
543 register struct gtx_frame *aframe;
545 register struct gtxframe_dlist *tlist, *nlist;
547 if (aframe->display != (struct gtxframe_dlist *)0) {
549 * Throw away each display list structure (we have at least
552 for (tlist = aframe->display; tlist; tlist = nlist) {
558 aframe->display = (struct gtxframe_dlist *)0;