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>
25 #if defined(AFS_HPUX110_ENV) && !defined(__HP_CURSES)
30 #include <curses.h> /*Curses library */
32 #include <sys/types.h>
34 #if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV)
50 #include "gtxcurseswin.h" /*Interface definition */
51 #include "gtxobjects.h"
56 int curses_debug; /*Is debugging turned on? */
57 static char mn[] = "gator_curseswindows"; /*Module name */
60 * Version of standard operations for a curses window.
62 struct gwinops curses_gwinops = {
64 gator_cursesgwin_clear,
65 gator_cursesgwin_destroy,
66 gator_cursesgwin_display,
67 gator_cursesgwin_drawline,
68 gator_cursesgwin_drawrectangle,
69 gator_cursesgwin_drawchar,
70 gator_cursesgwin_drawstring,
71 gator_cursesgwin_invert,
72 gator_cursesgwin_getchar,
73 gator_cursesgwin_getdimensions,
74 gator_cursesgwin_wait,
77 struct gwinbaseops gator_curses_gwinbops = {
78 gator_cursesgwin_create,
79 gator_cursesgwin_cleanup,
84 * Macros to map pixel positions to row & column positions.
85 * (Note: for now, they are the identity function!!)
87 #define GATOR_MAP_X_TO_COL(w, x) (x)
88 #define GATOR_MAP_Y_TO_LINE(w, y) (y)
90 /*------------------------------------------------------------------------
91 * gator_cursesgwin_init
94 * Initialize the curses window package.
97 * int adebug: Is debugging turned on?
101 * Error value otherwise.
104 * Nothing interesting.
108 *------------------------------------------------------------------------*/
111 gator_cursesgwin_init(adebug)
114 { /*gator_cursesgwin_init */
116 static char rn[] = "gator_cursesgwin_init"; /*Routine name */
117 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
120 * Remember if we'll be doing debugging, then init the curses package.
122 curses_debug = adebug;
125 fprintf(stderr, "[%s:%s] Calling initscr()\n", mn, rn);
129 * Fill out the base window structure for curses.
133 "[%s:%s] Allocating %d bytes for curses window private space in base window\n",
134 mn, rn, sizeof(struct gator_cursesgwin));
136 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
137 if (c_data == (struct gator_cursesgwin *)0) {
139 "[%s:%s] Can't allocate %d bytes for curses window private space in base window\n",
140 mn, rn, sizeof(struct gator_cursesgwin));
145 * Fill in the curses-specific base window info. We assume that chars are 8x13.
148 c_data->charwidth = 8;
149 c_data->charheight = 13;
150 c_data->box_vertchar = '|';
151 c_data->box_horizchar = '-';
154 * Fill in the generic base window info.
156 gator_basegwin.w_type = GATOR_WIN_CURSES;
157 gator_basegwin.w_x = 0;
158 gator_basegwin.w_y = 0;
159 gator_basegwin.w_width = c_data->charwidth * COLS;
160 gator_basegwin.w_height = c_data->charheight * LINES;
161 gator_basegwin.w_changed = 0;
162 gator_basegwin.w_op = &curses_gwinops;
163 gator_basegwin.w_parent = NULL;
166 * Plug the private data into the generic part of the base window.
168 gator_basegwin.w_data = (int *)c_data;
171 * Now, set the terminal into the right mode for handling input
173 raw(); /* curses raw mode */
176 gator_basegwin.w_frame = gtxframe_Create();
179 * Clear out the screen and return the good news.
181 wclear(((struct gator_cursesgwin *)(gator_basegwin.w_data))->wp);
184 } /*gator_cursesgwin_init */
186 /*------------------------------------------------------------------------
187 * gator_cursesgwin_create
190 * Create a curses window (incorrectly).
193 * struct gator_cursesgwin_params *params : Ptr to creation parameters.
196 * Ptr to the created curses window if successful,
197 * Null ptr otherwise.
200 * Nothing interesting.
204 *------------------------------------------------------------------------*/
207 gator_cursesgwin_create(params)
208 struct gator_cursesgwin_params *params;
210 { /*gator_cursesgwin_create */
212 static char rn[] = "gator_cursesgwin_create"; /*Routine name */
213 struct gwin *newgwin; /*Ptr to new curses window */
214 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
215 WINDOW *newcursgwin; /*Ptr to new curses window */
219 "[%s:%s] Allocating %d bytes for new gwin structure\n", mn,
220 rn, sizeof(struct gwin));
221 newgwin = (struct gwin *)malloc(sizeof(struct gwin));
222 if (newgwin == NULL) {
224 "[%s:%s] Can't malloc() %d bytes for new gwin structure: Errno is %d\n",
225 mn, rn, sizeof(struct gwin), errno);
229 newgwin->w_type = GATOR_WIN_CURSES;
230 newgwin->w_x = params->gwin_params.cr_x;
231 newgwin->w_y = params->gwin_params.cr_y;
232 newgwin->w_width = params->gwin_params.cr_width;
233 newgwin->w_height = params->gwin_params.cr_height;
234 newgwin->w_changed = 1;
235 newgwin->w_op = &curses_gwinops;
236 newgwin->w_parent = params->gwin_params.cr_parentwin;
240 "[%s:%s] Allocating %d bytes for curses window private space\n",
241 mn, rn, sizeof(struct gator_cursesgwin));
243 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
244 if (c_data == (struct gator_cursesgwin *)0) {
246 "[%s:%s] Can't allocate %d bytes for curses window private space\n",
247 mn, rn, sizeof(struct gator_cursesgwin));
252 newcursgwin = newwin(newgwin->w_height, /*Number of lines */
253 newgwin->w_width, /*Number of columns */
254 newgwin->w_y, /*Beginning y value */
255 newgwin->w_x); /*Beginning x value */
256 if (newcursgwin == (WINDOW *) 0) {
258 "[%s:%s] Failed to create curses window via newwin()\n", mn,
266 * Now, fill in the curses-specific window info.
268 c_data->wp = newcursgwin;
269 c_data->charwidth = params->charwidth;
270 c_data->charheight = params->charheight;
271 c_data->box_vertchar = params->box_vertchar;
272 c_data->box_horizchar = params->box_horizchar;
275 * Plug in a frame at the top-level.
277 newgwin->w_frame = gtxframe_Create();
280 * Plug the curses private data into the generic window object, then
281 * return the new window's info.
283 newgwin->w_data = (int *)c_data;
286 } /*gator_cursesgwin_create */
288 /*------------------------------------------------------------------------
289 * gator_cursesgwin_cleanup
292 * Clean up, probably right before the caller exits.
295 * struct gwin *gwp : Ptr to base window.
299 * Error value otherwise.
302 * Nothing interesting.
306 *------------------------------------------------------------------------*/
309 gator_cursesgwin_cleanup(gwp)
312 { /*gator_cursesgwin_cleanup */
314 static char rn[] = "gator_cursesgwin_cleanup"; /*Routine name */
315 struct gator_cursesgwin *cwp; /*Curses private area ptr */
317 cwp = (struct gator_cursesgwin *)(gwp->w_data);
320 * Cleaning up in curses is extremely easy - one simple call. We also
321 * want to clear the screen before we go.
324 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn,
330 * Now, set the terminal back into normal mode.
335 fprintf(stderr, "[%s:%s] Calling endwin()\n", mn, rn);
340 } /*gator_cursesgwin_cleanup */
342 /*------------------------------------------------------------------------
343 * gator_cursesgwin_box
346 * Draw a box around the given curses window.
349 * struct gwin *gwp : Ptr to the curses window to draw
354 * Error value otherwise.
357 * Nothing interesting.
361 *------------------------------------------------------------------------*/
364 gator_cursesgwin_box(gwp)
367 { /*gator_cursesgwin_box */
369 static char rn[] = "gator_cursesgwin_box"; /*Routine name */
370 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
372 cwp = (struct gator_cursesgwin *)(gwp->w_data);
374 fprintf(stderr, "[%s:%s] Calling box() on window at 0x%x\n", mn, rn,
376 box(cwp->wp, cwp->box_vertchar, cwp->box_horizchar);
380 } /*gator_cursesgwin_box */
382 /*------------------------------------------------------------------------
383 * gator_cursesgwin_clear
386 * Clear out the given curses window.
389 * struct gwin *gwp : Ptr to the curses window to clear out.
393 * Error value otherwise.
396 * Nothing interesting.
400 *------------------------------------------------------------------------*/
403 gator_cursesgwin_clear(gwp)
406 { /*gator_cursesgwin_clear */
408 static char rn[] = "gator_cursesgwin_clear"; /*Routine name */
409 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
412 * Clearing windows is very easy in curses; just one call will do it.
414 cwp = (struct gator_cursesgwin *)(gwp->w_data);
416 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn,
422 } /*gator_cursesgwin_clear */
424 /*------------------------------------------------------------------------
425 * gator_cursesgwin_destroy
428 * Destroy the given curses window.
431 * struct gwin *gwp : Ptr to the curses window to destroy.
435 * Error value otherwise.
438 * Nothing interesting.
442 *------------------------------------------------------------------------*/
445 gator_cursesgwin_destroy(gwp)
448 { /*gator_cursesgwin_destroy */
450 static char rn[] = "gator_cursesgwin_destroy"; /*Routine name */
451 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
453 cwp = (struct gator_cursesgwin *)(gwp->w_data);
455 fprintf(stderr, "[%s:%s] Calling delwin() on window at 0x%x\n", mn,
461 } /*gator_cursesgwin_destroy */
463 /*------------------------------------------------------------------------
464 * gator_cursesgwin_display
467 * Display/redraw the given curses window.
470 * struct gwin *gwp : Ptr to the curses window to draw.
474 * Error value otherwise.
477 * Nothing interesting.
481 *------------------------------------------------------------------------*/
484 gator_cursesgwin_display(gwp)
487 { /*gator_cursesgwin_display */
489 struct gator_cursesgwin *cwp; /*Curses private area ptr */
491 cwp = (struct gator_cursesgwin *)(gwp->w_data);
493 wclear(cwp->wp); /* clear screen */
494 gtxframe_Display(gwp->w_frame, gwp); /* display the frame */
495 wrefresh(cwp->wp); /* redraw the guy */
498 } /*gator_cursesgwin_display */
500 /*------------------------------------------------------------------------
501 * gator_cursesgwin_drawline
504 * Draw a line between two points in the given curses
508 * struct gwin *gwp : Ptr to the curses window in which
509 * the line is to be drawn.
510 * struct gwin_lineparams *params : Ptr to other params.
514 * Error value otherwise.
517 * Nothing interesting.
521 *------------------------------------------------------------------------*/
524 gator_cursesgwin_drawline(gwp, params)
526 struct gwin_lineparams *params;
528 { /*gator_cursesgwin_drawline */
530 static char rn[] = "gator_cursesgwin_drawline"; /*Routine name */
533 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
538 } /*gator_cursesgwin_drawline */
540 /*------------------------------------------------------------------------
541 * gator_cursesgwin_drawrectangle
544 * Draw a rectangle in the given curses window.
547 * struct gwin *gwp : Ptr to the curses window in which
548 * the rectangle is to be drawn.
549 * struct gwin_rectparams *params : Ptr to other params.
553 * Error value otherwise.
556 * Nothing interesting.
560 *------------------------------------------------------------------------*/
563 gator_cursesgwin_drawrectangle(gwp, params)
565 struct gwin_rectparams *params;
567 { /*gator_cursesgwin_drawrectangle */
569 static char rn[] = "gator_cursesgwin_drawrectangle"; /*Routine name */
572 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
577 } /*gator_cursesgwin_drawrectangle */
579 /*------------------------------------------------------------------------
580 * gator_cursesgwin_drawchar
583 * Draw a character in the given curses window.
586 * struct gwin *gwp : Ptr to the curses window in which
587 * the character is to be drawn.
588 * struct gwin_charparams *params : Ptr to other params.
592 * Error value otherwise.
595 * Nothing interesting.
599 *------------------------------------------------------------------------*/
602 gator_cursesgwin_drawchar(gwp, params)
604 struct gwin_charparams *params;
606 { /*gator_cursesgwin_drawchar */
608 static char rn[] = "gator_cursesgwin_drawchar"; /*Routine name */
609 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
610 int curses_x, curses_y; /*Mapped x,y positions */
612 cwp = (struct gator_cursesgwin *)(gwp->w_data);
613 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
614 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
617 "[%s:%s] Drawing char '%c' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n",
618 mn, rn, params->c, cwp->wp, params->x, params->y, curses_y,
619 curses_x, (params->highlight ? ", using standout mode" : ""));
620 wmove(cwp->wp, curses_y, curses_x);
621 if (params->highlight)
623 waddch(cwp->wp, params->c);
624 if (params->highlight)
629 } /*gator_cursesgwin_drawchar */
631 /*------------------------------------------------------------------------
632 * gator_cursesgwin_drawstring
635 * Draw a string in the given curses window.
638 * struct gwin *gwp : Ptr to the curses window in which
639 * the string is to be drawn.
640 * struct gwin_strparams *params : Ptr to other params.
644 * Error value otherwise.
647 * Nothing interesting.
651 *------------------------------------------------------------------------*/
654 gator_cursesgwin_drawstring(gwp, params)
656 struct gwin_strparams *params;
658 { /*gator_cursesgwin_drawstring */
660 static char rn[] = "gator_cursesgwin_drawstring"; /*Routine name */
661 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
662 int curses_x, curses_y; /*Mapped x,y positions */
664 cwp = (struct gator_cursesgwin *)(gwp->w_data);
665 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
666 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
669 "[%s:%s] Drawing string '%s' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n",
670 mn, rn, params->s, cwp->wp, params->x, params->y, curses_y,
671 curses_x, (params->highlight ? ", using standout mode" : ""));
672 wmove(cwp->wp, curses_y, curses_x);
673 if (params->highlight)
675 waddstr(cwp->wp, params->s);
676 if (params->highlight)
681 } /*gator_cursesgwin_drawstring */
683 /*------------------------------------------------------------------------
684 * gator_cursesgwin_invert
687 * Invert a region in the given curses window.
690 * struct gwin *gwp : Ptr to the curses window in which
691 * the inverted region lies.
692 * struct gwin_invparams *params : Ptr to other params.
696 * Error value otherwise.
699 * Nothing interesting.
703 *------------------------------------------------------------------------*/
706 gator_cursesgwin_invert(gwp, params)
708 struct gwin_invparams *params;
710 { /*gator_cursesgwin_invert */
712 static char rn[] = "gator_cursesgwin_invert"; /*Routine name */
715 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
720 } /*gator_cursesgwin_invert */
722 /*------------------------------------------------------------------------
723 * gator_cursesgwin_getchar
726 * Pick up a character from the given window.
729 * struct gwin *gwp : Ptr to the curses window to listen to.
732 * Value of the character read,
736 * Nothing interesting.
740 *------------------------------------------------------------------------*/
743 gator_cursesgwin_getchar(gwp)
746 { /*gator_cursesgwin_getchar */
748 return (getc(stdin));
750 } /*gator_cursesgwin_getchar */
752 /*------------------------------------------------------------------------
753 * gator_cursesgwin_wait
756 * Wait until input is available.
759 * struct gwin *gwp : Ptr to the curses window to wait on.
763 * Error value otherwise.
766 * Nothing interesting.
770 *------------------------------------------------------------------------*/
773 gator_cursesgwin_wait(gwp)
776 { /*gator_cursesgwin_wait */
778 while (!LWP_WaitForKeystroke(-1));
782 } /*gator_cursesgwin_wait */
784 /*------------------------------------------------------------------------
785 * gator_cursesgwin_getdimensions
788 * Get the window's X,Y dimensions.
791 * struct gwin *gwp : Ptr to the curses window to examine.
792 * struct gwin_sizeparams *params : Ptr to the size params to set.
796 * Error value otherwise.
799 * Nothing interesting.
803 *------------------------------------------------------------------------*/
806 gator_cursesgwin_getdimensions(gwp, aparms)
807 struct gwin_sizeparams *aparms;
810 { /*gator_cursesgwin_getdimensions */
812 struct gator_cursesgwin *cwp; /*Curses-specific data */
814 cwp = (struct gator_cursesgwin *)(gwp->w_data);
815 #if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN60_ENV)
816 aparms->maxx = cwp->wp->maxx;
817 aparms->maxy = cwp->wp->maxy;
818 #elif defined(AFS_NBSD_ENV)
819 aparms->maxx = getmaxx(cwp->wp);
820 aparms->maxy = getmaxy(cwp->wp);
822 aparms->maxx = cwp->wp->_maxx;
823 aparms->maxy = cwp->wp->_maxy;
828 } /*gator_cursesgwin_getdimensions */