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 #if defined(AFS_HPUX110_ENV) && !defined(__HP_CURSES)
28 #include <curses.h> /*Curses library */
30 #include <sys/types.h>
32 #if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_FBSD80_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(int adebug)
105 { /*gator_cursesgwin_init */
107 static char rn[] = "gator_cursesgwin_init"; /*Routine name */
108 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
111 * Remember if we'll be doing debugging, then init the curses package.
113 curses_debug = adebug;
116 fprintf(stderr, "[%s:%s] Calling initscr()\n", mn, rn);
120 * Fill out the base window structure for curses.
124 "[%s:%s] Allocating %" AFS_SIZET_FMT " bytes for curses window private space in base window\n",
125 mn, rn, sizeof(struct gator_cursesgwin));
127 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
128 if (c_data == (struct gator_cursesgwin *)0) {
130 "[%s:%s] Can't allocate %" AFS_SIZET_FMT " bytes for curses window private space in base window\n",
131 mn, rn, sizeof(struct gator_cursesgwin));
136 * Fill in the curses-specific base window info. We assume that chars are 8x13.
139 c_data->charwidth = 8;
140 c_data->charheight = 13;
141 c_data->box_vertchar = '|';
142 c_data->box_horizchar = '-';
145 * Fill in the generic base window info.
147 gator_basegwin.w_type = GATOR_WIN_CURSES;
148 gator_basegwin.w_x = 0;
149 gator_basegwin.w_y = 0;
150 gator_basegwin.w_width = c_data->charwidth * COLS;
151 gator_basegwin.w_height = c_data->charheight * LINES;
152 gator_basegwin.w_changed = 0;
153 gator_basegwin.w_op = &curses_gwinops;
154 gator_basegwin.w_parent = NULL;
157 * Plug the private data into the generic part of the base window.
159 gator_basegwin.w_data = (int *)c_data;
162 * Now, set the terminal into the right mode for handling input
164 raw(); /* curses raw mode */
167 gator_basegwin.w_frame = gtxframe_Create();
170 * Clear out the screen and return the good news.
172 wclear(((struct gator_cursesgwin *)(gator_basegwin.w_data))->wp);
175 } /*gator_cursesgwin_init */
177 /*------------------------------------------------------------------------
178 * gator_cursesgwin_create
181 * Create a curses window (incorrectly).
184 * struct gator_cursesgwin_params *params : Ptr to creation parameters.
187 * Ptr to the created curses window if successful,
188 * Null ptr otherwise.
191 * Nothing interesting.
195 *------------------------------------------------------------------------*/
198 gator_cursesgwin_create(void * rock)
200 static char rn[] = "gator_cursesgwin_create"; /*Routine name */
201 struct gator_cursesgwin_params *params = (struct gator_cursesgwin_params *)rock;
202 struct gwin *newgwin; /*Ptr to new curses window */
203 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
204 WINDOW *newcursgwin; /*Ptr to new curses window */
208 "[%s:%s] Allocating %" AFS_SIZET_FMT " bytes for new gwin structure\n", mn,
209 rn, sizeof(struct gwin));
210 newgwin = (struct gwin *)malloc(sizeof(struct gwin));
211 if (newgwin == NULL) {
213 "[%s:%s] Can't malloc() %" AFS_SIZET_FMT " bytes for new gwin structure: Errno is %d\n",
214 mn, rn, sizeof(struct gwin), errno);
218 newgwin->w_type = GATOR_WIN_CURSES;
219 newgwin->w_x = params->gwin_params.cr_x;
220 newgwin->w_y = params->gwin_params.cr_y;
221 newgwin->w_width = params->gwin_params.cr_width;
222 newgwin->w_height = params->gwin_params.cr_height;
223 newgwin->w_changed = 1;
224 newgwin->w_op = &curses_gwinops;
225 newgwin->w_parent = params->gwin_params.cr_parentwin;
229 "[%s:%s] Allocating %" AFS_SIZET_FMT " bytes for curses window private space\n",
230 mn, rn, sizeof(struct gator_cursesgwin));
232 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
233 if (c_data == (struct gator_cursesgwin *)0) {
235 "[%s:%s] Can't allocate %" AFS_SIZET_FMT " bytes for curses window private space\n",
236 mn, rn, sizeof(struct gator_cursesgwin));
241 newcursgwin = newwin(newgwin->w_height, /*Number of lines */
242 newgwin->w_width, /*Number of columns */
243 newgwin->w_y, /*Beginning y value */
244 newgwin->w_x); /*Beginning x value */
245 if (newcursgwin == (WINDOW *) 0) {
247 "[%s:%s] Failed to create curses window via newwin()\n", mn,
255 * Now, fill in the curses-specific window info.
257 c_data->wp = newcursgwin;
258 c_data->charwidth = params->charwidth;
259 c_data->charheight = params->charheight;
260 c_data->box_vertchar = params->box_vertchar;
261 c_data->box_horizchar = params->box_horizchar;
264 * Plug in a frame at the top-level.
266 newgwin->w_frame = gtxframe_Create();
269 * Plug the curses private data into the generic window object, then
270 * return the new window's info.
272 newgwin->w_data = (int *)c_data;
275 } /*gator_cursesgwin_create */
277 /*------------------------------------------------------------------------
278 * gator_cursesgwin_cleanup
281 * Clean up, probably right before the caller exits.
284 * struct gwin *gwp : Ptr to base window.
288 * Error value otherwise.
291 * Nothing interesting.
295 *------------------------------------------------------------------------*/
298 gator_cursesgwin_cleanup(struct gwin *gwp)
299 { /*gator_cursesgwin_cleanup */
301 static char rn[] = "gator_cursesgwin_cleanup"; /*Routine name */
302 struct gator_cursesgwin *cwp; /*Curses private area ptr */
304 cwp = (struct gator_cursesgwin *)(gwp->w_data);
307 * Cleaning up in curses is extremely easy - one simple call. We also
308 * want to clear the screen before we go.
311 fprintf(stderr, "[%s:%s] Calling wclear() on window at %p\n", mn,
317 * Now, set the terminal back into normal mode.
322 fprintf(stderr, "[%s:%s] Calling endwin()\n", mn, rn);
327 } /*gator_cursesgwin_cleanup */
329 /*------------------------------------------------------------------------
330 * gator_cursesgwin_box
333 * Draw a box around the given curses window.
336 * struct gwin *gwp : Ptr to the curses window to draw
341 * Error value otherwise.
344 * Nothing interesting.
348 *------------------------------------------------------------------------*/
351 gator_cursesgwin_box(struct gwin *gwp)
352 { /*gator_cursesgwin_box */
354 static char rn[] = "gator_cursesgwin_box"; /*Routine name */
355 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
357 cwp = (struct gator_cursesgwin *)(gwp->w_data);
359 fprintf(stderr, "[%s:%s] Calling box() on window at %p\n", mn, rn,
361 box(cwp->wp, cwp->box_vertchar, cwp->box_horizchar);
365 } /*gator_cursesgwin_box */
367 /*------------------------------------------------------------------------
368 * gator_cursesgwin_clear
371 * Clear out the given curses window.
374 * struct gwin *gwp : Ptr to the curses window to clear out.
378 * Error value otherwise.
381 * Nothing interesting.
385 *------------------------------------------------------------------------*/
388 gator_cursesgwin_clear(struct gwin *gwp)
389 { /*gator_cursesgwin_clear */
391 static char rn[] = "gator_cursesgwin_clear"; /*Routine name */
392 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
395 * Clearing windows is very easy in curses; just one call will do it.
397 cwp = (struct gator_cursesgwin *)(gwp->w_data);
399 fprintf(stderr, "[%s:%s] Calling wclear() on window at %p\n", mn,
405 } /*gator_cursesgwin_clear */
407 /*------------------------------------------------------------------------
408 * gator_cursesgwin_destroy
411 * Destroy the given curses window.
414 * struct gwin *gwp : Ptr to the curses window to destroy.
418 * Error value otherwise.
421 * Nothing interesting.
425 *------------------------------------------------------------------------*/
428 gator_cursesgwin_destroy(struct gwin *gwp)
429 { /*gator_cursesgwin_destroy */
431 static char rn[] = "gator_cursesgwin_destroy"; /*Routine name */
432 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
434 cwp = (struct gator_cursesgwin *)(gwp->w_data);
436 fprintf(stderr, "[%s:%s] Calling delwin() on window at %p\n", mn,
442 } /*gator_cursesgwin_destroy */
444 /*------------------------------------------------------------------------
445 * gator_cursesgwin_display
448 * Display/redraw the given curses window.
451 * struct gwin *gwp : Ptr to the curses window to draw.
455 * Error value otherwise.
458 * Nothing interesting.
462 *------------------------------------------------------------------------*/
465 gator_cursesgwin_display(struct gwin *gwp)
466 { /*gator_cursesgwin_display */
468 struct gator_cursesgwin *cwp; /*Curses private area ptr */
470 cwp = (struct gator_cursesgwin *)(gwp->w_data);
472 wclear(cwp->wp); /* clear screen */
473 gtxframe_Display(gwp->w_frame, gwp); /* display the frame */
474 wrefresh(cwp->wp); /* redraw the guy */
477 } /*gator_cursesgwin_display */
479 /*------------------------------------------------------------------------
480 * gator_cursesgwin_drawline
483 * Draw a line between two points in the given curses
487 * struct gwin *gwp : Ptr to the curses window in which
488 * the line is to be drawn.
489 * struct gwin_lineparams *params : Ptr to other params.
493 * Error value otherwise.
496 * Nothing interesting.
500 *------------------------------------------------------------------------*/
503 gator_cursesgwin_drawline(struct gwin *gwp, struct gwin_lineparams *params)
504 { /*gator_cursesgwin_drawline */
506 static char rn[] = "gator_cursesgwin_drawline"; /*Routine name */
509 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
514 } /*gator_cursesgwin_drawline */
516 /*------------------------------------------------------------------------
517 * gator_cursesgwin_drawrectangle
520 * Draw a rectangle in the given curses window.
523 * struct gwin *gwp : Ptr to the curses window in which
524 * the rectangle is to be drawn.
525 * struct gwin_rectparams *params : Ptr to other params.
529 * Error value otherwise.
532 * Nothing interesting.
536 *------------------------------------------------------------------------*/
539 gator_cursesgwin_drawrectangle(struct gwin *gwp, struct gwin_rectparams *params)
540 { /*gator_cursesgwin_drawrectangle */
542 static char rn[] = "gator_cursesgwin_drawrectangle"; /*Routine name */
545 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
550 } /*gator_cursesgwin_drawrectangle */
552 /*------------------------------------------------------------------------
553 * gator_cursesgwin_drawchar
556 * Draw a character in the given curses window.
559 * struct gwin *gwp : Ptr to the curses window in which
560 * the character is to be drawn.
561 * struct gwin_charparams *params : Ptr to other params.
565 * Error value otherwise.
568 * Nothing interesting.
572 *------------------------------------------------------------------------*/
575 gator_cursesgwin_drawchar(struct gwin *gwp, struct gwin_charparams *params)
576 { /*gator_cursesgwin_drawchar */
578 static char rn[] = "gator_cursesgwin_drawchar"; /*Routine name */
579 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
580 int curses_x, curses_y; /*Mapped x,y positions */
582 cwp = (struct gator_cursesgwin *)(gwp->w_data);
583 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
584 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
587 "[%s:%s] Drawing char '%c' on window at %p at (%d, %d) [line %d, column %d]%s\n",
588 mn, rn, params->c, cwp->wp, params->x, params->y, curses_y,
589 curses_x, (params->highlight ? ", using standout mode" : ""));
590 wmove(cwp->wp, curses_y, curses_x);
591 if (params->highlight)
593 waddch(cwp->wp, params->c);
594 if (params->highlight)
599 } /*gator_cursesgwin_drawchar */
601 /*------------------------------------------------------------------------
602 * gator_cursesgwin_drawstring
605 * Draw a string in the given curses window.
608 * struct gwin *gwp : Ptr to the curses window in which
609 * the string is to be drawn.
610 * struct gwin_strparams *params : Ptr to other params.
614 * Error value otherwise.
617 * Nothing interesting.
621 *------------------------------------------------------------------------*/
624 gator_cursesgwin_drawstring(struct gwin *gwp, struct gwin_strparams *params)
625 { /*gator_cursesgwin_drawstring */
627 static char rn[] = "gator_cursesgwin_drawstring"; /*Routine name */
628 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
629 int curses_x, curses_y; /*Mapped x,y positions */
631 cwp = (struct gator_cursesgwin *)(gwp->w_data);
632 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
633 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
636 "[%s:%s] Drawing string '%s' on window at %p at (%d, %d) [line %d, column %d]%s\n",
637 mn, rn, params->s, cwp->wp, params->x, params->y, curses_y,
638 curses_x, (params->highlight ? ", using standout mode" : ""));
639 wmove(cwp->wp, curses_y, curses_x);
640 if (params->highlight)
642 waddstr(cwp->wp, params->s);
643 if (params->highlight)
648 } /*gator_cursesgwin_drawstring */
650 /*------------------------------------------------------------------------
651 * gator_cursesgwin_invert
654 * Invert a region in the given curses window.
657 * struct gwin *gwp : Ptr to the curses window in which
658 * the inverted region lies.
659 * struct gwin_invparams *params : Ptr to other params.
663 * Error value otherwise.
666 * Nothing interesting.
670 *------------------------------------------------------------------------*/
673 gator_cursesgwin_invert(struct gwin *gwp, struct gwin_invparams *params)
674 { /*gator_cursesgwin_invert */
676 static char rn[] = "gator_cursesgwin_invert"; /*Routine name */
679 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
684 } /*gator_cursesgwin_invert */
686 /*------------------------------------------------------------------------
687 * gator_cursesgwin_getchar
690 * Pick up a character from the given window.
693 * struct gwin *gwp : Ptr to the curses window to listen to.
696 * Value of the character read,
700 * Nothing interesting.
704 *------------------------------------------------------------------------*/
707 gator_cursesgwin_getchar(struct gwin *gwp)
708 { /*gator_cursesgwin_getchar */
710 return (getc(stdin));
712 } /*gator_cursesgwin_getchar */
714 /*------------------------------------------------------------------------
715 * gator_cursesgwin_wait
718 * Wait until input is available.
721 * struct gwin *gwp : Ptr to the curses window to wait on.
725 * Error value otherwise.
728 * Nothing interesting.
732 *------------------------------------------------------------------------*/
735 gator_cursesgwin_wait(struct gwin *gwp)
736 { /*gator_cursesgwin_wait */
738 while (!LWP_WaitForKeystroke(-1));
742 } /*gator_cursesgwin_wait */
744 /*------------------------------------------------------------------------
745 * gator_cursesgwin_getdimensions
748 * Get the window's X,Y dimensions.
751 * struct gwin *gwp : Ptr to the curses window to examine.
752 * struct gwin_sizeparams *params : Ptr to the size params to set.
756 * Error value otherwise.
759 * Nothing interesting.
763 *------------------------------------------------------------------------*/
766 gator_cursesgwin_getdimensions(struct gwin *gwp, struct gwin_sizeparams *aparms)
767 { /*gator_cursesgwin_getdimensions */
769 struct gator_cursesgwin *cwp; /*Curses-specific data */
771 cwp = (struct gator_cursesgwin *)(gwp->w_data);
772 #if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN60_ENV)
773 aparms->maxx = cwp->wp->maxx;
774 aparms->maxy = cwp->wp->maxy;
775 #elif 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 */