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
10 #include <afsconfig.h>
11 #include <afs/param.h>
17 #include <sys/types.h>
24 #include "gtxobjects.h"
25 #include "gtxwindows.h"
26 #include "gtxcurseswin.h"
28 #include "gtxkeymap.h"
31 extern char *gtx_CopyString();
32 static struct keymap_map *recursiveMap = 0;
33 static char menubuffer[1024]; /*Buffer for menu selections */
34 int gtxframe_exitValue = 0; /*Program exit value */
36 gtxframe_CtrlUCmd(awindow, arock)
40 struct gtx_frame *tframe;
42 tframe = awindow->w_frame;
43 if (!tframe->defaultLine)
45 *(tframe->defaultLine) = 0;
49 gtxframe_CtrlHCmd(awindow, arock)
53 register struct gtx_frame *tframe;
57 tframe = awindow->w_frame;
58 if (!(tp = tframe->defaultLine))
62 return 0; /* rubout at the end of the line */
67 gtxframe_RecursiveEndCmd(awindow, arock)
69 register struct gwin *awindow;
71 register struct gtx_frame *tframe;
73 tframe = awindow->w_frame;
74 tframe->flags |= GTXFRAME_RECURSIVEEND;
75 tframe->flags &= ~GTXFRAME_RECURSIVEERR;
79 gtxframe_RecursiveErrCmd(awindow, arock)
81 register struct gwin *awindow;
83 register struct gtx_frame *tframe;
85 tframe = awindow->w_frame;
86 tframe->flags |= GTXFRAME_RECURSIVEEND;
87 tframe->flags |= GTXFRAME_RECURSIVEERR;
91 gtxframe_SelfInsertCmd(awindow, arock)
95 register struct gtx_frame *tframe;
99 tframe = awindow->w_frame;
100 if (!(tp = tframe->defaultLine))
103 tp[pos] = arock; /* arock has char to insert */
104 tp[pos + 1] = 0; /* null-terminate it, too */
108 /* save map, setup recursive map and install it */
111 register struct gtx_frame *aframe;
117 /* setup recursive edit map if not previously done */
118 recursiveMap = keymap_Create();
119 keymap_BindToString(recursiveMap, "\010", gtxframe_CtrlHCmd, NULL,
121 keymap_BindToString(recursiveMap, "\177", gtxframe_CtrlHCmd, NULL,
123 keymap_BindToString(recursiveMap, "\025", gtxframe_CtrlUCmd, NULL,
125 keymap_BindToString(recursiveMap, "\033", gtxframe_RecursiveEndCmd,
127 keymap_BindToString(recursiveMap, "\015", gtxframe_RecursiveEndCmd,
129 keymap_BindToString(recursiveMap, "\012", gtxframe_RecursiveEndCmd,
131 keymap_BindToString(recursiveMap, "\003", gtxframe_RecursiveErrCmd,
133 keymap_BindToString(recursiveMap, "\007", gtxframe_RecursiveErrCmd,
136 for (i = 040; i < 0177; i++) {
139 keymap_BindToString(recursiveMap, tstring, gtxframe_SelfInsertCmd,
143 aframe->savemap = aframe->keymap;
144 aframe->keymap = recursiveMap;
145 keymap_InitState(aframe->keystate, aframe->keymap);
149 /* Restore map to previous value */
152 register struct gtx_frame *aframe;
154 aframe->keymap = aframe->savemap;
155 aframe->savemap = (struct keymap_map *)0;
156 keymap_InitState(aframe->keystate, aframe->keymap);
160 gtxframe_SetFrame(awin, aframe)
161 struct gtx_frame *aframe;
165 /* Unthread this frame */
166 awin->w_frame->window = NULL;
168 awin->w_frame = aframe;
169 aframe->window = awin; /* Set frame's window ptr */
174 gtxframe_GetFrame(awin)
177 return awin->w_frame;
180 /* Add a menu string to display list */
181 gtxframe_AddMenu(aframe, alabel, astring)
184 struct gtx_frame *aframe;
186 register struct gtxframe_menu *tmenu;
189 for (tmenu = aframe->menus; tmenu; tmenu = tmenu->next) {
190 if (strcmp(alabel, tmenu->name) == 0)
193 tmenu = (struct gtxframe_menu *)0;
195 /* Handle everything but the command string, which is handled by the
196 * common-case code below */
197 tmenu = (struct gtxframe_menu *)malloc(sizeof(*tmenu));
198 if (tmenu == (struct gtxframe_menu *)0)
200 memset(tmenu, 0, sizeof(*tmenu));
201 tmenu->next = aframe->menus;
202 aframe->menus = tmenu;
203 tmenu->name = gtx_CopyString(alabel);
207 * Common case: redo the string labels. Note: at this point, tmenu
208 * points to a valid menu.
210 if (tmenu->cmdString)
211 free(tmenu->cmdString);
212 tmenu->cmdString = gtx_CopyString(astring);
216 /* Delete a given menu from a frame*/
217 gtxframe_DeleteMenu(aframe, alabel)
218 struct gtx_frame *aframe;
221 register struct gtxframe_menu *tm, **lm;
223 for (lm = &aframe->menus, tm = *lm; tm; lm = &tm->next, tm = *lm) {
224 if (strcmp(alabel, tm->name) == 0) {
225 /* found it, remove and return success */
226 *lm = tm->next; /* unthread from list */
233 return (-1); /* failed to find entry to delete */
236 /* Function to remove all known menus */
237 gtxframe_ClearMenus(aframe)
238 struct gtx_frame *aframe;
241 register struct gtxframe_menu *tm, *nm;
243 if (aframe->menus != (struct gtxframe_menu *)0) {
244 for (tm = aframe->menus; tm; tm = nm) {
252 aframe->menus = (struct gtxframe_menu *)0;
256 gtxframe_AskForString(aframe, aprompt, adefault, aresult, aresultSize)
257 register struct gtx_frame *aframe;
266 /* Ensure recursive-edit map is initialized */
270 if (aframe->promptLine)
271 free(aframe->promptLine);
272 if (aframe->defaultLine)
273 free(aframe->defaultLine);
274 aframe->promptLine = gtx_CopyString(aprompt);
275 tp = aframe->defaultLine = (char *)malloc(1024);
279 strcpy(tp, adefault);
283 /* Do recursive edit */
284 gtx_InputServer(aframe->window);
285 tp = aframe->defaultLine; /* In case command reallocated it */
287 /* Back from recursive edit, check out what's happened */
288 if (aframe->flags & GTXFRAME_RECURSIVEERR) {
293 if (code + 1 > aresultSize) {
300 /* Fall through to cleanup and return code */
303 if (aframe->promptLine)
304 free(aframe->promptLine);
305 if (aframe->defaultLine)
306 free(aframe->defaultLine);
307 aframe->defaultLine = aframe->promptLine = NULL;
309 gtxframe_DisplayString(aframe, "[Aborted]");
313 gtxframe_DisplayString(aframe, amsgLine)
315 register struct gtx_frame *aframe;
317 if (aframe->messageLine)
318 free(aframe->messageLine);
319 aframe->messageLine = gtx_CopyString(amsgLine);
323 /* Called by input processor to try to clear the dude */
324 gtxframe_ClearMessageLine(aframe)
325 struct gtx_frame *aframe;
327 /* If we haven't shown message long enough yet, just return */
328 if (aframe->flags & GTXFRAME_NEWDISPLAY)
330 if (aframe->messageLine)
331 free(aframe->messageLine);
332 aframe->messageLine = NULL;
337 ShowMessageLine(aframe)
338 struct gtx_frame *aframe;
340 struct gwin_strparams strparms;
341 struct gwin_sizeparams sizeparms;
347 /* First, find window size */
348 WOP_GETDIMENSIONS(aframe->window, &sizeparms);
350 if (aframe->promptLine) {
351 memset(&strparms, 0, sizeof(strparms));
353 strparms.y = sizeparms.maxy - 1;
354 strparms.highlight = 1;
355 tp = strparms.s = (char *)malloc(1024);
356 strcpy(tp, aframe->promptLine);
357 strcat(tp, aframe->defaultLine);
358 WOP_DRAWSTRING(aframe->window, &strparms);
359 aframe->flags |= GTXFRAME_NEWDISPLAY;
360 } else if (aframe->messageLine) {
361 /* Otherwise we're visible, print the message at the bottom */
362 memset(&strparms, 0, sizeof(strparms));
363 strparms.highlight = 1;
365 strparms.y = sizeparms.maxy - 1;
366 strparms.s = aframe->messageLine;
367 WOP_DRAWSTRING(aframe->window, &strparms);
368 aframe->flags |= GTXFRAME_NEWDISPLAY;
373 /* Exit function, returning whatever has been put in its argument */
375 gtxframe_ExitCmd(a_exitValuep)
378 { /*gtxframe_ExitCmd */
380 int exitval; /*Value we've been asked to exit with */
382 /* This next call should be type independent! */
383 gator_cursesgwin_cleanup(&gator_basegwin);
385 exitval = *((int *)(a_exitValuep));
388 } /*gtxframe_ExitCmd */
393 struct gtx_frame *tframe;
394 struct keymap_map *newkeymap;
395 struct keymap_state *newkeystate;
398 * Allocate all the pieces first: frame, keymap, and key state.
400 tframe = (struct gtx_frame *)malloc(sizeof(struct gtx_frame));
401 if (tframe == (struct gtx_frame *)0) {
402 return ((struct gtx_frame *)0);
405 newkeymap = keymap_Create();
406 if (newkeymap == (struct keymap_map *)0) {
408 * Get rid of the frame before exiting.
411 return ((struct gtx_frame *)0);
414 newkeystate = (struct keymap_state *)
415 malloc(sizeof(struct keymap_state));
416 if (newkeystate == (struct keymap_state *)0) {
418 * Get rid of the frame AND the keymap before exiting.
422 return ((struct gtx_frame *)0);
426 * Now that all the pieces exist, fill them in and stick them in
429 memset(tframe, 0, sizeof(struct gtx_frame));
430 tframe->keymap = newkeymap;
431 tframe->keystate = newkeystate;
432 keymap_InitState(tframe->keystate, tframe->keymap);
433 keymap_BindToString(tframe->keymap, "\003", gtxframe_ExitCmd, "ExitCmd",
434 (char *)(>xframe_exitValue));
437 * At this point, we return successfully.
442 gtxframe_Delete(aframe)
443 register struct gtx_frame *aframe;
445 keymap_Delete(aframe->keymap);
446 free(aframe->keystate);
447 if (aframe->messageLine)
448 free(aframe->messageLine);
453 gtxframe_Display(aframe, awm)
455 register struct gtx_frame *aframe;
457 register struct gtxframe_dlist *tlist;
458 register struct gtxframe_menu *tm;
459 struct gwin_strparams strparms;
461 /* Run through the menus, displaying them on the top line */
463 for (tm = aframe->menus; tm; tm = tm->next) {
464 strcat(menubuffer, tm->name);
465 strcat(menubuffer, ":");
466 strcat(menubuffer, tm->cmdString);
467 strcat(menubuffer, " ");
469 if (menubuffer[0] != 0) {
470 memset(&strparms, 0, sizeof(strparms));
473 strparms.s = menubuffer;
474 strparms.highlight = 1;
475 WOP_DRAWSTRING(awm, &strparms);
478 /* Run through the display list, displaying all objects */
479 for (tlist = aframe->display; tlist; tlist = tlist->next) {
480 OOP_DISPLAY(((struct onode *)(tlist->data)));
483 /* Finally, show the message line */
484 ShowMessageLine(awm->w_frame);
488 /* Add an object to a window's display list */
489 gtxframe_AddToList(aframe, aobj)
491 register struct gtx_frame *aframe;
493 register struct gtxframe_dlist *tlist;
495 for (tlist = aframe->display; tlist; tlist = tlist->next) {
496 if (tlist->data == (char *)aobj) {
498 * Don't add the same thing twice.
505 * OK, it's not alreadyt there. Create a new list object, fill it
506 * in, and splice it on.
508 tlist = (struct gtxframe_dlist *)malloc(sizeof(struct gtxframe_dlist));
509 if (tlist == (struct gtxframe_dlist *)0)
511 tlist->data = (char *)aobj;
512 tlist->next = aframe->display;
513 aframe->display = tlist;
517 /* Remove an object from a display list, if it is already there */
518 gtxframe_RemoveFromList(aframe, aobj)
520 register struct gtx_frame *aframe;
522 register struct gtxframe_dlist *tlist, **plist;
524 plist = &aframe->display;
525 for (tlist = *plist; tlist; plist = &tlist->next, tlist = *plist) {
526 if (tlist->data == (char *)aobj) {
527 *plist = tlist->next;
532 return (-1); /* Item not found */
535 /* Clear out everything on the display list for the given frame*/
536 gtxframe_ClearList(aframe)
537 register struct gtx_frame *aframe;
539 register struct gtxframe_dlist *tlist, *nlist;
541 if (aframe->display != (struct gtxframe_dlist *)0) {
543 * Throw away each display list structure (we have at least
546 for (tlist = aframe->display; tlist; tlist = nlist) {
552 aframe->display = (struct gtxframe_dlist *)0;