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>
24 #include "gtxobjects.h"
25 #include "gtxwindows.h"
26 #include "gtxcurseswin.h"
28 #include "gtxkeymap.h"
31 static struct keymap_map
*recursiveMap
= 0;
32 static char menubuffer
[1024]; /*Buffer for menu selections */
33 int gtxframe_exitValue
= 0; /*Program exit value */
36 gtxframe_CtrlUCmd(void *aparam
, void *arock
)
38 struct gwin
*awindow
= (struct gwin
*) aparam
;
39 struct gtx_frame
*tframe
;
41 tframe
= awindow
->w_frame
;
42 if (!tframe
->defaultLine
)
44 *(tframe
->defaultLine
) = 0;
49 gtxframe_CtrlHCmd(void *aparam
, void *arock
)
51 struct gwin
*awindow
= (struct gwin
*) aparam
;
53 struct gtx_frame
*tframe
;
57 tframe
= awindow
->w_frame
;
58 if (!(tp
= tframe
->defaultLine
))
62 return 0; /* rubout at the end of the line */
68 gtxframe_RecursiveEndCmd(void *aparam
, void *arock
)
70 struct gwin
*awindow
= (struct gwin
*) aparam
;
72 struct gtx_frame
*tframe
;
74 tframe
= awindow
->w_frame
;
75 tframe
->flags
|= GTXFRAME_RECURSIVEEND
;
76 tframe
->flags
&= ~GTXFRAME_RECURSIVEERR
;
81 gtxframe_RecursiveErrCmd(void *aparam
, void *arock
)
83 struct gwin
*awindow
= (struct gwin
*) aparam
;
85 struct gtx_frame
*tframe
;
87 tframe
= awindow
->w_frame
;
88 tframe
->flags
|= GTXFRAME_RECURSIVEEND
;
89 tframe
->flags
|= GTXFRAME_RECURSIVEERR
;
94 gtxframe_SelfInsertCmd(void *aparam
, void *rockparam
)
96 struct gwin
*awindow
= (struct gwin
*) aparam
;
98 int arock
= (intptr_t)rockparam
;
100 struct gtx_frame
*tframe
;
104 tframe
= awindow
->w_frame
;
105 if (!(tp
= tframe
->defaultLine
))
108 tp
[pos
] = arock
; /* arock has char to insert */
109 tp
[pos
+ 1] = 0; /* null-terminate it, too */
113 /* save map, setup recursive map and install it */
115 SaveMap(struct gtx_frame
*aframe
)
121 /* setup recursive edit map if not previously done */
122 recursiveMap
= keymap_Create();
123 keymap_BindToString(recursiveMap
, "\010", gtxframe_CtrlHCmd
, NULL
,
125 keymap_BindToString(recursiveMap
, "\177", gtxframe_CtrlHCmd
, NULL
,
127 keymap_BindToString(recursiveMap
, "\025", gtxframe_CtrlUCmd
, NULL
,
129 keymap_BindToString(recursiveMap
, "\033", gtxframe_RecursiveEndCmd
,
131 keymap_BindToString(recursiveMap
, "\015", gtxframe_RecursiveEndCmd
,
133 keymap_BindToString(recursiveMap
, "\012", gtxframe_RecursiveEndCmd
,
135 keymap_BindToString(recursiveMap
, "\003", gtxframe_RecursiveErrCmd
,
137 keymap_BindToString(recursiveMap
, "\007", gtxframe_RecursiveErrCmd
,
140 for (i
= 040; i
< 0177; i
++) {
143 keymap_BindToString(recursiveMap
, tstring
, gtxframe_SelfInsertCmd
,
144 NULL
, (void *)(intptr_t)i
);
147 aframe
->savemap
= aframe
->keymap
;
148 aframe
->keymap
= recursiveMap
;
149 keymap_InitState(aframe
->keystate
, aframe
->keymap
);
153 /* Restore map to previous value */
155 RestoreMap(struct gtx_frame
*aframe
)
157 aframe
->keymap
= aframe
->savemap
;
158 aframe
->savemap
= (struct keymap_map
*)0;
159 keymap_InitState(aframe
->keystate
, aframe
->keymap
);
164 gtxframe_SetFrame(struct gwin
*awin
, struct gtx_frame
*aframe
)
167 /* Unthread this frame */
168 awin
->w_frame
->window
= NULL
;
170 awin
->w_frame
= aframe
;
171 aframe
->window
= awin
; /* Set frame's window ptr */
176 gtxframe_GetFrame(struct gwin
*awin
)
178 return awin
->w_frame
;
181 /* Add a menu string to display list */
183 gtxframe_AddMenu(struct gtx_frame
*aframe
, char *alabel
, char *astring
)
185 struct gtxframe_menu
*tmenu
;
188 for (tmenu
= aframe
->menus
; tmenu
; tmenu
= tmenu
->next
) {
189 if (strcmp(alabel
, tmenu
->name
) == 0)
192 tmenu
= (struct gtxframe_menu
*)0;
194 /* Handle everything but the command string, which is handled by the
195 * common-case code below */
196 tmenu
= (struct gtxframe_menu
*)malloc(sizeof(*tmenu
));
197 if (tmenu
== (struct gtxframe_menu
*)0)
199 memset(tmenu
, 0, sizeof(*tmenu
));
200 tmenu
->next
= aframe
->menus
;
201 aframe
->menus
= tmenu
;
202 tmenu
->name
= gtx_CopyString(alabel
);
206 * Common case: redo the string labels. Note: at this point, tmenu
207 * points to a valid menu.
209 if (tmenu
->cmdString
)
210 free(tmenu
->cmdString
);
211 tmenu
->cmdString
= gtx_CopyString(astring
);
215 /* Delete a given menu from a frame*/
217 gtxframe_DeleteMenu(struct gtx_frame
*aframe
, char *alabel
)
219 struct gtxframe_menu
*tm
, **lm
;
221 for (lm
= &aframe
->menus
, tm
= *lm
; tm
; lm
= &tm
->next
, tm
= *lm
) {
222 if (strcmp(alabel
, tm
->name
) == 0) {
223 /* found it, remove and return success */
224 *lm
= tm
->next
; /* unthread from list */
231 return (-1); /* failed to find entry to delete */
234 /* Function to remove all known menus */
236 gtxframe_ClearMenus(struct gtx_frame
*aframe
)
239 struct gtxframe_menu
*tm
, *nm
;
241 if (aframe
->menus
!= (struct gtxframe_menu
*)0) {
242 for (tm
= aframe
->menus
; tm
; tm
= nm
) {
250 aframe
->menus
= (struct gtxframe_menu
*)0;
255 gtxframe_AskForString(struct gtx_frame
*aframe
, char *aprompt
,
256 char *adefault
, char *aresult
, int aresultSize
)
261 /* Ensure recursive-edit map is initialized */
265 if (aframe
->promptLine
)
266 free(aframe
->promptLine
);
267 if (aframe
->defaultLine
)
268 free(aframe
->defaultLine
);
269 aframe
->promptLine
= gtx_CopyString(aprompt
);
270 tp
= aframe
->defaultLine
= (char *)malloc(1024);
274 strcpy(tp
, adefault
);
278 /* Do recursive edit */
279 gtx_InputServer(aframe
->window
);
280 tp
= aframe
->defaultLine
; /* In case command reallocated it */
282 /* Back from recursive edit, check out what's happened */
283 if (aframe
->flags
& GTXFRAME_RECURSIVEERR
) {
288 if (code
+ 1 > aresultSize
) {
295 /* Fall through to cleanup and return code */
298 if (aframe
->promptLine
)
299 free(aframe
->promptLine
);
300 if (aframe
->defaultLine
)
301 free(aframe
->defaultLine
);
302 aframe
->defaultLine
= aframe
->promptLine
= NULL
;
304 gtxframe_DisplayString(aframe
, "[Aborted]");
309 gtxframe_DisplayString(struct gtx_frame
*aframe
, char *amsgLine
)
311 if (aframe
->messageLine
)
312 free(aframe
->messageLine
);
313 aframe
->messageLine
= gtx_CopyString(amsgLine
);
317 /* Called by input processor to try to clear the dude */
319 gtxframe_ClearMessageLine(struct gtx_frame
*aframe
)
321 /* If we haven't shown message long enough yet, just return */
322 if (aframe
->flags
& GTXFRAME_NEWDISPLAY
)
324 if (aframe
->messageLine
)
325 free(aframe
->messageLine
);
326 aframe
->messageLine
= NULL
;
331 ShowMessageLine(struct gtx_frame
*aframe
)
333 struct gwin_strparams strparms
;
334 struct gwin_sizeparams sizeparms
;
340 /* First, find window size */
341 WOP_GETDIMENSIONS(aframe
->window
, &sizeparms
);
343 if (aframe
->promptLine
) {
344 memset(&strparms
, 0, sizeof(strparms
));
346 strparms
.y
= sizeparms
.maxy
- 1;
347 strparms
.highlight
= 1;
348 tp
= strparms
.s
= (char *)malloc(1024);
349 strcpy(tp
, aframe
->promptLine
);
350 strcat(tp
, aframe
->defaultLine
);
351 WOP_DRAWSTRING(aframe
->window
, &strparms
);
352 aframe
->flags
|= GTXFRAME_NEWDISPLAY
;
353 } else if (aframe
->messageLine
) {
354 /* Otherwise we're visible, print the message at the bottom */
355 memset(&strparms
, 0, sizeof(strparms
));
356 strparms
.highlight
= 1;
358 strparms
.y
= sizeparms
.maxy
- 1;
359 strparms
.s
= aframe
->messageLine
;
360 WOP_DRAWSTRING(aframe
->window
, &strparms
);
361 aframe
->flags
|= GTXFRAME_NEWDISPLAY
;
366 /* Exit function, returning whatever has been put in its argument */
368 gtxframe_ExitCmd(void *a_exitValuep
, void *arock
)
369 { /*gtxframe_ExitCmd */
371 int exitval
; /*Value we've been asked to exit with */
373 /* This next call should be type independent! */
374 gator_cursesgwin_cleanup(&gator_basegwin
);
376 exitval
= *((int *)(a_exitValuep
));
379 } /*gtxframe_ExitCmd */
382 gtxframe_Create(void)
384 struct gtx_frame
*tframe
;
385 struct keymap_map
*newkeymap
;
386 struct keymap_state
*newkeystate
;
389 * Allocate all the pieces first: frame, keymap, and key state.
391 tframe
= (struct gtx_frame
*)malloc(sizeof(struct gtx_frame
));
392 if (tframe
== (struct gtx_frame
*)0) {
393 return ((struct gtx_frame
*)0);
396 newkeymap
= keymap_Create();
397 if (newkeymap
== (struct keymap_map
*)0) {
399 * Get rid of the frame before exiting.
402 return ((struct gtx_frame
*)0);
405 newkeystate
= (struct keymap_state
*)
406 malloc(sizeof(struct keymap_state
));
407 if (newkeystate
== (struct keymap_state
*)0) {
409 * Get rid of the frame AND the keymap before exiting.
413 return ((struct gtx_frame
*)0);
417 * Now that all the pieces exist, fill them in and stick them in
420 memset(tframe
, 0, sizeof(struct gtx_frame
));
421 tframe
->keymap
= newkeymap
;
422 tframe
->keystate
= newkeystate
;
423 keymap_InitState(tframe
->keystate
, tframe
->keymap
);
424 keymap_BindToString(tframe
->keymap
, "\003", gtxframe_ExitCmd
, "ExitCmd",
425 (char *)(>xframe_exitValue
));
428 * At this point, we return successfully.
434 gtxframe_Delete(struct gtx_frame
*aframe
)
436 keymap_Delete(aframe
->keymap
);
437 free(aframe
->keystate
);
438 if (aframe
->messageLine
)
439 free(aframe
->messageLine
);
445 gtxframe_Display(struct gtx_frame
*aframe
, struct gwin
*awm
)
447 struct gtxframe_dlist
*tlist
;
448 struct gtxframe_menu
*tm
;
449 struct gwin_strparams strparms
;
451 /* Run through the menus, displaying them on the top line */
453 for (tm
= aframe
->menus
; tm
; tm
= tm
->next
) {
454 strcat(menubuffer
, tm
->name
);
455 strcat(menubuffer
, ":");
456 strcat(menubuffer
, tm
->cmdString
);
457 strcat(menubuffer
, " ");
459 if (menubuffer
[0] != 0) {
460 memset(&strparms
, 0, sizeof(strparms
));
463 strparms
.s
= menubuffer
;
464 strparms
.highlight
= 1;
465 WOP_DRAWSTRING(awm
, &strparms
);
468 /* Run through the display list, displaying all objects */
469 for (tlist
= aframe
->display
; tlist
; tlist
= tlist
->next
) {
470 OOP_DISPLAY(((struct onode
*)(tlist
->data
)));
473 /* Finally, show the message line */
474 ShowMessageLine(awm
->w_frame
);
478 /* Add an object to a window's display list */
480 gtxframe_AddToList(struct gtx_frame
*aframe
, struct onode
*aobj
)
482 struct gtxframe_dlist
*tlist
;
484 for (tlist
= aframe
->display
; tlist
; tlist
= tlist
->next
) {
485 if (tlist
->data
== (char *)aobj
) {
487 * Don't add the same thing twice.
494 * OK, it's not alreadyt there. Create a new list object, fill it
495 * in, and splice it on.
497 tlist
= (struct gtxframe_dlist
*)malloc(sizeof(struct gtxframe_dlist
));
498 if (tlist
== (struct gtxframe_dlist
*)0)
500 tlist
->data
= (char *)aobj
;
501 tlist
->next
= aframe
->display
;
502 aframe
->display
= tlist
;
506 /* Remove an object from a display list, if it is already there */
508 gtxframe_RemoveFromList(struct gtx_frame
*aframe
, struct onode
*aobj
)
510 struct gtxframe_dlist
*tlist
, **plist
;
512 plist
= &aframe
->display
;
513 for (tlist
= *plist
; tlist
; plist
= &tlist
->next
, tlist
= *plist
) {
514 if (tlist
->data
== (char *)aobj
) {
515 *plist
= tlist
->next
;
520 return (-1); /* Item not found */
523 /* Clear out everything on the display list for the given frame*/
525 gtxframe_ClearList(struct gtx_frame
*aframe
)
527 struct gtxframe_dlist
*tlist
, *nlist
;
529 if (aframe
->display
!= (struct gtxframe_dlist
*)0) {
531 * Throw away each display list structure (we have at least
534 for (tlist
= aframe
->display
; tlist
; tlist
= nlist
) {
540 aframe
->display
= (struct gtxframe_dlist
*)0;