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>
18 #include "gtxobjects.h"
19 #include "gtxwindows.h"
20 #include "gtxcurseswin.h"
22 #include "gtxkeymap.h"
25 static struct keymap_map
*recursiveMap
= 0;
26 static char menubuffer
[1024]; /*Buffer for menu selections */
27 int gtxframe_exitValue
= 0; /*Program exit value */
30 gtxframe_CtrlUCmd(void *aparam
, void *arock
)
32 struct gwin
*awindow
= (struct gwin
*) aparam
;
33 struct gtx_frame
*tframe
;
35 tframe
= awindow
->w_frame
;
36 if (!tframe
->defaultLine
)
38 *(tframe
->defaultLine
) = 0;
43 gtxframe_CtrlHCmd(void *aparam
, void *arock
)
45 struct gwin
*awindow
= (struct gwin
*) aparam
;
47 struct gtx_frame
*tframe
;
51 tframe
= awindow
->w_frame
;
52 if (!(tp
= tframe
->defaultLine
))
56 return 0; /* rubout at the end of the line */
62 gtxframe_RecursiveEndCmd(void *aparam
, void *arock
)
64 struct gwin
*awindow
= (struct gwin
*) aparam
;
66 struct gtx_frame
*tframe
;
68 tframe
= awindow
->w_frame
;
69 tframe
->flags
|= GTXFRAME_RECURSIVEEND
;
70 tframe
->flags
&= ~GTXFRAME_RECURSIVEERR
;
75 gtxframe_RecursiveErrCmd(void *aparam
, void *arock
)
77 struct gwin
*awindow
= (struct gwin
*) aparam
;
79 struct gtx_frame
*tframe
;
81 tframe
= awindow
->w_frame
;
82 tframe
->flags
|= GTXFRAME_RECURSIVEEND
;
83 tframe
->flags
|= GTXFRAME_RECURSIVEERR
;
88 gtxframe_SelfInsertCmd(void *aparam
, void *rockparam
)
90 struct gwin
*awindow
= (struct gwin
*) aparam
;
92 int arock
= (intptr_t)rockparam
;
94 struct gtx_frame
*tframe
;
98 tframe
= awindow
->w_frame
;
99 if (!(tp
= tframe
->defaultLine
))
102 tp
[pos
] = arock
; /* arock has char to insert */
103 tp
[pos
+ 1] = 0; /* null-terminate it, too */
107 /* save map, setup recursive map and install it */
109 SaveMap(struct gtx_frame
*aframe
)
115 /* setup recursive edit map if not previously done */
116 recursiveMap
= keymap_Create();
117 keymap_BindToString(recursiveMap
, "\010", gtxframe_CtrlHCmd
, NULL
,
119 keymap_BindToString(recursiveMap
, "\177", gtxframe_CtrlHCmd
, NULL
,
121 keymap_BindToString(recursiveMap
, "\025", gtxframe_CtrlUCmd
, NULL
,
123 keymap_BindToString(recursiveMap
, "\033", gtxframe_RecursiveEndCmd
,
125 keymap_BindToString(recursiveMap
, "\015", gtxframe_RecursiveEndCmd
,
127 keymap_BindToString(recursiveMap
, "\012", gtxframe_RecursiveEndCmd
,
129 keymap_BindToString(recursiveMap
, "\003", gtxframe_RecursiveErrCmd
,
131 keymap_BindToString(recursiveMap
, "\007", gtxframe_RecursiveErrCmd
,
134 for (i
= 040; i
< 0177; i
++) {
137 keymap_BindToString(recursiveMap
, tstring
, gtxframe_SelfInsertCmd
,
138 NULL
, (void *)(intptr_t)i
);
141 aframe
->savemap
= aframe
->keymap
;
142 aframe
->keymap
= recursiveMap
;
143 keymap_InitState(aframe
->keystate
, aframe
->keymap
);
147 /* Restore map to previous value */
149 RestoreMap(struct gtx_frame
*aframe
)
151 aframe
->keymap
= aframe
->savemap
;
152 aframe
->savemap
= (struct keymap_map
*)0;
153 keymap_InitState(aframe
->keystate
, aframe
->keymap
);
158 gtxframe_SetFrame(struct gwin
*awin
, struct gtx_frame
*aframe
)
161 /* Unthread this frame */
162 awin
->w_frame
->window
= NULL
;
164 awin
->w_frame
= aframe
;
165 aframe
->window
= awin
; /* Set frame's window ptr */
170 gtxframe_GetFrame(struct gwin
*awin
)
172 return awin
->w_frame
;
175 /* Add a menu string to display list */
177 gtxframe_AddMenu(struct gtx_frame
*aframe
, char *alabel
, char *astring
)
179 struct gtxframe_menu
*tmenu
;
182 for (tmenu
= aframe
->menus
; tmenu
; tmenu
= tmenu
->next
) {
183 if (strcmp(alabel
, tmenu
->name
) == 0)
186 tmenu
= (struct gtxframe_menu
*)0;
188 /* Handle everything but the command string, which is handled by the
189 * common-case code below */
190 tmenu
= calloc(1, sizeof(*tmenu
));
191 if (tmenu
== (struct gtxframe_menu
*)0)
193 tmenu
->next
= aframe
->menus
;
194 aframe
->menus
= tmenu
;
195 tmenu
->name
= gtx_CopyString(alabel
);
199 * Common case: redo the string labels. Note: at this point, tmenu
200 * points to a valid menu.
202 if (tmenu
->cmdString
)
203 free(tmenu
->cmdString
);
204 tmenu
->cmdString
= gtx_CopyString(astring
);
208 /* Delete a given menu from a frame*/
210 gtxframe_DeleteMenu(struct gtx_frame
*aframe
, char *alabel
)
212 struct gtxframe_menu
*tm
, **lm
;
214 for (lm
= &aframe
->menus
, tm
= *lm
; tm
; lm
= &tm
->next
, tm
= *lm
) {
215 if (strcmp(alabel
, tm
->name
) == 0) {
216 /* found it, remove and return success */
217 *lm
= tm
->next
; /* unthread from list */
224 return (-1); /* failed to find entry to delete */
227 /* Function to remove all known menus */
229 gtxframe_ClearMenus(struct gtx_frame
*aframe
)
232 struct gtxframe_menu
*tm
, *nm
;
234 if (aframe
->menus
!= (struct gtxframe_menu
*)0) {
235 for (tm
= aframe
->menus
; tm
; tm
= nm
) {
243 aframe
->menus
= (struct gtxframe_menu
*)0;
248 gtxframe_AskForString(struct gtx_frame
*aframe
, char *aprompt
,
249 char *adefault
, char *aresult
, int aresultSize
)
254 /* Ensure recursive-edit map is initialized */
258 if (aframe
->promptLine
)
259 free(aframe
->promptLine
);
260 if (aframe
->defaultLine
)
261 free(aframe
->defaultLine
);
262 aframe
->promptLine
= gtx_CopyString(aprompt
);
263 tp
= aframe
->defaultLine
= malloc(1024);
267 strcpy(tp
, adefault
);
271 /* Do recursive edit */
272 gtx_InputServer(aframe
->window
);
273 tp
= aframe
->defaultLine
; /* In case command reallocated it */
275 /* Back from recursive edit, check out what's happened */
276 if (aframe
->flags
& GTXFRAME_RECURSIVEERR
) {
281 if (code
+ 1 > aresultSize
) {
288 /* Fall through to cleanup and return code */
291 if (aframe
->promptLine
)
292 free(aframe
->promptLine
);
293 if (aframe
->defaultLine
)
294 free(aframe
->defaultLine
);
295 aframe
->defaultLine
= aframe
->promptLine
= NULL
;
297 gtxframe_DisplayString(aframe
, "[Aborted]");
302 gtxframe_DisplayString(struct gtx_frame
*aframe
, char *amsgLine
)
304 if (aframe
->messageLine
)
305 free(aframe
->messageLine
);
306 aframe
->messageLine
= gtx_CopyString(amsgLine
);
310 /* Called by input processor to try to clear the dude */
312 gtxframe_ClearMessageLine(struct gtx_frame
*aframe
)
314 /* If we haven't shown message long enough yet, just return */
315 if (aframe
->flags
& GTXFRAME_NEWDISPLAY
)
317 if (aframe
->messageLine
)
318 free(aframe
->messageLine
);
319 aframe
->messageLine
= NULL
;
324 ShowMessageLine(struct gtx_frame
*aframe
)
326 struct gwin_strparams strparms
;
327 struct gwin_sizeparams sizeparms
;
333 /* First, find window size */
334 WOP_GETDIMENSIONS(aframe
->window
, &sizeparms
);
336 if (aframe
->promptLine
) {
337 memset(&strparms
, 0, sizeof(strparms
));
339 strparms
.y
= sizeparms
.maxy
- 1;
340 strparms
.highlight
= 1;
341 tp
= strparms
.s
= malloc(1024);
342 strcpy(tp
, aframe
->promptLine
);
343 strcat(tp
, aframe
->defaultLine
);
344 WOP_DRAWSTRING(aframe
->window
, &strparms
);
345 aframe
->flags
|= GTXFRAME_NEWDISPLAY
;
346 } else if (aframe
->messageLine
) {
347 /* Otherwise we're visible, print the message at the bottom */
348 memset(&strparms
, 0, sizeof(strparms
));
349 strparms
.highlight
= 1;
351 strparms
.y
= sizeparms
.maxy
- 1;
352 strparms
.s
= aframe
->messageLine
;
353 WOP_DRAWSTRING(aframe
->window
, &strparms
);
354 aframe
->flags
|= GTXFRAME_NEWDISPLAY
;
359 /* Exit function, returning whatever has been put in its argument */
361 gtxframe_ExitCmd(void *a_exitValuep
, void *arock
)
362 { /*gtxframe_ExitCmd */
364 int exitval
; /*Value we've been asked to exit with */
366 /* This next call should be type independent! */
367 gator_cursesgwin_cleanup(&gator_basegwin
);
369 exitval
= *((int *)(a_exitValuep
));
372 } /*gtxframe_ExitCmd */
375 gtxframe_Create(void)
377 struct gtx_frame
*tframe
;
378 struct keymap_map
*newkeymap
;
379 struct keymap_state
*newkeystate
;
382 * Allocate all the pieces first: frame, keymap, and key state.
384 tframe
= calloc(1, sizeof(struct gtx_frame
));
385 if (tframe
== (struct gtx_frame
*)0) {
386 return ((struct gtx_frame
*)0);
389 newkeymap
= keymap_Create();
390 if (newkeymap
== (struct keymap_map
*)0) {
392 * Get rid of the frame before exiting.
395 return ((struct gtx_frame
*)0);
398 newkeystate
= malloc(sizeof(struct keymap_state
));
399 if (newkeystate
== (struct keymap_state
*)0) {
401 * Get rid of the frame AND the keymap before exiting.
405 return ((struct gtx_frame
*)0);
409 * Now that all the pieces exist, fill them in and stick them in
412 tframe
->keymap
= newkeymap
;
413 tframe
->keystate
= newkeystate
;
414 keymap_InitState(tframe
->keystate
, tframe
->keymap
);
415 keymap_BindToString(tframe
->keymap
, "\003", gtxframe_ExitCmd
, "ExitCmd",
416 (char *)(>xframe_exitValue
));
419 * At this point, we return successfully.
425 gtxframe_Delete(struct gtx_frame
*aframe
)
427 keymap_Delete(aframe
->keymap
);
428 free(aframe
->keystate
);
429 if (aframe
->messageLine
)
430 free(aframe
->messageLine
);
436 gtxframe_Display(struct gtx_frame
*aframe
, struct gwin
*awm
)
438 struct gtxframe_dlist
*tlist
;
439 struct gtxframe_menu
*tm
;
440 struct gwin_strparams strparms
;
442 /* Run through the menus, displaying them on the top line */
444 for (tm
= aframe
->menus
; tm
; tm
= tm
->next
) {
445 strcat(menubuffer
, tm
->name
);
446 strcat(menubuffer
, ":");
447 strcat(menubuffer
, tm
->cmdString
);
448 strcat(menubuffer
, " ");
450 if (menubuffer
[0] != 0) {
451 memset(&strparms
, 0, sizeof(strparms
));
454 strparms
.s
= menubuffer
;
455 strparms
.highlight
= 1;
456 WOP_DRAWSTRING(awm
, &strparms
);
459 /* Run through the display list, displaying all objects */
460 for (tlist
= aframe
->display
; tlist
; tlist
= tlist
->next
) {
461 OOP_DISPLAY(((struct onode
*)(tlist
->data
)));
464 /* Finally, show the message line */
465 ShowMessageLine(awm
->w_frame
);
469 /* Add an object to a window's display list */
471 gtxframe_AddToList(struct gtx_frame
*aframe
, struct onode
*aobj
)
473 struct gtxframe_dlist
*tlist
;
475 for (tlist
= aframe
->display
; tlist
; tlist
= tlist
->next
) {
476 if (tlist
->data
== (char *)aobj
) {
478 * Don't add the same thing twice.
485 * OK, it's not alreadyt there. Create a new list object, fill it
486 * in, and splice it on.
488 tlist
= malloc(sizeof(struct gtxframe_dlist
));
489 if (tlist
== (struct gtxframe_dlist
*)0)
491 tlist
->data
= (char *)aobj
;
492 tlist
->next
= aframe
->display
;
493 aframe
->display
= tlist
;
497 /* Remove an object from a display list, if it is already there */
499 gtxframe_RemoveFromList(struct gtx_frame
*aframe
, struct onode
*aobj
)
501 struct gtxframe_dlist
*tlist
, **plist
;
503 plist
= &aframe
->display
;
504 for (tlist
= *plist
; tlist
; plist
= &tlist
->next
, tlist
= *plist
) {
505 if (tlist
->data
== (char *)aobj
) {
506 *plist
= tlist
->next
;
511 return (-1); /* Item not found */
514 /* Clear out everything on the display list for the given frame*/
516 gtxframe_ClearList(struct gtx_frame
*aframe
)
518 struct gtxframe_dlist
*tlist
, *nlist
;
520 if (aframe
->display
!= (struct gtxframe_dlist
*)0) {
522 * Throw away each display list structure (we have at least
525 for (tlist
= aframe
->display
; tlist
; tlist
= nlist
) {
531 aframe
->display
= (struct gtxframe_dlist
*)0;