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(adebug)
109 { /*gator_cursesgwin_init */
111 static char rn[] = "gator_cursesgwin_init"; /*Routine name */
112 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
115 * Remember if we'll be doing debugging, then init the curses package.
117 curses_debug = adebug;
120 fprintf(stderr, "[%s:%s] Calling initscr()\n", mn, rn);
124 * Fill out the base window structure for curses.
128 "[%s:%s] Allocating %d bytes for curses window private space in base window\n",
129 mn, rn, sizeof(struct gator_cursesgwin));
131 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
132 if (c_data == (struct gator_cursesgwin *)0) {
134 "[%s:%s] Can't allocate %d bytes for curses window private space in base window\n",
135 mn, rn, sizeof(struct gator_cursesgwin));
140 * Fill in the curses-specific base window info. We assume that chars are 8x13.
143 c_data->charwidth = 8;
144 c_data->charheight = 13;
145 c_data->box_vertchar = '|';
146 c_data->box_horizchar = '-';
149 * Fill in the generic base window info.
151 gator_basegwin.w_type = GATOR_WIN_CURSES;
152 gator_basegwin.w_x = 0;
153 gator_basegwin.w_y = 0;
154 gator_basegwin.w_width = c_data->charwidth * COLS;
155 gator_basegwin.w_height = c_data->charheight * LINES;
156 gator_basegwin.w_changed = 0;
157 gator_basegwin.w_op = &curses_gwinops;
158 gator_basegwin.w_parent = NULL;
161 * Plug the private data into the generic part of the base window.
163 gator_basegwin.w_data = (int *)c_data;
166 * Now, set the terminal into the right mode for handling input
168 raw(); /* curses raw mode */
171 gator_basegwin.w_frame = gtxframe_Create();
174 * Clear out the screen and return the good news.
176 wclear(((struct gator_cursesgwin *)(gator_basegwin.w_data))->wp);
179 } /*gator_cursesgwin_init */
181 /*------------------------------------------------------------------------
182 * gator_cursesgwin_create
185 * Create a curses window (incorrectly).
188 * struct gator_cursesgwin_params *params : Ptr to creation parameters.
191 * Ptr to the created curses window if successful,
192 * Null ptr otherwise.
195 * Nothing interesting.
199 *------------------------------------------------------------------------*/
202 gator_cursesgwin_create(params)
203 struct gator_cursesgwin_params *params;
205 { /*gator_cursesgwin_create */
207 static char rn[] = "gator_cursesgwin_create"; /*Routine name */
208 struct gwin *newgwin; /*Ptr to new curses window */
209 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data */
210 WINDOW *newcursgwin; /*Ptr to new curses window */
214 "[%s:%s] Allocating %d bytes for new gwin structure\n", mn,
215 rn, sizeof(struct gwin));
216 newgwin = (struct gwin *)malloc(sizeof(struct gwin));
217 if (newgwin == NULL) {
219 "[%s:%s] Can't malloc() %d bytes for new gwin structure: Errno is %d\n",
220 mn, rn, sizeof(struct gwin), errno);
224 newgwin->w_type = GATOR_WIN_CURSES;
225 newgwin->w_x = params->gwin_params.cr_x;
226 newgwin->w_y = params->gwin_params.cr_y;
227 newgwin->w_width = params->gwin_params.cr_width;
228 newgwin->w_height = params->gwin_params.cr_height;
229 newgwin->w_changed = 1;
230 newgwin->w_op = &curses_gwinops;
231 newgwin->w_parent = params->gwin_params.cr_parentwin;
235 "[%s:%s] Allocating %d bytes for curses window private space\n",
236 mn, rn, sizeof(struct gator_cursesgwin));
238 (struct gator_cursesgwin *)malloc(sizeof(struct gator_cursesgwin));
239 if (c_data == (struct gator_cursesgwin *)0) {
241 "[%s:%s] Can't allocate %d bytes for curses window private space\n",
242 mn, rn, sizeof(struct gator_cursesgwin));
247 newcursgwin = newwin(newgwin->w_height, /*Number of lines */
248 newgwin->w_width, /*Number of columns */
249 newgwin->w_y, /*Beginning y value */
250 newgwin->w_x); /*Beginning x value */
251 if (newcursgwin == (WINDOW *) 0) {
253 "[%s:%s] Failed to create curses window via newwin()\n", mn,
261 * Now, fill in the curses-specific window info.
263 c_data->wp = newcursgwin;
264 c_data->charwidth = params->charwidth;
265 c_data->charheight = params->charheight;
266 c_data->box_vertchar = params->box_vertchar;
267 c_data->box_horizchar = params->box_horizchar;
270 * Plug in a frame at the top-level.
272 newgwin->w_frame = gtxframe_Create();
275 * Plug the curses private data into the generic window object, then
276 * return the new window's info.
278 newgwin->w_data = (int *)c_data;
281 } /*gator_cursesgwin_create */
283 /*------------------------------------------------------------------------
284 * gator_cursesgwin_cleanup
287 * Clean up, probably right before the caller exits.
290 * struct gwin *gwp : Ptr to base window.
294 * Error value otherwise.
297 * Nothing interesting.
301 *------------------------------------------------------------------------*/
304 gator_cursesgwin_cleanup(gwp)
307 { /*gator_cursesgwin_cleanup */
309 static char rn[] = "gator_cursesgwin_cleanup"; /*Routine name */
310 struct gator_cursesgwin *cwp; /*Curses private area ptr */
312 cwp = (struct gator_cursesgwin *)(gwp->w_data);
315 * Cleaning up in curses is extremely easy - one simple call. We also
316 * want to clear the screen before we go.
319 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn,
325 * Now, set the terminal back into normal mode.
330 fprintf(stderr, "[%s:%s] Calling endwin()\n", mn, rn);
335 } /*gator_cursesgwin_cleanup */
337 /*------------------------------------------------------------------------
338 * gator_cursesgwin_box
341 * Draw a box around the given curses window.
344 * struct gwin *gwp : Ptr to the curses window to draw
349 * Error value otherwise.
352 * Nothing interesting.
356 *------------------------------------------------------------------------*/
359 gator_cursesgwin_box(gwp)
362 { /*gator_cursesgwin_box */
364 static char rn[] = "gator_cursesgwin_box"; /*Routine name */
365 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
367 cwp = (struct gator_cursesgwin *)(gwp->w_data);
369 fprintf(stderr, "[%s:%s] Calling box() on window at 0x%x\n", mn, rn,
371 box(cwp->wp, cwp->box_vertchar, cwp->box_horizchar);
375 } /*gator_cursesgwin_box */
377 /*------------------------------------------------------------------------
378 * gator_cursesgwin_clear
381 * Clear out the given curses window.
384 * struct gwin *gwp : Ptr to the curses window to clear out.
388 * Error value otherwise.
391 * Nothing interesting.
395 *------------------------------------------------------------------------*/
398 gator_cursesgwin_clear(gwp)
401 { /*gator_cursesgwin_clear */
403 static char rn[] = "gator_cursesgwin_clear"; /*Routine name */
404 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
407 * Clearing windows is very easy in curses; just one call will do it.
409 cwp = (struct gator_cursesgwin *)(gwp->w_data);
411 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn,
417 } /*gator_cursesgwin_clear */
419 /*------------------------------------------------------------------------
420 * gator_cursesgwin_destroy
423 * Destroy the given curses window.
426 * struct gwin *gwp : Ptr to the curses window to destroy.
430 * Error value otherwise.
433 * Nothing interesting.
437 *------------------------------------------------------------------------*/
440 gator_cursesgwin_destroy(gwp)
443 { /*gator_cursesgwin_destroy */
445 static char rn[] = "gator_cursesgwin_destroy"; /*Routine name */
446 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
448 cwp = (struct gator_cursesgwin *)(gwp->w_data);
450 fprintf(stderr, "[%s:%s] Calling delwin() on window at 0x%x\n", mn,
456 } /*gator_cursesgwin_destroy */
458 /*------------------------------------------------------------------------
459 * gator_cursesgwin_display
462 * Display/redraw the given curses window.
465 * struct gwin *gwp : Ptr to the curses window to draw.
469 * Error value otherwise.
472 * Nothing interesting.
476 *------------------------------------------------------------------------*/
479 gator_cursesgwin_display(gwp)
482 { /*gator_cursesgwin_display */
484 struct gator_cursesgwin *cwp; /*Curses private area ptr */
486 cwp = (struct gator_cursesgwin *)(gwp->w_data);
488 wclear(cwp->wp); /* clear screen */
489 gtxframe_Display(gwp->w_frame, gwp); /* display the frame */
490 wrefresh(cwp->wp); /* redraw the guy */
493 } /*gator_cursesgwin_display */
495 /*------------------------------------------------------------------------
496 * gator_cursesgwin_drawline
499 * Draw a line between two points in the given curses
503 * struct gwin *gwp : Ptr to the curses window in which
504 * the line is to be drawn.
505 * struct gwin_lineparams *params : Ptr to other params.
509 * Error value otherwise.
512 * Nothing interesting.
516 *------------------------------------------------------------------------*/
519 gator_cursesgwin_drawline(gwp, params)
521 struct gwin_lineparams *params;
523 { /*gator_cursesgwin_drawline */
525 static char rn[] = "gator_cursesgwin_drawline"; /*Routine name */
528 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
533 } /*gator_cursesgwin_drawline */
535 /*------------------------------------------------------------------------
536 * gator_cursesgwin_drawrectangle
539 * Draw a rectangle in the given curses window.
542 * struct gwin *gwp : Ptr to the curses window in which
543 * the rectangle is to be drawn.
544 * struct gwin_rectparams *params : Ptr to other params.
548 * Error value otherwise.
551 * Nothing interesting.
555 *------------------------------------------------------------------------*/
558 gator_cursesgwin_drawrectangle(gwp, params)
560 struct gwin_rectparams *params;
562 { /*gator_cursesgwin_drawrectangle */
564 static char rn[] = "gator_cursesgwin_drawrectangle"; /*Routine name */
567 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
572 } /*gator_cursesgwin_drawrectangle */
574 /*------------------------------------------------------------------------
575 * gator_cursesgwin_drawchar
578 * Draw a character in the given curses window.
581 * struct gwin *gwp : Ptr to the curses window in which
582 * the character is to be drawn.
583 * struct gwin_charparams *params : Ptr to other params.
587 * Error value otherwise.
590 * Nothing interesting.
594 *------------------------------------------------------------------------*/
597 gator_cursesgwin_drawchar(gwp, params)
599 struct gwin_charparams *params;
601 { /*gator_cursesgwin_drawchar */
603 static char rn[] = "gator_cursesgwin_drawchar"; /*Routine name */
604 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
605 int curses_x, curses_y; /*Mapped x,y positions */
607 cwp = (struct gator_cursesgwin *)(gwp->w_data);
608 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
609 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
612 "[%s:%s] Drawing char '%c' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n",
613 mn, rn, params->c, cwp->wp, params->x, params->y, curses_y,
614 curses_x, (params->highlight ? ", using standout mode" : ""));
615 wmove(cwp->wp, curses_y, curses_x);
616 if (params->highlight)
618 waddch(cwp->wp, params->c);
619 if (params->highlight)
624 } /*gator_cursesgwin_drawchar */
626 /*------------------------------------------------------------------------
627 * gator_cursesgwin_drawstring
630 * Draw a string in the given curses window.
633 * struct gwin *gwp : Ptr to the curses window in which
634 * the string is to be drawn.
635 * struct gwin_strparams *params : Ptr to other params.
639 * Error value otherwise.
642 * Nothing interesting.
646 *------------------------------------------------------------------------*/
649 gator_cursesgwin_drawstring(gwp, params)
651 struct gwin_strparams *params;
653 { /*gator_cursesgwin_drawstring */
655 static char rn[] = "gator_cursesgwin_drawstring"; /*Routine name */
656 struct gator_cursesgwin *cwp; /*Ptr to curses private area */
657 int curses_x, curses_y; /*Mapped x,y positions */
659 cwp = (struct gator_cursesgwin *)(gwp->w_data);
660 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
661 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
664 "[%s:%s] Drawing string '%s' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n",
665 mn, rn, params->s, cwp->wp, params->x, params->y, curses_y,
666 curses_x, (params->highlight ? ", using standout mode" : ""));
667 wmove(cwp->wp, curses_y, curses_x);
668 if (params->highlight)
670 waddstr(cwp->wp, params->s);
671 if (params->highlight)
676 } /*gator_cursesgwin_drawstring */
678 /*------------------------------------------------------------------------
679 * gator_cursesgwin_invert
682 * Invert a region in the given curses window.
685 * struct gwin *gwp : Ptr to the curses window in which
686 * the inverted region lies.
687 * struct gwin_invparams *params : Ptr to other params.
691 * Error value otherwise.
694 * Nothing interesting.
698 *------------------------------------------------------------------------*/
701 gator_cursesgwin_invert(gwp, params)
703 struct gwin_invparams *params;
705 { /*gator_cursesgwin_invert */
707 static char rn[] = "gator_cursesgwin_invert"; /*Routine name */
710 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn,
715 } /*gator_cursesgwin_invert */
717 /*------------------------------------------------------------------------
718 * gator_cursesgwin_getchar
721 * Pick up a character from the given window.
724 * struct gwin *gwp : Ptr to the curses window to listen to.
727 * Value of the character read,
731 * Nothing interesting.
735 *------------------------------------------------------------------------*/
738 gator_cursesgwin_getchar(gwp)
741 { /*gator_cursesgwin_getchar */
743 return (getc(stdin));
745 } /*gator_cursesgwin_getchar */
747 /*------------------------------------------------------------------------
748 * gator_cursesgwin_wait
751 * Wait until input is available.
754 * struct gwin *gwp : Ptr to the curses window to wait on.
758 * Error value otherwise.
761 * Nothing interesting.
765 *------------------------------------------------------------------------*/
768 gator_cursesgwin_wait(gwp)
771 { /*gator_cursesgwin_wait */
773 while (!LWP_WaitForKeystroke(-1));
777 } /*gator_cursesgwin_wait */
779 /*------------------------------------------------------------------------
780 * gator_cursesgwin_getdimensions
783 * Get the window's X,Y dimensions.
786 * struct gwin *gwp : Ptr to the curses window to examine.
787 * struct gwin_sizeparams *params : Ptr to the size params to set.
791 * Error value otherwise.
794 * Nothing interesting.
798 *------------------------------------------------------------------------*/
801 gator_cursesgwin_getdimensions(gwp, aparms)
802 struct gwin_sizeparams *aparms;
805 { /*gator_cursesgwin_getdimensions */
807 struct gator_cursesgwin *cwp; /*Curses-specific data */
809 cwp = (struct gator_cursesgwin *)(gwp->w_data);
810 #if defined(AFS_DARWIN_ENV) && !defined(AFS_DARWIN60_ENV)
811 aparms->maxx = cwp->wp->maxx;
812 aparms->maxy = cwp->wp->maxy;
813 #elif defined(AFS_NBSD_ENV)
814 aparms->maxx = getmaxx(cwp->wp);
815 aparms->maxy = getmaxy(cwp->wp);
817 aparms->maxx = cwp->wp->_maxx;
818 aparms->maxy = cwp->wp->_maxy;
823 } /*gator_cursesgwin_getdimensions */