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>
17 #include <sys/types.h>
30 #include "gtxobjects.h"
31 #include "gtxwindows.h"
32 #include "gtxcurseswin.h"
34 #include "gtxkeymap.h"
37 extern char *gtx_CopyString();
38 static struct keymap_map *recursiveMap=0;
39 static char menubuffer[1024]; /*Buffer for menu selections*/
40 int gtxframe_exitValue = 0; /*Program exit value*/
42 gtxframe_CtrlUCmd(awindow, arock)
44 struct gwin *awindow; {
45 struct gtx_frame *tframe;
47 tframe = awindow->w_frame;
48 if (!tframe->defaultLine) return -1;
49 *(tframe->defaultLine) = 0;
53 gtxframe_CtrlHCmd(awindow, arock)
55 struct gwin *awindow; {
56 register struct gtx_frame *tframe;
60 tframe = awindow->w_frame;
61 if (!(tp=tframe->defaultLine)) return -1;
63 if (pos == 0) return 0; /* rubout at the end of the line */
68 gtxframe_RecursiveEndCmd(awindow, arock)
70 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; {
82 register struct gtx_frame *tframe;
84 tframe = awindow->w_frame;
85 tframe->flags |= GTXFRAME_RECURSIVEEND;
86 tframe->flags |= GTXFRAME_RECURSIVEERR;
90 gtxframe_SelfInsertCmd(awindow, arock)
92 struct gwin *awindow; {
93 register struct gtx_frame *tframe;
97 tframe = awindow->w_frame;
98 if (!(tp = tframe->defaultLine)) return -1;
100 tp[pos] = arock; /* arock has char to insert */
101 tp[pos+1] = 0; /* null-terminate it, too */
105 /* save map, setup recursive map and install it */
106 static SaveMap(aframe)
107 register struct gtx_frame *aframe; {
112 /* setup recursive edit map if not previously done */
113 recursiveMap = keymap_Create();
114 keymap_BindToString(recursiveMap,
119 keymap_BindToString(recursiveMap,
120 "\177",gtxframe_CtrlHCmd,
123 keymap_BindToString(recursiveMap,
128 keymap_BindToString(recursiveMap,
130 gtxframe_RecursiveEndCmd,
133 keymap_BindToString(recursiveMap,
135 gtxframe_RecursiveEndCmd,
138 keymap_BindToString(recursiveMap,
140 gtxframe_RecursiveEndCmd,
143 keymap_BindToString(recursiveMap,
145 gtxframe_RecursiveErrCmd,
148 keymap_BindToString(recursiveMap,
150 gtxframe_RecursiveErrCmd,
154 for(i=040; i<0177; i++) {
157 keymap_BindToString(recursiveMap, tstring, gtxframe_SelfInsertCmd,
161 aframe->savemap = aframe->keymap;
162 aframe->keymap = recursiveMap;
163 keymap_InitState(aframe->keystate, aframe->keymap);
167 /* Restore map to previous value */
168 static RestoreMap(aframe)
169 register struct gtx_frame *aframe; {
170 aframe->keymap = aframe->savemap;
171 aframe->savemap = (struct keymap_map *) 0;
172 keymap_InitState(aframe->keystate, aframe->keymap);
176 gtxframe_SetFrame(awin, aframe)
177 struct gtx_frame *aframe;
180 /* Unthread this frame */
181 awin->w_frame->window = NULL;
183 awin->w_frame = aframe;
184 aframe->window = awin; /* Set frame's window ptr */
188 struct gtx_frame *gtxframe_GetFrame(awin)
190 return awin->w_frame;
193 /* Add a menu string to display list */
194 gtxframe_AddMenu(aframe, alabel, astring)
197 struct gtx_frame *aframe; {
198 register struct gtxframe_menu *tmenu;
201 for(tmenu = aframe->menus; tmenu; tmenu = tmenu->next) {
202 if (strcmp(alabel, tmenu->name)==0) break;
205 tmenu = (struct gtxframe_menu *)0;
207 /* Handle everything but the command string, which is handled by the
208 common-case code below */
209 tmenu = (struct gtxframe_menu *) malloc(sizeof(*tmenu));
210 if (tmenu == (struct gtxframe_menu *)0)
212 memset(tmenu, 0, sizeof(*tmenu));
213 tmenu->next = aframe->menus;
214 aframe->menus = tmenu;
215 tmenu->name = gtx_CopyString(alabel);
219 * Common case: redo the string labels. Note: at this point, tmenu
220 * points to a valid menu.
222 if (tmenu->cmdString)
223 free(tmenu->cmdString);
224 tmenu->cmdString = gtx_CopyString(astring);
228 /* Delete a given menu from a frame*/
229 gtxframe_DeleteMenu(aframe, alabel)
230 struct gtx_frame *aframe;
232 register struct gtxframe_menu *tm, **lm;
234 for(lm = &aframe->menus, tm = *lm; tm; lm = &tm->next, tm = *lm) {
235 if (strcmp(alabel, tm->name) == 0) {
236 /* found it, remove and return success */
237 *lm = tm->next; /* unthread from list */
244 return(-1); /* failed to find entry to delete */
247 /* Function to remove all known menus */
248 gtxframe_ClearMenus(aframe)
249 struct gtx_frame *aframe; {
251 register struct gtxframe_menu *tm, *nm;
253 if (aframe->menus != (struct gtxframe_menu *)0) {
254 for(tm=aframe->menus; tm; tm=nm) {
262 aframe->menus = (struct gtxframe_menu *) 0;
266 gtxframe_AskForString(aframe, aprompt, adefault, aresult, aresultSize)
267 register struct gtx_frame *aframe;
275 /* Ensure recursive-edit map is initialized */
279 if (aframe->promptLine)
280 free(aframe->promptLine);
281 if (aframe->defaultLine)
282 free(aframe->defaultLine);
283 aframe->promptLine = gtx_CopyString(aprompt);
284 tp = aframe->defaultLine = (char *) malloc(1024);
288 strcpy(tp, adefault);
292 /* Do recursive edit */
293 gtx_InputServer(aframe->window);
294 tp = aframe->defaultLine; /* In case command reallocated it */
296 /* Back from recursive edit, check out what's happened */
297 if (aframe->flags & GTXFRAME_RECURSIVEERR) {
302 if (code+1 > aresultSize) {
309 /* Fall through to cleanup and return code */
312 if (aframe->promptLine)
313 free(aframe->promptLine);
314 if (aframe->defaultLine)
315 free(aframe->defaultLine);
316 aframe->defaultLine = aframe->promptLine = NULL;
318 gtxframe_DisplayString(aframe, "[Aborted]");
322 gtxframe_DisplayString(aframe, amsgLine)
324 register struct gtx_frame *aframe; {
325 if (aframe->messageLine)
326 free(aframe->messageLine);
327 aframe->messageLine = gtx_CopyString(amsgLine);
330 /* Called by input processor to try to clear the dude */
331 gtxframe_ClearMessageLine(aframe)
332 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;
342 static ShowMessageLine(aframe)
343 struct gtx_frame *aframe; {
344 struct gwin_strparams strparms;
345 struct gwin_sizeparams sizeparms;
348 if (!aframe->window) return -1;
350 /* First, find window size */
351 WOP_GETDIMENSIONS(aframe->window, &sizeparms);
353 if (aframe->promptLine) {
354 memset(&strparms, 0, sizeof(strparms));
356 strparms.y = sizeparms.maxy-1;
357 strparms.highlight = 1;
358 tp = strparms.s = (char *) malloc(1024);
359 strcpy(tp, aframe->promptLine);
360 strcat(tp, aframe->defaultLine);
361 WOP_DRAWSTRING(aframe->window, &strparms);
362 aframe->flags |= GTXFRAME_NEWDISPLAY;
364 else if (aframe->messageLine) {
365 /* Otherwise we're visible, print the message at the bottom */
366 memset(&strparms, 0, sizeof(strparms));
367 strparms.highlight = 1;
369 strparms.y = sizeparms.maxy-1;
370 strparms.s = aframe->messageLine;
371 WOP_DRAWSTRING(aframe->window, &strparms);
372 aframe->flags |= GTXFRAME_NEWDISPLAY;
377 /* Exit function, returning whatever has been put in its argument */
378 int gtxframe_ExitCmd(a_exitValuep)
381 { /*gtxframe_ExitCmd*/
383 int exitval; /*Value we've been asked to exit with*/
385 /* This next call should be type independent! */
386 gator_cursesgwin_cleanup(&gator_basegwin);
388 exitval = *((int *)(a_exitValuep));
391 } /*gtxframe_ExitCmd*/
393 struct gtx_frame *gtxframe_Create() {
394 struct gtx_frame *tframe;
395 struct keymap_map *newkeymap;
396 struct keymap_state *newkeystate;
399 * Allocate all the pieces first: frame, keymap, and key state.
401 tframe = (struct gtx_frame *) malloc (sizeof(struct gtx_frame));
402 if (tframe == (struct gtx_frame *)0) {
403 return((struct gtx_frame *)0);
406 newkeymap = keymap_Create();
407 if (newkeymap == (struct keymap_map *)0) {
409 * Get rid of the frame before exiting.
412 return((struct gtx_frame *)0);
415 newkeystate = (struct keymap_state *)
416 malloc(sizeof(struct keymap_state));
417 if (newkeystate == (struct keymap_state *)0) {
419 * Get rid of the frame AND the keymap before exiting.
423 return((struct gtx_frame *)0);
427 * Now that all the pieces exist, fill them in and stick them in
430 memset(tframe, 0, sizeof(struct gtx_frame));
431 tframe->keymap = newkeymap;
432 tframe->keystate = newkeystate;
433 keymap_InitState(tframe->keystate, tframe->keymap);
434 keymap_BindToString(tframe->keymap,
438 (char *) (>xframe_exitValue));
441 * At this point, we return successfully.
446 gtxframe_Delete(aframe)
447 register struct gtx_frame *aframe; {
448 keymap_Delete(aframe->keymap);
449 free(aframe->keystate);
450 if (aframe->messageLine)
451 free(aframe->messageLine);
456 gtxframe_Display(aframe, awm)
458 register struct gtx_frame *aframe; {
459 register struct gtxframe_dlist *tlist;
460 register struct gtxframe_menu *tm;
461 struct gwin_strparams strparms;
463 /* Run through the menus, displaying them on the top line */
465 for(tm = aframe->menus; tm; tm = tm->next) {
466 strcat(menubuffer, tm->name);
467 strcat(menubuffer, ":");
468 strcat(menubuffer, tm->cmdString);
469 strcat(menubuffer, " ");
471 if (menubuffer[0] != 0) {
472 memset(&strparms, 0, sizeof(strparms));
475 strparms.s = menubuffer;
476 strparms.highlight = 1;
477 WOP_DRAWSTRING(awm, &strparms);
480 /* Run through the display list, displaying all objects */
481 for(tlist=aframe->display; tlist; tlist=tlist->next) {
482 OOP_DISPLAY(((struct onode *)(tlist->data)));
485 /* Finally, show the message line */
486 ShowMessageLine(awm->w_frame);
490 /* Add an object to a window's display list */
491 gtxframe_AddToList(aframe, aobj)
493 register struct gtx_frame *aframe; {
494 register struct gtxframe_dlist *tlist;
496 for(tlist = aframe->display; tlist; tlist=tlist->next) {
497 if (tlist->data == (char *) aobj) {
499 * Don't add the same thing twice.
506 * OK, it's not alreadyt there. Create a new list object, fill it
507 * in, and splice it on.
509 tlist = (struct gtxframe_dlist *) malloc(sizeof(struct gtxframe_dlist));
510 if (tlist == (struct gtxframe_dlist *)0)
512 tlist->data = (char *) aobj;
513 tlist->next = aframe->display;
514 aframe->display = tlist;
518 /* Remove an object from a display list, if it is already there */
519 gtxframe_RemoveFromList(aframe, aobj)
521 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; {
538 register struct gtxframe_dlist *tlist, *nlist;
540 if (aframe->display != (struct gtxframe_dlist *)0) {
542 * Throw away each display list structure (we have at least
545 for(tlist = aframe->display; tlist; tlist = nlist) {
551 aframe->display = (struct gtxframe_dlist *) 0;