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>
15 #include <sys/types.h>
22 #include "gtxobjects.h"
23 #include "gtxwindows.h"
24 #include "gtxcurseswin.h"
26 #include "gtxkeymap.h"
29 static struct keymap_map *recursiveMap = 0;
30 static char menubuffer[1024]; /*Buffer for menu selections */
31 int gtxframe_exitValue = 0; /*Program exit value */
34 gtxframe_CtrlUCmd(void *aparam, void *arock)
36 struct gwin *awindow = (struct gwin *) aparam;
37 struct gtx_frame *tframe;
39 tframe = awindow->w_frame;
40 if (!tframe->defaultLine)
42 *(tframe->defaultLine) = 0;
47 gtxframe_CtrlHCmd(void *aparam, void *arock)
49 struct gwin *awindow = (struct gwin *) aparam;
51 register struct gtx_frame *tframe;
55 tframe = awindow->w_frame;
56 if (!(tp = tframe->defaultLine))
60 return 0; /* rubout at the end of the line */
66 gtxframe_RecursiveEndCmd(void *aparam, void *arock)
68 struct gwin *awindow = (struct gwin *) aparam;
70 register struct gtx_frame *tframe;
72 tframe = awindow->w_frame;
73 tframe->flags |= GTXFRAME_RECURSIVEEND;
74 tframe->flags &= ~GTXFRAME_RECURSIVEERR;
79 gtxframe_RecursiveErrCmd(void *aparam, void *arock)
81 struct gwin *awindow = (struct gwin *) aparam;
83 register struct gtx_frame *tframe;
85 tframe = awindow->w_frame;
86 tframe->flags |= GTXFRAME_RECURSIVEEND;
87 tframe->flags |= GTXFRAME_RECURSIVEERR;
92 gtxframe_SelfInsertCmd(void *aparam, void *rockparam)
94 struct gwin *awindow = (struct gwin *) aparam;
96 int arock = (int) rockparam;
98 register struct gtx_frame *tframe;
102 tframe = awindow->w_frame;
103 if (!(tp = tframe->defaultLine))
106 tp[pos] = arock; /* arock has char to insert */
107 tp[pos + 1] = 0; /* null-terminate it, too */
111 /* save map, setup recursive map and install it */
113 SaveMap(struct gtx_frame *aframe)
119 /* setup recursive edit map if not previously done */
120 recursiveMap = keymap_Create();
121 keymap_BindToString(recursiveMap, "\010", gtxframe_CtrlHCmd, NULL,
123 keymap_BindToString(recursiveMap, "\177", gtxframe_CtrlHCmd, NULL,
125 keymap_BindToString(recursiveMap, "\025", gtxframe_CtrlUCmd, NULL,
127 keymap_BindToString(recursiveMap, "\033", gtxframe_RecursiveEndCmd,
129 keymap_BindToString(recursiveMap, "\015", gtxframe_RecursiveEndCmd,
131 keymap_BindToString(recursiveMap, "\012", gtxframe_RecursiveEndCmd,
133 keymap_BindToString(recursiveMap, "\003", gtxframe_RecursiveErrCmd,
135 keymap_BindToString(recursiveMap, "\007", gtxframe_RecursiveErrCmd,
138 for (i = 040; i < 0177; i++) {
141 keymap_BindToString(recursiveMap, tstring, gtxframe_SelfInsertCmd,
145 aframe->savemap = aframe->keymap;
146 aframe->keymap = recursiveMap;
147 keymap_InitState(aframe->keystate, aframe->keymap);
151 /* Restore map to previous value */
153 RestoreMap(struct gtx_frame *aframe)
155 aframe->keymap = aframe->savemap;
156 aframe->savemap = (struct keymap_map *)0;
157 keymap_InitState(aframe->keystate, aframe->keymap);
162 gtxframe_SetFrame(struct gwin *awin, 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(struct gwin *awin)
176 return awin->w_frame;
179 /* Add a menu string to display list */
181 gtxframe_AddMenu(struct gtx_frame *aframe, char *alabel, char *astring)
183 register struct gtxframe_menu *tmenu;
186 for (tmenu = aframe->menus; tmenu; tmenu = tmenu->next) {
187 if (strcmp(alabel, tmenu->name) == 0)
190 tmenu = (struct gtxframe_menu *)0;
192 /* Handle everything but the command string, which is handled by the
193 * common-case code below */
194 tmenu = (struct gtxframe_menu *)malloc(sizeof(*tmenu));
195 if (tmenu == (struct gtxframe_menu *)0)
197 memset(tmenu, 0, sizeof(*tmenu));
198 tmenu->next = aframe->menus;
199 aframe->menus = tmenu;
200 tmenu->name = gtx_CopyString(alabel);
204 * Common case: redo the string labels. Note: at this point, tmenu
205 * points to a valid menu.
207 if (tmenu->cmdString)
208 free(tmenu->cmdString);
209 tmenu->cmdString = gtx_CopyString(astring);
213 /* Delete a given menu from a frame*/
215 gtxframe_DeleteMenu(struct gtx_frame *aframe, char *alabel)
217 register struct gtxframe_menu *tm, **lm;
219 for (lm = &aframe->menus, tm = *lm; tm; lm = &tm->next, tm = *lm) {
220 if (strcmp(alabel, tm->name) == 0) {
221 /* found it, remove and return success */
222 *lm = tm->next; /* unthread from list */
229 return (-1); /* failed to find entry to delete */
232 /* Function to remove all known menus */
234 gtxframe_ClearMenus(struct gtx_frame *aframe)
237 register struct gtxframe_menu *tm, *nm;
239 if (aframe->menus != (struct gtxframe_menu *)0) {
240 for (tm = aframe->menus; tm; tm = nm) {
248 aframe->menus = (struct gtxframe_menu *)0;
253 gtxframe_AskForString(struct gtx_frame *aframe, char *aprompt,
254 char *adefault, char *aresult, int aresultSize)
259 /* Ensure recursive-edit map is initialized */
263 if (aframe->promptLine)
264 free(aframe->promptLine);
265 if (aframe->defaultLine)
266 free(aframe->defaultLine);
267 aframe->promptLine = gtx_CopyString(aprompt);
268 tp = aframe->defaultLine = (char *)malloc(1024);
272 strcpy(tp, adefault);
276 /* Do recursive edit */
277 gtx_InputServer(aframe->window);
278 tp = aframe->defaultLine; /* In case command reallocated it */
280 /* Back from recursive edit, check out what's happened */
281 if (aframe->flags & GTXFRAME_RECURSIVEERR) {
286 if (code + 1 > aresultSize) {
293 /* Fall through to cleanup and return code */
296 if (aframe->promptLine)
297 free(aframe->promptLine);
298 if (aframe->defaultLine)
299 free(aframe->defaultLine);
300 aframe->defaultLine = aframe->promptLine = NULL;
302 gtxframe_DisplayString(aframe, "[Aborted]");
307 gtxframe_DisplayString(struct gtx_frame *aframe, char *amsgLine)
309 if (aframe->messageLine)
310 free(aframe->messageLine);
311 aframe->messageLine = gtx_CopyString(amsgLine);
315 /* Called by input processor to try to clear the dude */
317 gtxframe_ClearMessageLine(struct gtx_frame *aframe)
319 /* If we haven't shown message long enough yet, just return */
320 if (aframe->flags & GTXFRAME_NEWDISPLAY)
322 if (aframe->messageLine)
323 free(aframe->messageLine);
324 aframe->messageLine = NULL;
329 ShowMessageLine(struct gtx_frame *aframe)
331 struct gwin_strparams strparms;
332 struct gwin_sizeparams sizeparms;
338 /* First, find window size */
339 WOP_GETDIMENSIONS(aframe->window, &sizeparms);
341 if (aframe->promptLine) {
342 memset(&strparms, 0, sizeof(strparms));
344 strparms.y = sizeparms.maxy - 1;
345 strparms.highlight = 1;
346 tp = strparms.s = (char *)malloc(1024);
347 strcpy(tp, aframe->promptLine);
348 strcat(tp, aframe->defaultLine);
349 WOP_DRAWSTRING(aframe->window, &strparms);
350 aframe->flags |= GTXFRAME_NEWDISPLAY;
351 } else if (aframe->messageLine) {
352 /* Otherwise we're visible, print the message at the bottom */
353 memset(&strparms, 0, sizeof(strparms));
354 strparms.highlight = 1;
356 strparms.y = sizeparms.maxy - 1;
357 strparms.s = aframe->messageLine;
358 WOP_DRAWSTRING(aframe->window, &strparms);
359 aframe->flags |= GTXFRAME_NEWDISPLAY;
364 /* Exit function, returning whatever has been put in its argument */
366 gtxframe_ExitCmd(void *a_exitValuep, void *arock)
367 { /*gtxframe_ExitCmd */
369 int exitval; /*Value we've been asked to exit with */
371 /* This next call should be type independent! */
372 gator_cursesgwin_cleanup(&gator_basegwin);
374 exitval = *((int *)(a_exitValuep));
377 } /*gtxframe_ExitCmd */
380 gtxframe_Create(void)
382 struct gtx_frame *tframe;
383 struct keymap_map *newkeymap;
384 struct keymap_state *newkeystate;
387 * Allocate all the pieces first: frame, keymap, and key state.
389 tframe = (struct gtx_frame *)malloc(sizeof(struct gtx_frame));
390 if (tframe == (struct gtx_frame *)0) {
391 return ((struct gtx_frame *)0);
394 newkeymap = keymap_Create();
395 if (newkeymap == (struct keymap_map *)0) {
397 * Get rid of the frame before exiting.
400 return ((struct gtx_frame *)0);
403 newkeystate = (struct keymap_state *)
404 malloc(sizeof(struct keymap_state));
405 if (newkeystate == (struct keymap_state *)0) {
407 * Get rid of the frame AND the keymap before exiting.
411 return ((struct gtx_frame *)0);
415 * Now that all the pieces exist, fill them in and stick them in
418 memset(tframe, 0, sizeof(struct gtx_frame));
419 tframe->keymap = newkeymap;
420 tframe->keystate = newkeystate;
421 keymap_InitState(tframe->keystate, tframe->keymap);
422 keymap_BindToString(tframe->keymap, "\003", gtxframe_ExitCmd, "ExitCmd",
423 (char *)(>xframe_exitValue));
426 * At this point, we return successfully.
432 gtxframe_Delete(struct gtx_frame *aframe)
434 keymap_Delete(aframe->keymap);
435 free(aframe->keystate);
436 if (aframe->messageLine)
437 free(aframe->messageLine);
443 gtxframe_Display(struct gtx_frame *aframe, struct gwin *awm)
445 register struct gtxframe_dlist *tlist;
446 register struct gtxframe_menu *tm;
447 struct gwin_strparams strparms;
449 /* Run through the menus, displaying them on the top line */
451 for (tm = aframe->menus; tm; tm = tm->next) {
452 strcat(menubuffer, tm->name);
453 strcat(menubuffer, ":");
454 strcat(menubuffer, tm->cmdString);
455 strcat(menubuffer, " ");
457 if (menubuffer[0] != 0) {
458 memset(&strparms, 0, sizeof(strparms));
461 strparms.s = menubuffer;
462 strparms.highlight = 1;
463 WOP_DRAWSTRING(awm, &strparms);
466 /* Run through the display list, displaying all objects */
467 for (tlist = aframe->display; tlist; tlist = tlist->next) {
468 OOP_DISPLAY(((struct onode *)(tlist->data)));
471 /* Finally, show the message line */
472 ShowMessageLine(awm->w_frame);
476 /* Add an object to a window's display list */
478 gtxframe_AddToList(struct gtx_frame *aframe, struct onode *aobj)
480 register struct gtxframe_dlist *tlist;
482 for (tlist = aframe->display; tlist; tlist = tlist->next) {
483 if (tlist->data == (char *)aobj) {
485 * Don't add the same thing twice.
492 * OK, it's not alreadyt there. Create a new list object, fill it
493 * in, and splice it on.
495 tlist = (struct gtxframe_dlist *)malloc(sizeof(struct gtxframe_dlist));
496 if (tlist == (struct gtxframe_dlist *)0)
498 tlist->data = (char *)aobj;
499 tlist->next = aframe->display;
500 aframe->display = tlist;
504 /* Remove an object from a display list, if it is already there */
506 gtxframe_RemoveFromList(struct gtx_frame *aframe, struct onode *aobj)
508 register struct gtxframe_dlist *tlist, **plist;
510 plist = &aframe->display;
511 for (tlist = *plist; tlist; plist = &tlist->next, tlist = *plist) {
512 if (tlist->data == (char *)aobj) {
513 *plist = tlist->next;
518 return (-1); /* Item not found */
521 /* Clear out everything on the display list for the given frame*/
523 gtxframe_ClearList(struct gtx_frame *aframe)
525 register struct gtxframe_dlist *tlist, *nlist;
527 if (aframe->display != (struct gtxframe_dlist *)0) {
529 * Throw away each display list structure (we have at least
532 for (tlist = aframe->display; tlist; tlist = nlist) {
538 aframe->display = (struct gtxframe_dlist *)0;