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>
21 #include "gtxobjects.h"
22 #include "gtxwindows.h"
23 #include "gtxcurseswin.h"
25 #include "gtxkeymap.h"
28 extern char *gtx_CopyString();
29 static struct keymap_map *recursiveMap=0;
30 static char menubuffer[1024]; /*Buffer for menu selections*/
31 int gtxframe_exitValue = 0; /*Program exit value*/
33 gtxframe_CtrlUCmd(awindow, arock)
35 struct gwin *awindow; {
36 struct gtx_frame *tframe;
38 tframe = awindow->w_frame;
39 if (!tframe->defaultLine) return -1;
40 *(tframe->defaultLine) = 0;
44 gtxframe_CtrlHCmd(awindow, arock)
46 struct gwin *awindow; {
47 register struct gtx_frame *tframe;
51 tframe = awindow->w_frame;
52 if (!(tp=tframe->defaultLine)) return -1;
54 if (pos == 0) return 0; /* rubout at the end of the line */
59 gtxframe_RecursiveEndCmd(awindow, arock)
61 register struct gwin *awindow; {
62 register struct gtx_frame *tframe;
64 tframe = awindow->w_frame;
65 tframe->flags |= GTXFRAME_RECURSIVEEND;
66 tframe->flags &= ~GTXFRAME_RECURSIVEERR;
70 gtxframe_RecursiveErrCmd(awindow, arock)
72 register struct gwin *awindow; {
73 register struct gtx_frame *tframe;
75 tframe = awindow->w_frame;
76 tframe->flags |= GTXFRAME_RECURSIVEEND;
77 tframe->flags |= GTXFRAME_RECURSIVEERR;
81 gtxframe_SelfInsertCmd(awindow, arock)
83 struct gwin *awindow; {
84 register struct gtx_frame *tframe;
88 tframe = awindow->w_frame;
89 if (!(tp = tframe->defaultLine)) return -1;
91 tp[pos] = arock; /* arock has char to insert */
92 tp[pos+1] = 0; /* null-terminate it, too */
96 /* save map, setup recursive map and install it */
97 static SaveMap(aframe)
98 register struct gtx_frame *aframe; {
103 /* setup recursive edit map if not previously done */
104 recursiveMap = keymap_Create();
105 keymap_BindToString(recursiveMap,
110 keymap_BindToString(recursiveMap,
111 "\177",gtxframe_CtrlHCmd,
114 keymap_BindToString(recursiveMap,
119 keymap_BindToString(recursiveMap,
121 gtxframe_RecursiveEndCmd,
124 keymap_BindToString(recursiveMap,
126 gtxframe_RecursiveEndCmd,
129 keymap_BindToString(recursiveMap,
131 gtxframe_RecursiveEndCmd,
134 keymap_BindToString(recursiveMap,
136 gtxframe_RecursiveErrCmd,
139 keymap_BindToString(recursiveMap,
141 gtxframe_RecursiveErrCmd,
145 for(i=040; i<0177; i++) {
148 keymap_BindToString(recursiveMap, tstring, gtxframe_SelfInsertCmd,
152 aframe->savemap = aframe->keymap;
153 aframe->keymap = recursiveMap;
154 keymap_InitState(aframe->keystate, aframe->keymap);
158 /* Restore map to previous value */
159 static RestoreMap(aframe)
160 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;
171 /* Unthread this frame */
172 awin->w_frame->window = (struct gwin *) 0;
174 awin->w_frame = aframe;
175 aframe->window = awin; /* Set frame's window ptr */
179 struct gtx_frame *gtxframe_GetFrame(awin)
181 return awin->w_frame;
184 /* Add a menu string to display list */
185 gtxframe_AddMenu(aframe, alabel, astring)
188 struct gtx_frame *aframe; {
189 register struct gtxframe_menu *tmenu;
192 for(tmenu = aframe->menus; tmenu; tmenu = tmenu->next) {
193 if (strcmp(alabel, tmenu->name)==0) break;
196 tmenu = (struct gtxframe_menu *)0;
198 /* Handle everything but the command string, which is handled by the
199 common-case code below */
200 tmenu = (struct gtxframe_menu *) malloc(sizeof(*tmenu));
201 if (tmenu == (struct gtxframe_menu *)0)
203 memset(tmenu, 0, sizeof(*tmenu));
204 tmenu->next = aframe->menus;
205 aframe->menus = tmenu;
206 tmenu->name = gtx_CopyString(alabel);
210 * Common case: redo the string labels. Note: at this point, tmenu
211 * points to a valid menu.
213 if (tmenu->cmdString)
214 free(tmenu->cmdString);
215 tmenu->cmdString = gtx_CopyString(astring);
219 /* Delete a given menu from a frame*/
220 gtxframe_DeleteMenu(aframe, alabel)
221 struct gtx_frame *aframe;
223 register struct gtxframe_menu *tm, **lm;
225 for(lm = &aframe->menus, tm = *lm; tm; lm = &tm->next, tm = *lm) {
226 if (strcmp(alabel, tm->name) == 0) {
227 /* found it, remove and return success */
228 *lm = tm->next; /* unthread from list */
235 return(-1); /* failed to find entry to delete */
238 /* Function to remove all known menus */
239 gtxframe_ClearMenus(aframe)
240 struct gtx_frame *aframe; {
242 register struct gtxframe_menu *tm, *nm;
244 if (aframe->menus != (struct gtxframe_menu *)0) {
245 for(tm=aframe->menus; tm; tm=nm) {
253 aframe->menus = (struct gtxframe_menu *) 0;
257 gtxframe_AskForString(aframe, aprompt, adefault, aresult, aresultSize)
258 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 = (char *) 0;
309 gtxframe_DisplayString(aframe, "[Aborted]");
313 gtxframe_DisplayString(aframe, amsgLine)
315 register struct gtx_frame *aframe; {
316 if (aframe->messageLine)
317 free(aframe->messageLine);
318 aframe->messageLine = gtx_CopyString(amsgLine);
321 /* Called by input processor to try to clear the dude */
322 gtxframe_ClearMessageLine(aframe)
323 struct gtx_frame *aframe; {
324 /* If we haven't shown message long enough yet, just return */
325 if (aframe->flags & GTXFRAME_NEWDISPLAY)
327 if (aframe->messageLine)
328 free(aframe->messageLine);
329 aframe->messageLine = (char *) 0;
333 static ShowMessageLine(aframe)
334 struct gtx_frame *aframe; {
335 struct gwin_strparams strparms;
336 struct gwin_sizeparams sizeparms;
339 if (!aframe->window) return -1;
341 /* First, find window size */
342 WOP_GETDIMENSIONS(aframe->window, &sizeparms);
344 if (aframe->promptLine) {
345 memset(&strparms, 0, sizeof(strparms));
347 strparms.y = sizeparms.maxy-1;
348 strparms.highlight = 1;
349 tp = strparms.s = (char *) malloc(1024);
350 strcpy(tp, aframe->promptLine);
351 strcat(tp, aframe->defaultLine);
352 WOP_DRAWSTRING(aframe->window, &strparms);
353 aframe->flags |= GTXFRAME_NEWDISPLAY;
355 else if (aframe->messageLine) {
356 /* Otherwise we're visible, print the message at the bottom */
357 memset(&strparms, 0, sizeof(strparms));
358 strparms.highlight = 1;
360 strparms.y = sizeparms.maxy-1;
361 strparms.s = aframe->messageLine;
362 WOP_DRAWSTRING(aframe->window, &strparms);
363 aframe->flags |= GTXFRAME_NEWDISPLAY;
368 /* Exit function, returning whatever has been put in its argument */
369 int gtxframe_ExitCmd(a_exitValuep)
372 { /*gtxframe_ExitCmd*/
374 int exitval; /*Value we've been asked to exit with*/
376 /* This next call should be type independent! */
377 gator_cursesgwin_cleanup(&gator_basegwin);
379 exitval = *((int *)(a_exitValuep));
382 } /*gtxframe_ExitCmd*/
384 struct gtx_frame *gtxframe_Create() {
385 struct gtx_frame *tframe;
386 struct keymap_map *newkeymap;
387 struct keymap_state *newkeystate;
390 * Allocate all the pieces first: frame, keymap, and key state.
392 tframe = (struct gtx_frame *) malloc (sizeof(struct gtx_frame));
393 if (tframe == (struct gtx_frame *)0) {
394 return((struct gtx_frame *)0);
397 newkeymap = keymap_Create();
398 if (newkeymap == (struct keymap_map *)0) {
400 * Get rid of the frame before exiting.
403 return((struct gtx_frame *)0);
406 newkeystate = (struct keymap_state *)
407 malloc(sizeof(struct keymap_state));
408 if (newkeystate == (struct keymap_state *)0) {
410 * Get rid of the frame AND the keymap before exiting.
414 return((struct gtx_frame *)0);
418 * Now that all the pieces exist, fill them in and stick them in
421 memset(tframe, 0, sizeof(struct gtx_frame));
422 tframe->keymap = newkeymap;
423 tframe->keystate = newkeystate;
424 keymap_InitState(tframe->keystate, tframe->keymap);
425 keymap_BindToString(tframe->keymap,
429 (char *) (>xframe_exitValue));
432 * At this point, we return successfully.
437 gtxframe_Delete(aframe)
438 register struct gtx_frame *aframe; {
439 keymap_Delete(aframe->keymap);
440 free(aframe->keystate);
441 if (aframe->messageLine)
442 free(aframe->messageLine);
447 gtxframe_Display(aframe, awm)
449 register struct gtx_frame *aframe; {
450 register struct gtxframe_dlist *tlist;
451 register struct gtxframe_menu *tm;
452 struct gwin_strparams strparms;
454 /* Run through the menus, displaying them on the top line */
456 for(tm = aframe->menus; tm; tm = tm->next) {
457 strcat(menubuffer, tm->name);
458 strcat(menubuffer, ":");
459 strcat(menubuffer, tm->cmdString);
460 strcat(menubuffer, " ");
462 if (menubuffer[0] != 0) {
463 memset(&strparms, 0, sizeof(strparms));
466 strparms.s = menubuffer;
467 strparms.highlight = 1;
468 WOP_DRAWSTRING(awm, &strparms);
471 /* Run through the display list, displaying all objects */
472 for(tlist=aframe->display; tlist; tlist=tlist->next) {
473 OOP_DISPLAY(((struct onode *)(tlist->data)));
476 /* Finally, show the message line */
477 ShowMessageLine(awm->w_frame);
481 /* Add an object to a window's display list */
482 gtxframe_AddToList(aframe, aobj)
484 register struct gtx_frame *aframe; {
485 register struct gtxframe_dlist *tlist;
487 for(tlist = aframe->display; tlist; tlist=tlist->next) {
488 if (tlist->data == (char *) aobj) {
490 * Don't add the same thing twice.
497 * OK, it's not alreadyt there. Create a new list object, fill it
498 * in, and splice it on.
500 tlist = (struct gtxframe_dlist *) malloc(sizeof(struct gtxframe_dlist));
501 if (tlist == (struct gtxframe_dlist *)0)
503 tlist->data = (char *) aobj;
504 tlist->next = aframe->display;
505 aframe->display = tlist;
509 /* Remove an object from a display list, if it is already there */
510 gtxframe_RemoveFromList(aframe, aobj)
512 register struct gtx_frame *aframe; {
513 register struct gtxframe_dlist *tlist, **plist;
515 plist = &aframe->display;
516 for(tlist = *plist; tlist; plist = &tlist->next, tlist = *plist) {
517 if (tlist->data == (char *) aobj) {
518 *plist = tlist->next;
523 return(-1); /* Item not found */
526 /* Clear out everything on the display list for the given frame*/
527 gtxframe_ClearList(aframe)
528 register struct gtx_frame *aframe; {
529 register struct gtxframe_dlist *tlist, *nlist;
531 if (aframe->display != (struct gtxframe_dlist *)0) {
533 * Throw away each display list structure (we have at least
536 for(tlist = aframe->display; tlist; tlist = nlist) {
542 aframe->display = (struct gtxframe_dlist *) 0;