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)
45 #include "gtxcurseswin.h" /*Interface definition */
46 #include "gtxobjects.h"
51 int curses_debug; /*Is debugging turned on? */
52 static char mn[] = "gator_curseswindows"; /*Module name */
55 * Version of standard operations for a curses window.
57 struct gwinops curses_gwinops = {
59 gator_cursesgwin_clear,
60 gator_cursesgwin_destroy,
61 gator_cursesgwin_display,
62 gator_cursesgwin_drawline,
63 gator_cursesgwin_drawrectangle,
64 gator_cursesgwin_drawchar,
65 gator_cursesgwin_drawstring,
66 gator_cursesgwin_invert,
67 gator_cursesgwin_getchar,
68 gator_cursesgwin_getdimensions,
69 gator_cursesgwin_wait,
72 struct gwinbaseops gator_curses_gwinbops = {
73 gator_cursesgwin_create,
74 gator_cursesgwin_cleanup,
79 * Macros to map pixel positions to row & column positions.
80 * (Note: for now, they are the identity function!!)
82 #define GATOR_MAP_X_TO_COL(w, x) (x)
83 #define GATOR_MAP_Y_TO_LINE(w, y) (y)
85 /*------------------------------------------------------------------------
86 * gator_cursesgwin_init
89 * Initialize the curses window package.
92 * int adebug: Is debugging turned on?
96 * Error value otherwise.
99 * Nothing interesting.
103 *------------------------------------------------------------------------*/
106 gator_cursesgwin_init(int 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 %lu 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 %lu 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(struct gator_cursesgwin_params *params)
201 { /*gator_cursesgwin_create */
203 static char rn[] = "gator_cursesgwin_create"; /*Routine name */
204 struct gwin *newgwin; /*Ptr to new curses window */
205 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
206 WINDOW *newcursgwin; /*Ptr to new curses window */
210 "[%s:%s] Allocating %lu bytes for new gwin structure\n", mn,
211 rn, sizeof(struct gwin));
212 newgwin = (struct gwin *)malloc(sizeof(struct gwin));
213 if (newgwin == NULL) {
215 "[%s:%s] Can't malloc() %lu bytes for new gwin structure: Errno is %d\n",
216 mn, rn, sizeof(struct gwin), errno);
220 newgwin->w_type = GATOR_WIN_CURSES;
221 newgwin->w_x = params->gwin_params.cr_x;
222 newgwin->w_y = params->gwin_params.cr_y;
223 newgwin->w_width = params->gwin_params.cr_width;
224 newgwin->w_height = params->gwin_params.cr_height;
225 newgwin->w_changed = 1;
226 newgwin->w_op = &curses_gwinops;
227 newgwin->w_parent = params->gwin_params.cr_parentwin;
231 "[%s:%s] Allocating %lu bytes for curses window private space\n",
232 mn, rn, sizeof(struct gator_cursesgwin));
234 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
235 if (c_data == (struct gator_cursesgwin *)0) {
237 "[%s:%s] Can't allocate %lu bytes for curses window private space\n",
238 mn, rn, sizeof(struct gator_cursesgwin));
243 newcursgwin = newwin(newgwin->w_height, /*Number of lines */
244 newgwin->w_width, /*Number of columns */
245 newgwin->w_y, /*Beginning y value */
246 newgwin->w_x); /*Beginning x value */
247 if (newcursgwin == (WINDOW *) 0) {
249 "[%s:%s] Failed to create curses window via newwin()\n", mn,
257 * Now, fill in the curses-specific window info.
259 c_data->wp = newcursgwin;
260 c_data->charwidth = params->charwidth;
261 c_data->charheight = params->charheight;
262 c_data->box_vertchar = params->box_vertchar;
263 c_data->box_horizchar = params->box_horizchar;
266 * Plug in a frame at the top-level.
268 newgwin->w_frame = gtxframe_Create();
271 * Plug the curses private data into the generic window object, then
272 * return the new window's info.
274 newgwin->w_data = (int *)c_data;
277 } /*gator_cursesgwin_create */
279 /*------------------------------------------------------------------------
280 * gator_cursesgwin_cleanup
283 * Clean up, probably right before the caller exits.
286 * struct gwin *gwp : Ptr to base window.
290 * Error value otherwise.
293 * Nothing interesting.
297 *------------------------------------------------------------------------*/
300 gator_cursesgwin_cleanup(struct gwin *gwp)
301 { /*gator_cursesgwin_cleanup */
303 static char rn[] = "gator_cursesgwin_cleanup"; /*Routine name */
304 struct gator_cursesgwin *cwp; /*Curses private area ptr */
306 cwp = (struct gator_cursesgwin *)(gwp->w_data);
309 * Cleaning up in curses is extremely easy - one simple call. We also
310 * want to clear the screen before we go.
313 fprintf(stderr, "[%s:%s] Calling wclear() on window at %p\n", mn,
319 * Now, set the terminal back into normal mode.
324 fprintf(stderr, "[%s:%s] Calling endwin()\n", mn, rn);
329 } /*gator_cursesgwin_cleanup */
331 /*------------------------------------------------------------------------
332 * gator_cursesgwin_box
335 * Draw a box around the given curses window.
338 * struct gwin *gwp : Ptr to the curses window to draw
343 * Error value otherwise.
346 * Nothing interesting.
350 *------------------------------------------------------------------------*/
353 gator_cursesgwin_box(struct gwin *gwp)
354 { /*gator_cursesgwin_box */
356 static char rn[] = "gator_cursesgwin_box"; /*Routine name */
357 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
359 cwp = (struct gator_cursesgwin *)(gwp->w_data);
361 fprintf(stderr, "[%s:%s] Calling box() on window at %p\n", mn, rn,
363 box(cwp->wp, cwp->box_vertchar, cwp->box_horizchar);
367 } /*gator_cursesgwin_box */
369 /*------------------------------------------------------------------------
370 * gator_cursesgwin_clear
373 * Clear out the given curses window.
376 * struct gwin *gwp : Ptr to the curses window to clear out.
380 * Error value otherwise.
383 * Nothing interesting.
387 *------------------------------------------------------------------------*/
390 gator_cursesgwin_clear(struct gwin *gwp)
391 { /*gator_cursesgwin_clear */
393 static char rn[] = "gator_cursesgwin_clear"; /*Routine name */
394 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
397 * Clearing windows is very easy in curses; just one call will do it.
399 cwp = (struct gator_cursesgwin *)(gwp->w_data);
401 fprintf(stderr, "[%s:%s] Calling wclear() on window at %p\n", mn,
407 } /*gator_cursesgwin_clear */
409 /*------------------------------------------------------------------------
410 * gator_cursesgwin_destroy
413 * Destroy the given curses window.
416 * struct gwin *gwp : Ptr to the curses window to destroy.
420 * Error value otherwise.
423 * Nothing interesting.
427 *------------------------------------------------------------------------*/
430 gator_cursesgwin_destroy(struct gwin *gwp)
431 { /*gator_cursesgwin_destroy */
433 static char rn[] = "gator_cursesgwin_destroy"; /*Routine name */
434 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
436 cwp = (struct gator_cursesgwin *)(gwp->w_data);
438 fprintf(stderr, "[%s:%s] Calling delwin() on window at %p\n", mn,
444 } /*gator_cursesgwin_destroy */
446 /*------------------------------------------------------------------------
447 * gator_cursesgwin_display
450 * Display/redraw the given curses window.
453 * struct gwin *gwp : Ptr to the curses window to draw.
457 * Error value otherwise.
460 * Nothing interesting.
464 *------------------------------------------------------------------------*/
467 gator_cursesgwin_display(struct gwin *gwp)
468 { /*gator_cursesgwin_display */
470 struct gator_cursesgwin *cwp; /*Curses private area ptr */
472 cwp = (struct gator_cursesgwin *)(gwp->w_data);
474 wclear(cwp->wp); /* clear screen */
475 gtxframe_Display(gwp->w_frame, gwp); /* display the frame */
476 wrefresh(cwp->wp); /* redraw the guy */
479 } /*gator_cursesgwin_display */
481 /*------------------------------------------------------------------------
482 * gator_cursesgwin_drawline
485 * Draw a line between two points in the given curses
489 * struct gwin *gwp : Ptr to the curses window in which
490 * the line is to be drawn.
491 * struct gwin_lineparams *params : Ptr to other params.
495 * Error value otherwise.
498 * Nothing interesting.
502 *------------------------------------------------------------------------*/
505 gator_cursesgwin_drawline(struct gwin *gwp, struct gwin_lineparams *params)
506 { /*gator_cursesgwin_drawline */
508 static char rn[] = "gator_cursesgwin_drawline"; /*Routine name */
511 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
516 } /*gator_cursesgwin_drawline */
518 /*------------------------------------------------------------------------
519 * gator_cursesgwin_drawrectangle
522 * Draw a rectangle in the given curses window.
525 * struct gwin *gwp : Ptr to the curses window in which
526 * the rectangle is to be drawn.
527 * struct gwin_rectparams *params : Ptr to other params.
531 * Error value otherwise.
534 * Nothing interesting.
538 *------------------------------------------------------------------------*/
541 gator_cursesgwin_drawrectangle(struct gwin *gwp, struct gwin_rectparams *params)
542 { /*gator_cursesgwin_drawrectangle */
544 static char rn[] = "gator_cursesgwin_drawrectangle"; /*Routine name */
547 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
552 } /*gator_cursesgwin_drawrectangle */
554 /*------------------------------------------------------------------------
555 * gator_cursesgwin_drawchar
558 * Draw a character in the given curses window.
561 * struct gwin *gwp : Ptr to the curses window in which
562 * the character is to be drawn.
563 * struct gwin_charparams *params : Ptr to other params.
567 * Error value otherwise.
570 * Nothing interesting.
574 *------------------------------------------------------------------------*/
577 gator_cursesgwin_drawchar(struct gwin *gwp, struct gwin_charparams *params)
578 { /*gator_cursesgwin_drawchar */
580 static char rn[] = "gator_cursesgwin_drawchar"; /*Routine name */
581 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
582 int curses_x, curses_y; /*Mapped x,y positions */
584 cwp = (struct gator_cursesgwin *)(gwp->w_data);
585 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
586 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
589 "[%s:%s] Drawing char '%c' on window at %p at (%d, %d) [line %d, column %d]%s\n",
590 mn, rn, params->c, cwp->wp, params->x, params->y, curses_y,
591 curses_x, (params->highlight ? ", using standout mode" : ""));
592 wmove(cwp->wp, curses_y, curses_x);
593 if (params->highlight)
595 waddch(cwp->wp, params->c);
596 if (params->highlight)
601 } /*gator_cursesgwin_drawchar */
603 /*------------------------------------------------------------------------
604 * gator_cursesgwin_drawstring
607 * Draw a string in the given curses window.
610 * struct gwin *gwp : Ptr to the curses window in which
611 * the string is to be drawn.
612 * struct gwin_strparams *params : Ptr to other params.
616 * Error value otherwise.
619 * Nothing interesting.
623 *------------------------------------------------------------------------*/
626 gator_cursesgwin_drawstring(struct gwin *gwp, struct gwin_strparams *params)
627 { /*gator_cursesgwin_drawstring */
629 static char rn[] = "gator_cursesgwin_drawstring"; /*Routine name */
630 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
631 int curses_x, curses_y; /*Mapped x,y positions */
633 cwp = (struct gator_cursesgwin *)(gwp->w_data);
634 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
635 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
638 "[%s:%s] Drawing string '%s' on window at %p at (%d, %d) [line %d, column %d]%s\n",
639 mn, rn, params->s, cwp->wp, params->x, params->y, curses_y,
640 curses_x, (params->highlight ? ", using standout mode" : ""));
641 wmove(cwp->wp, curses_y, curses_x);
642 if (params->highlight)
644 waddstr(cwp->wp, params->s);
645 if (params->highlight)
650 } /*gator_cursesgwin_drawstring */
652 /*------------------------------------------------------------------------
653 * gator_cursesgwin_invert
656 * Invert a region in the given curses window.
659 * struct gwin *gwp : Ptr to the curses window in which
660 * the inverted region lies.
661 * struct gwin_invparams *params : Ptr to other params.
665 * Error value otherwise.
668 * Nothing interesting.
672 *------------------------------------------------------------------------*/
675 gator_cursesgwin_invert(struct gwin *gwp, struct gwin_invparams *params)
676 { /*gator_cursesgwin_invert */
678 static char rn[] = "gator_cursesgwin_invert"; /*Routine name */
681 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
686 } /*gator_cursesgwin_invert */
688 /*------------------------------------------------------------------------
689 * gator_cursesgwin_getchar
692 * Pick up a character from the given window.
695 * struct gwin *gwp : Ptr to the curses window to listen to.
698 * Value of the character read,
702 * Nothing interesting.
706 *------------------------------------------------------------------------*/
709 gator_cursesgwin_getchar(struct gwin *gwp)
710 { /*gator_cursesgwin_getchar */
712 return (getc(stdin));
714 } /*gator_cursesgwin_getchar */
716 /*------------------------------------------------------------------------
717 * gator_cursesgwin_wait
720 * Wait until input is available.
723 * struct gwin *gwp : Ptr to the curses window to wait on.
727 * Error value otherwise.
730 * Nothing interesting.
734 *------------------------------------------------------------------------*/
737 gator_cursesgwin_wait(struct gwin *gwp)
738 { /*gator_cursesgwin_wait */
740 while (!LWP_WaitForKeystroke(-1));
744 } /*gator_cursesgwin_wait */
746 /*------------------------------------------------------------------------
747 * gator_cursesgwin_getdimensions
750 * Get the window's X,Y dimensions.
753 * struct gwin *gwp : Ptr to the curses window to examine.
754 * struct gwin_sizeparams *params : Ptr to the size params to set.
758 * Error value otherwise.
761 * Nothing interesting.
765 *------------------------------------------------------------------------*/
768 gator_cursesgwin_getdimensions(struct gwin *gwp, struct gwin_sizeparams *aparms)
769 { /*gator_cursesgwin_getdimensions */
771 struct gator_cursesgwin *cwp; /*Curses-specific data */
773 cwp = (struct gator_cursesgwin *)(gwp->w_data);
774 #if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN60_ENV)
775 aparms->maxx = cwp->wp->maxx;
776 aparms->maxy = cwp->wp->maxy;
777 #elif defined(AFS_NBSD_ENV)
778 aparms->maxx = getmaxx(cwp->wp);
779 aparms->maxy = getmaxy(cwp->wp);
781 aparms->maxx = cwp->wp->_maxx;
782 aparms->maxy = cwp->wp->_maxy;
787 } /*gator_cursesgwin_getdimensions */