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>
23 #include "gtxobjects.h"
24 #include "gtxwindows.h"
25 #include "gtxcurseswin.h"
27 #include "gtxkeymap.h"
30 static struct keymap_map *recursiveMap = 0;
31 static char menubuffer[1024]; /*Buffer for menu selections */
32 int gtxframe_exitValue = 0; /*Program exit value */
35 gtxframe_CtrlUCmd(void *aparam, void *arock)
37 struct gwin *awindow = (struct gwin *) aparam;
38 struct gtx_frame *tframe;
40 tframe = awindow->w_frame;
41 if (!tframe->defaultLine)
43 *(tframe->defaultLine) = 0;
48 gtxframe_CtrlHCmd(void *aparam, void *arock)
50 struct gwin *awindow = (struct gwin *) aparam;
52 register struct gtx_frame *tframe;
56 tframe = awindow->w_frame;
57 if (!(tp = tframe->defaultLine))
61 return 0; /* rubout at the end of the line */
67 gtxframe_RecursiveEndCmd(void *aparam, void *arock)
69 struct gwin *awindow = (struct gwin *) aparam;
71 register struct gtx_frame *tframe;
73 tframe = awindow->w_frame;
74 tframe->flags |= GTXFRAME_RECURSIVEEND;
75 tframe->flags &= ~GTXFRAME_RECURSIVEERR;
80 gtxframe_RecursiveErrCmd(void *aparam, void *arock)
82 struct gwin *awindow = (struct gwin *) aparam;
84 register struct gtx_frame *tframe;
86 tframe = awindow->w_frame;
87 tframe->flags |= GTXFRAME_RECURSIVEEND;
88 tframe->flags |= GTXFRAME_RECURSIVEERR;
93 gtxframe_SelfInsertCmd(void *aparam, void *rockparam)
95 struct gwin *awindow = (struct gwin *) aparam;
97 int arock = (intptr_t)rockparam;
99 register struct gtx_frame *tframe;
103 tframe = awindow->w_frame;
104 if (!(tp = tframe->defaultLine))
107 tp[pos] = arock; /* arock has char to insert */
108 tp[pos + 1] = 0; /* null-terminate it, too */
112 /* save map, setup recursive map and install it */
114 SaveMap(struct gtx_frame *aframe)
120 /* setup recursive edit map if not previously done */
121 recursiveMap = keymap_Create();
122 keymap_BindToString(recursiveMap, "\010", gtxframe_CtrlHCmd, NULL,
124 keymap_BindToString(recursiveMap, "\177", gtxframe_CtrlHCmd, NULL,
126 keymap_BindToString(recursiveMap, "\025", gtxframe_CtrlUCmd, NULL,
128 keymap_BindToString(recursiveMap, "\033", gtxframe_RecursiveEndCmd,
130 keymap_BindToString(recursiveMap, "\015", gtxframe_RecursiveEndCmd,
132 keymap_BindToString(recursiveMap, "\012", gtxframe_RecursiveEndCmd,
134 keymap_BindToString(recursiveMap, "\003", gtxframe_RecursiveErrCmd,
136 keymap_BindToString(recursiveMap, "\007", gtxframe_RecursiveErrCmd,
139 for (i = 040; i < 0177; i++) {
142 keymap_BindToString(recursiveMap, tstring, gtxframe_SelfInsertCmd,
143 NULL, (void *)(intptr_t)i);
146 aframe->savemap = aframe->keymap;
147 aframe->keymap = recursiveMap;
148 keymap_InitState(aframe->keystate, aframe->keymap);
152 /* Restore map to previous value */
154 RestoreMap(struct gtx_frame *aframe)
156 aframe->keymap = aframe->savemap;
157 aframe->savemap = (struct keymap_map *)0;
158 keymap_InitState(aframe->keystate, aframe->keymap);
163 gtxframe_SetFrame(struct gwin *awin, struct gtx_frame *aframe)
166 /* Unthread this frame */
167 awin->w_frame->window = NULL;
169 awin->w_frame = aframe;
170 aframe->window = awin; /* Set frame's window ptr */
175 gtxframe_GetFrame(struct gwin *awin)
177 return awin->w_frame;
180 /* Add a menu string to display list */
182 gtxframe_AddMenu(struct gtx_frame *aframe, char *alabel, char *astring)
184 register struct gtxframe_menu *tmenu;
187 for (tmenu = aframe->menus; tmenu; tmenu = tmenu->next) {
188 if (strcmp(alabel, tmenu->name) == 0)
191 tmenu = (struct gtxframe_menu *)0;
193 /* Handle everything but the command string, which is handled by the
194 * common-case code below */
195 tmenu = (struct gtxframe_menu *)malloc(sizeof(*tmenu));
196 if (tmenu == (struct gtxframe_menu *)0)
198 memset(tmenu, 0, sizeof(*tmenu));
199 tmenu->next = aframe->menus;
200 aframe->menus = tmenu;
201 tmenu->name = gtx_CopyString(alabel);
205 * Common case: redo the string labels. Note: at this point, tmenu
206 * points to a valid menu.
208 if (tmenu->cmdString)
209 free(tmenu->cmdString);
210 tmenu->cmdString = gtx_CopyString(astring);
214 /* Delete a given menu from a frame*/
216 gtxframe_DeleteMenu(struct gtx_frame *aframe, char *alabel)
218 register struct gtxframe_menu *tm, **lm;
220 for (lm = &aframe->menus, tm = *lm; tm; lm = &tm->next, tm = *lm) {
221 if (strcmp(alabel, tm->name) == 0) {
222 /* found it, remove and return success */
223 *lm = tm->next; /* unthread from list */
230 return (-1); /* failed to find entry to delete */
233 /* Function to remove all known menus */
235 gtxframe_ClearMenus(struct gtx_frame *aframe)
238 register struct gtxframe_menu *tm, *nm;
240 if (aframe->menus != (struct gtxframe_menu *)0) {
241 for (tm = aframe->menus; tm; tm = nm) {
249 aframe->menus = (struct gtxframe_menu *)0;
254 gtxframe_AskForString(struct gtx_frame *aframe, char *aprompt,
255 char *adefault, char *aresult, int aresultSize)
260 /* Ensure recursive-edit map is initialized */
264 if (aframe->promptLine)
265 free(aframe->promptLine);
266 if (aframe->defaultLine)
267 free(aframe->defaultLine);
268 aframe->promptLine = gtx_CopyString(aprompt);
269 tp = aframe->defaultLine = (char *)malloc(1024);
273 strcpy(tp, adefault);
277 /* Do recursive edit */
278 gtx_InputServer(aframe->window);
279 tp = aframe->defaultLine; /* In case command reallocated it */
281 /* Back from recursive edit, check out what's happened */
282 if (aframe->flags & GTXFRAME_RECURSIVEERR) {
287 if (code + 1 > aresultSize) {
294 /* Fall through to cleanup and return code */
297 if (aframe->promptLine)
298 free(aframe->promptLine);
299 if (aframe->defaultLine)
300 free(aframe->defaultLine);
301 aframe->defaultLine = aframe->promptLine = NULL;
303 gtxframe_DisplayString(aframe, "[Aborted]");
308 gtxframe_DisplayString(struct gtx_frame *aframe, char *amsgLine)
310 if (aframe->messageLine)
311 free(aframe->messageLine);
312 aframe->messageLine = gtx_CopyString(amsgLine);
316 /* Called by input processor to try to clear the dude */
318 gtxframe_ClearMessageLine(struct gtx_frame *aframe)
320 /* If we haven't shown message long enough yet, just return */
321 if (aframe->flags & GTXFRAME_NEWDISPLAY)
323 if (aframe->messageLine)
324 free(aframe->messageLine);
325 aframe->messageLine = NULL;
330 ShowMessageLine(struct gtx_frame *aframe)
332 struct gwin_strparams strparms;
333 struct gwin_sizeparams sizeparms;
339 /* First, find window size */
340 WOP_GETDIMENSIONS(aframe->window, &sizeparms);
342 if (aframe->promptLine) {
343 memset(&strparms, 0, sizeof(strparms));
345 strparms.y = sizeparms.maxy - 1;
346 strparms.highlight = 1;
347 tp = strparms.s = (char *)malloc(1024);
348 strcpy(tp, aframe->promptLine);
349 strcat(tp, aframe->defaultLine);
350 WOP_DRAWSTRING(aframe->window, &strparms);
351 aframe->flags |= GTXFRAME_NEWDISPLAY;
352 } else if (aframe->messageLine) {
353 /* Otherwise we're visible, print the message at the bottom */
354 memset(&strparms, 0, sizeof(strparms));
355 strparms.highlight = 1;
357 strparms.y = sizeparms.maxy - 1;
358 strparms.s = aframe->messageLine;
359 WOP_DRAWSTRING(aframe->window, &strparms);
360 aframe->flags |= GTXFRAME_NEWDISPLAY;
365 /* Exit function, returning whatever has been put in its argument */
367 gtxframe_ExitCmd(void *a_exitValuep, void *arock)
368 { /*gtxframe_ExitCmd */
370 int exitval; /*Value we've been asked to exit with */
372 /* This next call should be type independent! */
373 gator_cursesgwin_cleanup(&gator_basegwin);
375 exitval = *((int *)(a_exitValuep));
378 } /*gtxframe_ExitCmd */
381 gtxframe_Create(void)
383 struct gtx_frame *tframe;
384 struct keymap_map *newkeymap;
385 struct keymap_state *newkeystate;
388 * Allocate all the pieces first: frame, keymap, and key state.
390 tframe = (struct gtx_frame *)malloc(sizeof(struct gtx_frame));
391 if (tframe == (struct gtx_frame *)0) {
392 return ((struct gtx_frame *)0);
395 newkeymap = keymap_Create();
396 if (newkeymap == (struct keymap_map *)0) {
398 * Get rid of the frame before exiting.
401 return ((struct gtx_frame *)0);
404 newkeystate = (struct keymap_state *)
405 malloc(sizeof(struct keymap_state));
406 if (newkeystate == (struct keymap_state *)0) {
408 * Get rid of the frame AND the keymap before exiting.
412 return ((struct gtx_frame *)0);
416 * Now that all the pieces exist, fill them in and stick them in
419 memset(tframe, 0, sizeof(struct gtx_frame));
420 tframe->keymap = newkeymap;
421 tframe->keystate = newkeystate;
422 keymap_InitState(tframe->keystate, tframe->keymap);
423 keymap_BindToString(tframe->keymap, "\003", gtxframe_ExitCmd, "ExitCmd",
424 (char *)(>xframe_exitValue));
427 * At this point, we return successfully.
433 gtxframe_Delete(struct gtx_frame *aframe)
435 keymap_Delete(aframe->keymap);
436 free(aframe->keystate);
437 if (aframe->messageLine)
438 free(aframe->messageLine);
444 gtxframe_Display(struct gtx_frame *aframe, struct gwin *awm)
446 register struct gtxframe_dlist *tlist;
447 register struct gtxframe_menu *tm;
448 struct gwin_strparams strparms;
450 /* Run through the menus, displaying them on the top line */
452 for (tm = aframe->menus; tm; tm = tm->next) {
453 strcat(menubuffer, tm->name);
454 strcat(menubuffer, ":");
455 strcat(menubuffer, tm->cmdString);
456 strcat(menubuffer, " ");
458 if (menubuffer[0] != 0) {
459 memset(&strparms, 0, sizeof(strparms));
462 strparms.s = menubuffer;
463 strparms.highlight = 1;
464 WOP_DRAWSTRING(awm, &strparms);
467 /* Run through the display list, displaying all objects */
468 for (tlist = aframe->display; tlist; tlist = tlist->next) {
469 OOP_DISPLAY(((struct onode *)(tlist->data)));
472 /* Finally, show the message line */
473 ShowMessageLine(awm->w_frame);
477 /* Add an object to a window's display list */
479 gtxframe_AddToList(struct gtx_frame *aframe, struct onode *aobj)
481 register struct gtxframe_dlist *tlist;
483 for (tlist = aframe->display; tlist; tlist = tlist->next) {
484 if (tlist->data == (char *)aobj) {
486 * Don't add the same thing twice.
493 * OK, it's not alreadyt there. Create a new list object, fill it
494 * in, and splice it on.
496 tlist = (struct gtxframe_dlist *)malloc(sizeof(struct gtxframe_dlist));
497 if (tlist == (struct gtxframe_dlist *)0)
499 tlist->data = (char *)aobj;
500 tlist->next = aframe->display;
501 aframe->display = tlist;
505 /* Remove an object from a display list, if it is already there */
507 gtxframe_RemoveFromList(struct gtx_frame *aframe, struct onode *aobj)
509 register struct gtxframe_dlist *tlist, **plist;
511 plist = &aframe->display;
512 for (tlist = *plist; tlist; plist = &tlist->next, tlist = *plist) {
513 if (tlist->data == (char *)aobj) {
514 *plist = tlist->next;
519 return (-1); /* Item not found */
522 /* Clear out everything on the display list for the given frame*/
524 gtxframe_ClearList(struct gtx_frame *aframe)
526 register struct gtxframe_dlist *tlist, *nlist;
528 if (aframe->display != (struct gtxframe_dlist *)0) {
530 * Throw away each display list structure (we have at least
533 for (tlist = aframe->display; tlist; tlist = nlist) {
539 aframe->display = (struct gtxframe_dlist *)0;