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)
43 #include "gtxcurseswin.h" /*Interface definition */
44 #include "gtxobjects.h"
49 int curses_debug; /*Is debugging turned on? */
50 static char mn[] = "gator_curseswindows"; /*Module name */
53 * Version of standard operations for a curses window.
55 struct gwinops curses_gwinops = {
57 gator_cursesgwin_clear,
58 gator_cursesgwin_destroy,
59 gator_cursesgwin_display,
60 gator_cursesgwin_drawline,
61 gator_cursesgwin_drawrectangle,
62 gator_cursesgwin_drawchar,
63 gator_cursesgwin_drawstring,
64 gator_cursesgwin_invert,
65 gator_cursesgwin_getchar,
66 gator_cursesgwin_getdimensions,
67 gator_cursesgwin_wait,
70 struct gwinbaseops gator_curses_gwinbops = {
71 gator_cursesgwin_create,
72 gator_cursesgwin_cleanup,
77 * Macros to map pixel positions to row & column positions.
78 * (Note: for now, they are the identity function!!)
80 #define GATOR_MAP_X_TO_COL(w, x) (x)
81 #define GATOR_MAP_Y_TO_LINE(w, y) (y)
83 /*------------------------------------------------------------------------
84 * gator_cursesgwin_init
87 * Initialize the curses window package.
90 * int adebug: Is debugging turned on?
94 * Error value otherwise.
97 * Nothing interesting.
101 *------------------------------------------------------------------------*/
104 gator_cursesgwin_init(adebug)
107 { /*gator_cursesgwin_init */
109 static char rn[] = "gator_cursesgwin_init"; /*Routine name */
110 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
113 * Remember if we'll be doing debugging, then init the curses package.
115 curses_debug = adebug;
118 fprintf(stderr, "[%s:%s] Calling initscr()\n", mn, rn);
122 * Fill out the base window structure for curses.
126 "[%s:%s] Allocating %d bytes for curses window private space in base window\n",
127 mn, rn, sizeof(struct gator_cursesgwin));
129 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
130 if (c_data == (struct gator_cursesgwin *)0) {
132 "[%s:%s] Can't allocate %d bytes for curses window private space in base window\n",
133 mn, rn, sizeof(struct gator_cursesgwin));
138 * Fill in the curses-specific base window info. We assume that chars are 8x13.
141 c_data->charwidth = 8;
142 c_data->charheight = 13;
143 c_data->box_vertchar = '|';
144 c_data->box_horizchar = '-';
147 * Fill in the generic base window info.
149 gator_basegwin.w_type = GATOR_WIN_CURSES;
150 gator_basegwin.w_x = 0;
151 gator_basegwin.w_y = 0;
152 gator_basegwin.w_width = c_data->charwidth * COLS;
153 gator_basegwin.w_height = c_data->charheight * LINES;
154 gator_basegwin.w_changed = 0;
155 gator_basegwin.w_op = &curses_gwinops;
156 gator_basegwin.w_parent = NULL;
159 * Plug the private data into the generic part of the base window.
161 gator_basegwin.w_data = (int *)c_data;
164 * Now, set the terminal into the right mode for handling input
166 raw(); /* curses raw mode */
169 gator_basegwin.w_frame = gtxframe_Create();
172 * Clear out the screen and return the good news.
174 wclear(((struct gator_cursesgwin *)(gator_basegwin.w_data))->wp);
177 } /*gator_cursesgwin_init */
179 /*------------------------------------------------------------------------
180 * gator_cursesgwin_create
183 * Create a curses window (incorrectly).
186 * struct gator_cursesgwin_params *params : Ptr to creation parameters.
189 * Ptr to the created curses window if successful,
190 * Null ptr otherwise.
193 * Nothing interesting.
197 *------------------------------------------------------------------------*/
200 gator_cursesgwin_create(params)
201 struct gator_cursesgwin_params *params;
203 { /*gator_cursesgwin_create */
205 static char rn[] = "gator_cursesgwin_create"; /*Routine name */
206 struct gwin *newgwin; /*Ptr to new curses window */
207 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
208 WINDOW *newcursgwin; /*Ptr to new curses window */
212 "[%s:%s] Allocating %d bytes for new gwin structure\n", mn,
213 rn, sizeof(struct gwin));
214 newgwin = (struct gwin *)malloc(sizeof(struct gwin));
215 if (newgwin == NULL) {
217 "[%s:%s] Can't malloc() %d bytes for new gwin structure: Errno is %d\n",
218 mn, rn, sizeof(struct gwin), errno);
222 newgwin->w_type = GATOR_WIN_CURSES;
223 newgwin->w_x = params->gwin_params.cr_x;
224 newgwin->w_y = params->gwin_params.cr_y;
225 newgwin->w_width = params->gwin_params.cr_width;
226 newgwin->w_height = params->gwin_params.cr_height;
227 newgwin->w_changed = 1;
228 newgwin->w_op = &curses_gwinops;
229 newgwin->w_parent = params->gwin_params.cr_parentwin;
233 "[%s:%s] Allocating %d bytes for curses window private space\n",
234 mn, rn, sizeof(struct gator_cursesgwin));
236 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
237 if (c_data == (struct gator_cursesgwin *)0) {
239 "[%s:%s] Can't allocate %d bytes for curses window private space\n",
240 mn, rn, sizeof(struct gator_cursesgwin));
245 newcursgwin = newwin(newgwin->w_height, /*Number of lines */
246 newgwin->w_width, /*Number of columns */
247 newgwin->w_y, /*Beginning y value */
248 newgwin->w_x); /*Beginning x value */
249 if (newcursgwin == (WINDOW *) 0) {
251 "[%s:%s] Failed to create curses window via newwin()\n", mn,
259 * Now, fill in the curses-specific window info.
261 c_data->wp = newcursgwin;
262 c_data->charwidth = params->charwidth;
263 c_data->charheight = params->charheight;
264 c_data->box_vertchar = params->box_vertchar;
265 c_data->box_horizchar = params->box_horizchar;
268 * Plug in a frame at the top-level.
270 newgwin->w_frame = gtxframe_Create();
273 * Plug the curses private data into the generic window object, then
274 * return the new window's info.
276 newgwin->w_data = (int *)c_data;
279 } /*gator_cursesgwin_create */
281 /*------------------------------------------------------------------------
282 * gator_cursesgwin_cleanup
285 * Clean up, probably right before the caller exits.
288 * struct gwin *gwp : Ptr to base window.
292 * Error value otherwise.
295 * Nothing interesting.
299 *------------------------------------------------------------------------*/
302 gator_cursesgwin_cleanup(gwp)
305 { /*gator_cursesgwin_cleanup */
307 static char rn[] = "gator_cursesgwin_cleanup"; /*Routine name */
308 struct gator_cursesgwin *cwp; /*Curses private area ptr */
310 cwp = (struct gator_cursesgwin *)(gwp->w_data);
313 * Cleaning up in curses is extremely easy - one simple call. We also
314 * want to clear the screen before we go.
317 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn,
323 * Now, set the terminal back into normal mode.
328 fprintf(stderr, "[%s:%s] Calling endwin()\n", mn, rn);
333 } /*gator_cursesgwin_cleanup */
335 /*------------------------------------------------------------------------
336 * gator_cursesgwin_box
339 * Draw a box around the given curses window.
342 * struct gwin *gwp : Ptr to the curses window to draw
347 * Error value otherwise.
350 * Nothing interesting.
354 *------------------------------------------------------------------------*/
357 gator_cursesgwin_box(gwp)
360 { /*gator_cursesgwin_box */
362 static char rn[] = "gator_cursesgwin_box"; /*Routine name */
363 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
365 cwp = (struct gator_cursesgwin *)(gwp->w_data);
367 fprintf(stderr, "[%s:%s] Calling box() on window at 0x%x\n", mn, rn,
369 box(cwp->wp, cwp->box_vertchar, cwp->box_horizchar);
373 } /*gator_cursesgwin_box */
375 /*------------------------------------------------------------------------
376 * gator_cursesgwin_clear
379 * Clear out the given curses window.
382 * struct gwin *gwp : Ptr to the curses window to clear out.
386 * Error value otherwise.
389 * Nothing interesting.
393 *------------------------------------------------------------------------*/
396 gator_cursesgwin_clear(gwp)
399 { /*gator_cursesgwin_clear */
401 static char rn[] = "gator_cursesgwin_clear"; /*Routine name */
402 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
405 * Clearing windows is very easy in curses; just one call will do it.
407 cwp = (struct gator_cursesgwin *)(gwp->w_data);
409 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn,
415 } /*gator_cursesgwin_clear */
417 /*------------------------------------------------------------------------
418 * gator_cursesgwin_destroy
421 * Destroy the given curses window.
424 * struct gwin *gwp : Ptr to the curses window to destroy.
428 * Error value otherwise.
431 * Nothing interesting.
435 *------------------------------------------------------------------------*/
438 gator_cursesgwin_destroy(gwp)
441 { /*gator_cursesgwin_destroy */
443 static char rn[] = "gator_cursesgwin_destroy"; /*Routine name */
444 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
446 cwp = (struct gator_cursesgwin *)(gwp->w_data);
448 fprintf(stderr, "[%s:%s] Calling delwin() on window at 0x%x\n", mn,
454 } /*gator_cursesgwin_destroy */
456 /*------------------------------------------------------------------------
457 * gator_cursesgwin_display
460 * Display/redraw the given curses window.
463 * struct gwin *gwp : Ptr to the curses window to draw.
467 * Error value otherwise.
470 * Nothing interesting.
474 *------------------------------------------------------------------------*/
477 gator_cursesgwin_display(gwp)
480 { /*gator_cursesgwin_display */
482 struct gator_cursesgwin *cwp; /*Curses private area ptr */
484 cwp = (struct gator_cursesgwin *)(gwp->w_data);
486 wclear(cwp->wp); /* clear screen */
487 gtxframe_Display(gwp->w_frame, gwp); /* display the frame */
488 wrefresh(cwp->wp); /* redraw the guy */
491 } /*gator_cursesgwin_display */
493 /*------------------------------------------------------------------------
494 * gator_cursesgwin_drawline
497 * Draw a line between two points in the given curses
501 * struct gwin *gwp : Ptr to the curses window in which
502 * the line is to be drawn.
503 * struct gwin_lineparams *params : Ptr to other params.
507 * Error value otherwise.
510 * Nothing interesting.
514 *------------------------------------------------------------------------*/
517 gator_cursesgwin_drawline(gwp, params)
519 struct gwin_lineparams *params;
521 { /*gator_cursesgwin_drawline */
523 static char rn[] = "gator_cursesgwin_drawline"; /*Routine name */
526 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
531 } /*gator_cursesgwin_drawline */
533 /*------------------------------------------------------------------------
534 * gator_cursesgwin_drawrectangle
537 * Draw a rectangle in the given curses window.
540 * struct gwin *gwp : Ptr to the curses window in which
541 * the rectangle is to be drawn.
542 * struct gwin_rectparams *params : Ptr to other params.
546 * Error value otherwise.
549 * Nothing interesting.
553 *------------------------------------------------------------------------*/
556 gator_cursesgwin_drawrectangle(gwp, params)
558 struct gwin_rectparams *params;
560 { /*gator_cursesgwin_drawrectangle */
562 static char rn[] = "gator_cursesgwin_drawrectangle"; /*Routine name */
565 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
570 } /*gator_cursesgwin_drawrectangle */
572 /*------------------------------------------------------------------------
573 * gator_cursesgwin_drawchar
576 * Draw a character in the given curses window.
579 * struct gwin *gwp : Ptr to the curses window in which
580 * the character is to be drawn.
581 * struct gwin_charparams *params : Ptr to other params.
585 * Error value otherwise.
588 * Nothing interesting.
592 *------------------------------------------------------------------------*/
595 gator_cursesgwin_drawchar(gwp, params)
597 struct gwin_charparams *params;
599 { /*gator_cursesgwin_drawchar */
601 static char rn[] = "gator_cursesgwin_drawchar"; /*Routine name */
602 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
603 int curses_x, curses_y; /*Mapped x,y positions */
605 cwp = (struct gator_cursesgwin *)(gwp->w_data);
606 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
607 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
610 "[%s:%s] Drawing char '%c' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n",
611 mn, rn, params->c, cwp->wp, params->x, params->y, curses_y,
612 curses_x, (params->highlight ? ", using standout mode" : ""));
613 wmove(cwp->wp, curses_y, curses_x);
614 if (params->highlight)
616 waddch(cwp->wp, params->c);
617 if (params->highlight)
622 } /*gator_cursesgwin_drawchar */
624 /*------------------------------------------------------------------------
625 * gator_cursesgwin_drawstring
628 * Draw a string in the given curses window.
631 * struct gwin *gwp : Ptr to the curses window in which
632 * the string is to be drawn.
633 * struct gwin_strparams *params : Ptr to other params.
637 * Error value otherwise.
640 * Nothing interesting.
644 *------------------------------------------------------------------------*/
647 gator_cursesgwin_drawstring(gwp, params)
649 struct gwin_strparams *params;
651 { /*gator_cursesgwin_drawstring */
653 static char rn[] = "gator_cursesgwin_drawstring"; /*Routine name */
654 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
655 int curses_x, curses_y; /*Mapped x,y positions */
657 cwp = (struct gator_cursesgwin *)(gwp->w_data);
658 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
659 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
662 "[%s:%s] Drawing string '%s' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n",
663 mn, rn, params->s, cwp->wp, params->x, params->y, curses_y,
664 curses_x, (params->highlight ? ", using standout mode" : ""));
665 wmove(cwp->wp, curses_y, curses_x);
666 if (params->highlight)
668 waddstr(cwp->wp, params->s);
669 if (params->highlight)
674 } /*gator_cursesgwin_drawstring */
676 /*------------------------------------------------------------------------
677 * gator_cursesgwin_invert
680 * Invert a region in the given curses window.
683 * struct gwin *gwp : Ptr to the curses window in which
684 * the inverted region lies.
685 * struct gwin_invparams *params : Ptr to other params.
689 * Error value otherwise.
692 * Nothing interesting.
696 *------------------------------------------------------------------------*/
699 gator_cursesgwin_invert(gwp, params)
701 struct gwin_invparams *params;
703 { /*gator_cursesgwin_invert */
705 static char rn[] = "gator_cursesgwin_invert"; /*Routine name */
708 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
713 } /*gator_cursesgwin_invert */
715 /*------------------------------------------------------------------------
716 * gator_cursesgwin_getchar
719 * Pick up a character from the given window.
722 * struct gwin *gwp : Ptr to the curses window to listen to.
725 * Value of the character read,
729 * Nothing interesting.
733 *------------------------------------------------------------------------*/
736 gator_cursesgwin_getchar(gwp)
739 { /*gator_cursesgwin_getchar */
741 return (getc(stdin));
743 } /*gator_cursesgwin_getchar */
745 /*------------------------------------------------------------------------
746 * gator_cursesgwin_wait
749 * Wait until input is available.
752 * struct gwin *gwp : Ptr to the curses window to wait on.
756 * Error value otherwise.
759 * Nothing interesting.
763 *------------------------------------------------------------------------*/
766 gator_cursesgwin_wait(gwp)
769 { /*gator_cursesgwin_wait */
771 while (!LWP_WaitForKeystroke(-1));
775 } /*gator_cursesgwin_wait */
777 /*------------------------------------------------------------------------
778 * gator_cursesgwin_getdimensions
781 * Get the window's X,Y dimensions.
784 * struct gwin *gwp : Ptr to the curses window to examine.
785 * struct gwin_sizeparams *params : Ptr to the size params to set.
789 * Error value otherwise.
792 * Nothing interesting.
796 *------------------------------------------------------------------------*/
799 gator_cursesgwin_getdimensions(gwp, aparms)
800 struct gwin_sizeparams *aparms;
803 { /*gator_cursesgwin_getdimensions */
805 struct gator_cursesgwin *cwp; /*Curses-specific data */
807 cwp = (struct gator_cursesgwin *)(gwp->w_data);
808 #if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN60_ENV)
809 aparms->maxx = cwp->wp->maxx;
810 aparms->maxy = cwp->wp->maxy;
811 #elif defined(AFS_NBSD_ENV)
812 aparms->maxx = getmaxx(cwp->wp);
813 aparms->maxy = getmaxy(cwp->wp);
815 aparms->maxx = cwp->wp->_maxx;
816 aparms->maxy = cwp->wp->_maxy;
821 } /*gator_cursesgwin_getdimensions */