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 * gator_curseswindows.c
14 * Implementation of the gator curses window facility.
16 *------------------------------------------------------------------------*/
18 #include <afsconfig.h>
19 #include <afs/param.h>
23 #include <sys/types.h>
25 #if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_FBSD80_ENV)
36 #include "gtxcurseswin.h" /*Interface definition */
37 #include "gtxobjects.h"
42 int curses_debug; /*Is debugging turned on? */
43 static char mn[] = "gator_curseswindows"; /*Module name */
46 * Version of standard operations for a curses window.
48 struct gwinops curses_gwinops = {
50 gator_cursesgwin_clear,
51 gator_cursesgwin_destroy,
52 gator_cursesgwin_display,
53 gator_cursesgwin_drawline,
54 gator_cursesgwin_drawrectangle,
55 gator_cursesgwin_drawchar,
56 gator_cursesgwin_drawstring,
57 gator_cursesgwin_invert,
58 gator_cursesgwin_getchar,
59 gator_cursesgwin_getdimensions,
60 gator_cursesgwin_wait,
63 struct gwinbaseops gator_curses_gwinbops = {
64 gator_cursesgwin_create,
65 gator_cursesgwin_cleanup,
70 * Macros to map pixel positions to row & column positions.
71 * (Note: for now, they are the identity function!!)
73 #define GATOR_MAP_X_TO_COL(w, x) (x)
74 #define GATOR_MAP_Y_TO_LINE(w, y) (y)
76 /*------------------------------------------------------------------------
77 * gator_cursesgwin_init
80 * Initialize the curses window package.
83 * int adebug: Is debugging turned on?
87 * Error value otherwise.
90 * Nothing interesting.
94 *------------------------------------------------------------------------*/
97 gator_cursesgwin_init(int adebug)
98 { /*gator_cursesgwin_init */
100 static char rn[] = "gator_cursesgwin_init"; /*Routine name */
101 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
104 * Remember if we'll be doing debugging, then init the curses package.
106 curses_debug = adebug;
109 fprintf(stderr, "[%s:%s] Calling initscr()\n", mn, rn);
113 * Fill out the base window structure for curses.
117 "[%s:%s] Allocating %" AFS_SIZET_FMT " bytes for curses window private space in base window\n",
118 mn, rn, sizeof(struct gator_cursesgwin));
120 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
121 if (c_data == (struct gator_cursesgwin *)0) {
123 "[%s:%s] Can't allocate %" AFS_SIZET_FMT " bytes for curses window private space in base window\n",
124 mn, rn, sizeof(struct gator_cursesgwin));
129 * Fill in the curses-specific base window info. We assume that chars are 8x13.
132 c_data->charwidth = 8;
133 c_data->charheight = 13;
134 c_data->box_vertchar = '|';
135 c_data->box_horizchar = '-';
138 * Fill in the generic base window info.
140 gator_basegwin.w_type = GATOR_WIN_CURSES;
141 gator_basegwin.w_x = 0;
142 gator_basegwin.w_y = 0;
143 gator_basegwin.w_width = c_data->charwidth * COLS;
144 gator_basegwin.w_height = c_data->charheight * LINES;
145 gator_basegwin.w_changed = 0;
146 gator_basegwin.w_op = &curses_gwinops;
147 gator_basegwin.w_parent = NULL;
150 * Plug the private data into the generic part of the base window.
152 gator_basegwin.w_data = (int *)c_data;
155 * Now, set the terminal into the right mode for handling input
157 raw(); /* curses raw mode */
160 gator_basegwin.w_frame = gtxframe_Create();
163 * Clear out the screen and return the good news.
165 wclear(((struct gator_cursesgwin *)(gator_basegwin.w_data))->wp);
168 } /*gator_cursesgwin_init */
170 /*------------------------------------------------------------------------
171 * gator_cursesgwin_create
174 * Create a curses window (incorrectly).
177 * struct gator_cursesgwin_params *params : Ptr to creation parameters.
180 * Ptr to the created curses window if successful,
181 * Null ptr otherwise.
184 * Nothing interesting.
188 *------------------------------------------------------------------------*/
191 gator_cursesgwin_create(void * rock)
193 static char rn[] = "gator_cursesgwin_create"; /*Routine name */
194 struct gator_cursesgwin_params *params = (struct gator_cursesgwin_params *)rock;
195 struct gwin *newgwin; /*Ptr to new curses window */
196 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
197 WINDOW *newcursgwin; /*Ptr to new curses window */
201 "[%s:%s] Allocating %" AFS_SIZET_FMT " bytes for new gwin structure\n", mn,
202 rn, sizeof(struct gwin));
203 newgwin = (struct gwin *)malloc(sizeof(struct gwin));
204 if (newgwin == NULL) {
206 "[%s:%s] Can't malloc() %" AFS_SIZET_FMT " bytes for new gwin structure: Errno is %d\n",
207 mn, rn, sizeof(struct gwin), errno);
211 newgwin->w_type = GATOR_WIN_CURSES;
212 newgwin->w_x = params->gwin_params.cr_x;
213 newgwin->w_y = params->gwin_params.cr_y;
214 newgwin->w_width = params->gwin_params.cr_width;
215 newgwin->w_height = params->gwin_params.cr_height;
216 newgwin->w_changed = 1;
217 newgwin->w_op = &curses_gwinops;
218 newgwin->w_parent = params->gwin_params.cr_parentwin;
222 "[%s:%s] Allocating %" AFS_SIZET_FMT " bytes for curses window private space\n",
223 mn, rn, sizeof(struct gator_cursesgwin));
225 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
226 if (c_data == (struct gator_cursesgwin *)0) {
228 "[%s:%s] Can't allocate %" AFS_SIZET_FMT " bytes for curses window private space\n",
229 mn, rn, sizeof(struct gator_cursesgwin));
234 newcursgwin = newwin(newgwin->w_height, /*Number of lines */
235 newgwin->w_width, /*Number of columns */
236 newgwin->w_y, /*Beginning y value */
237 newgwin->w_x); /*Beginning x value */
238 if (newcursgwin == (WINDOW *) 0) {
240 "[%s:%s] Failed to create curses window via newwin()\n", mn,
248 * Now, fill in the curses-specific window info.
250 c_data->wp = newcursgwin;
251 c_data->charwidth = params->charwidth;
252 c_data->charheight = params->charheight;
253 c_data->box_vertchar = params->box_vertchar;
254 c_data->box_horizchar = params->box_horizchar;
257 * Plug in a frame at the top-level.
259 newgwin->w_frame = gtxframe_Create();
262 * Plug the curses private data into the generic window object, then
263 * return the new window's info.
265 newgwin->w_data = (int *)c_data;
268 } /*gator_cursesgwin_create */
270 /*------------------------------------------------------------------------
271 * gator_cursesgwin_cleanup
274 * Clean up, probably right before the caller exits.
277 * struct gwin *gwp : Ptr to base window.
281 * Error value otherwise.
284 * Nothing interesting.
288 *------------------------------------------------------------------------*/
291 gator_cursesgwin_cleanup(struct gwin *gwp)
292 { /*gator_cursesgwin_cleanup */
294 static char rn[] = "gator_cursesgwin_cleanup"; /*Routine name */
295 struct gator_cursesgwin *cwp; /*Curses private area ptr */
297 cwp = (struct gator_cursesgwin *)(gwp->w_data);
300 * Cleaning up in curses is extremely easy - one simple call. We also
301 * want to clear the screen before we go.
304 fprintf(stderr, "[%s:%s] Calling wclear() on window at %p\n", mn,
310 * Now, set the terminal back into normal mode.
315 fprintf(stderr, "[%s:%s] Calling endwin()\n", mn, rn);
320 } /*gator_cursesgwin_cleanup */
322 /*------------------------------------------------------------------------
323 * gator_cursesgwin_box
326 * Draw a box around the given curses window.
329 * struct gwin *gwp : Ptr to the curses window to draw
334 * Error value otherwise.
337 * Nothing interesting.
341 *------------------------------------------------------------------------*/
344 gator_cursesgwin_box(struct gwin *gwp)
345 { /*gator_cursesgwin_box */
347 static char rn[] = "gator_cursesgwin_box"; /*Routine name */
348 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
350 cwp = (struct gator_cursesgwin *)(gwp->w_data);
352 fprintf(stderr, "[%s:%s] Calling box() on window at %p\n", mn, rn,
354 box(cwp->wp, cwp->box_vertchar, cwp->box_horizchar);
358 } /*gator_cursesgwin_box */
360 /*------------------------------------------------------------------------
361 * gator_cursesgwin_clear
364 * Clear out the given curses window.
367 * struct gwin *gwp : Ptr to the curses window to clear out.
371 * Error value otherwise.
374 * Nothing interesting.
378 *------------------------------------------------------------------------*/
381 gator_cursesgwin_clear(struct gwin *gwp)
382 { /*gator_cursesgwin_clear */
384 static char rn[] = "gator_cursesgwin_clear"; /*Routine name */
385 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
388 * Clearing windows is very easy in curses; just one call will do it.
390 cwp = (struct gator_cursesgwin *)(gwp->w_data);
392 fprintf(stderr, "[%s:%s] Calling wclear() on window at %p\n", mn,
398 } /*gator_cursesgwin_clear */
400 /*------------------------------------------------------------------------
401 * gator_cursesgwin_destroy
404 * Destroy the given curses window.
407 * struct gwin *gwp : Ptr to the curses window to destroy.
411 * Error value otherwise.
414 * Nothing interesting.
418 *------------------------------------------------------------------------*/
421 gator_cursesgwin_destroy(struct gwin *gwp)
422 { /*gator_cursesgwin_destroy */
424 static char rn[] = "gator_cursesgwin_destroy"; /*Routine name */
425 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
427 cwp = (struct gator_cursesgwin *)(gwp->w_data);
429 fprintf(stderr, "[%s:%s] Calling delwin() on window at %p\n", mn,
435 } /*gator_cursesgwin_destroy */
437 /*------------------------------------------------------------------------
438 * gator_cursesgwin_display
441 * Display/redraw the given curses window.
444 * struct gwin *gwp : Ptr to the curses window to draw.
448 * Error value otherwise.
451 * Nothing interesting.
455 *------------------------------------------------------------------------*/
458 gator_cursesgwin_display(struct gwin *gwp)
459 { /*gator_cursesgwin_display */
461 struct gator_cursesgwin *cwp; /*Curses private area ptr */
463 cwp = (struct gator_cursesgwin *)(gwp->w_data);
465 wclear(cwp->wp); /* clear screen */
466 gtxframe_Display(gwp->w_frame, gwp); /* display the frame */
467 wrefresh(cwp->wp); /* redraw the guy */
470 } /*gator_cursesgwin_display */
472 /*------------------------------------------------------------------------
473 * gator_cursesgwin_drawline
476 * Draw a line between two points in the given curses
480 * struct gwin *gwp : Ptr to the curses window in which
481 * the line is to be drawn.
482 * struct gwin_lineparams *params : Ptr to other params.
486 * Error value otherwise.
489 * Nothing interesting.
493 *------------------------------------------------------------------------*/
496 gator_cursesgwin_drawline(struct gwin *gwp, struct gwin_lineparams *params)
497 { /*gator_cursesgwin_drawline */
499 static char rn[] = "gator_cursesgwin_drawline"; /*Routine name */
502 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
507 } /*gator_cursesgwin_drawline */
509 /*------------------------------------------------------------------------
510 * gator_cursesgwin_drawrectangle
513 * Draw a rectangle in the given curses window.
516 * struct gwin *gwp : Ptr to the curses window in which
517 * the rectangle is to be drawn.
518 * struct gwin_rectparams *params : Ptr to other params.
522 * Error value otherwise.
525 * Nothing interesting.
529 *------------------------------------------------------------------------*/
532 gator_cursesgwin_drawrectangle(struct gwin *gwp, struct gwin_rectparams *params)
533 { /*gator_cursesgwin_drawrectangle */
535 static char rn[] = "gator_cursesgwin_drawrectangle"; /*Routine name */
538 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
543 } /*gator_cursesgwin_drawrectangle */
545 /*------------------------------------------------------------------------
546 * gator_cursesgwin_drawchar
549 * Draw a character in the given curses window.
552 * struct gwin *gwp : Ptr to the curses window in which
553 * the character is to be drawn.
554 * struct gwin_charparams *params : Ptr to other params.
558 * Error value otherwise.
561 * Nothing interesting.
565 *------------------------------------------------------------------------*/
568 gator_cursesgwin_drawchar(struct gwin *gwp, struct gwin_charparams *params)
569 { /*gator_cursesgwin_drawchar */
571 static char rn[] = "gator_cursesgwin_drawchar"; /*Routine name */
572 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
573 int curses_x, curses_y; /*Mapped x,y positions */
576 cwp = (struct gator_cursesgwin *)(gwp->w_data);
577 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
578 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
581 "[%s:%s] Drawing char '%c' on window at %p at (%d, %d) [line %d, column %d]%s\n",
582 mn, rn, params->c, cwp->wp, params->x, params->y, curses_y,
583 curses_x, (params->highlight ? ", using standout mode" : ""));
584 wmove(cwp->wp, curses_y, curses_x);
585 if (params->highlight)
586 code=wstandout(cwp->wp);
589 waddch(cwp->wp, params->c);
590 if (params->highlight)
591 code=wstandend(cwp->wp);
597 } /*gator_cursesgwin_drawchar */
599 /*------------------------------------------------------------------------
600 * gator_cursesgwin_drawstring
603 * Draw a string in the given curses window.
606 * struct gwin *gwp : Ptr to the curses window in which
607 * the string is to be drawn.
608 * struct gwin_strparams *params : Ptr to other params.
612 * Error value otherwise.
615 * Nothing interesting.
619 *------------------------------------------------------------------------*/
622 gator_cursesgwin_drawstring(struct gwin *gwp, struct gwin_strparams *params)
623 { /*gator_cursesgwin_drawstring */
625 static char rn[] = "gator_cursesgwin_drawstring"; /*Routine name */
626 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
627 int curses_x, curses_y; /*Mapped x,y positions */
630 cwp = (struct gator_cursesgwin *)(gwp->w_data);
631 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
632 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
635 "[%s:%s] Drawing string '%s' on window at %p at (%d, %d) [line %d, column %d]%s\n",
636 mn, rn, params->s, cwp->wp, params->x, params->y, curses_y,
637 curses_x, (params->highlight ? ", using standout mode" : ""));
638 wmove(cwp->wp, curses_y, curses_x);
639 if (params->highlight)
640 code=wstandout(cwp->wp);
643 waddstr(cwp->wp, params->s);
644 if (params->highlight)
645 code=wstandend(cwp->wp);
651 } /*gator_cursesgwin_drawstring */
653 /*------------------------------------------------------------------------
654 * gator_cursesgwin_invert
657 * Invert a region in the given curses window.
660 * struct gwin *gwp : Ptr to the curses window in which
661 * the inverted region lies.
662 * struct gwin_invparams *params : Ptr to other params.
666 * Error value otherwise.
669 * Nothing interesting.
673 *------------------------------------------------------------------------*/
676 gator_cursesgwin_invert(struct gwin *gwp, struct gwin_invparams *params)
677 { /*gator_cursesgwin_invert */
679 static char rn[] = "gator_cursesgwin_invert"; /*Routine name */
682 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
687 } /*gator_cursesgwin_invert */
689 /*------------------------------------------------------------------------
690 * gator_cursesgwin_getchar
693 * Pick up a character from the given window.
696 * struct gwin *gwp : Ptr to the curses window to listen to.
699 * Value of the character read,
703 * Nothing interesting.
707 *------------------------------------------------------------------------*/
710 gator_cursesgwin_getchar(struct gwin *gwp)
711 { /*gator_cursesgwin_getchar */
713 return (getc(stdin));
715 } /*gator_cursesgwin_getchar */
717 /*------------------------------------------------------------------------
718 * gator_cursesgwin_wait
721 * Wait until input is available.
724 * struct gwin *gwp : Ptr to the curses window to wait on.
728 * Error value otherwise.
731 * Nothing interesting.
735 *------------------------------------------------------------------------*/
738 gator_cursesgwin_wait(struct gwin *gwp)
739 { /*gator_cursesgwin_wait */
741 while (!LWP_WaitForKeystroke(-1));
745 } /*gator_cursesgwin_wait */
747 /*------------------------------------------------------------------------
748 * gator_cursesgwin_getdimensions
751 * Get the window's X,Y dimensions.
754 * struct gwin *gwp : Ptr to the curses window to examine.
755 * struct gwin_sizeparams *params : Ptr to the size params to set.
759 * Error value otherwise.
762 * Nothing interesting.
766 *------------------------------------------------------------------------*/
769 gator_cursesgwin_getdimensions(struct gwin *gwp, struct gwin_sizeparams *aparms)
770 { /*gator_cursesgwin_getdimensions */
772 struct gator_cursesgwin *cwp; /*Curses-specific data */
774 cwp = (struct gator_cursesgwin *)(gwp->w_data);
775 #if defined(AFS_NBSD_ENV) || defined(AFS_DARWIN100_ENV)
776 aparms->maxx = getmaxx(cwp->wp);
777 aparms->maxy = getmaxy(cwp->wp);
779 aparms->maxx = cwp->wp->_maxx;
780 aparms->maxy = cwp->wp->_maxy;
785 } /*gator_cursesgwin_getdimensions */