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_SUN5_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_FBSD80_ENV)
29 #include "gtxcurseswin.h" /*Interface definition */
30 #include "gtxobjects.h"
33 int curses_debug
; /*Is debugging turned on? */
34 static char mn
[] = "gator_curseswindows"; /*Module name */
37 * Version of standard operations for a curses window.
39 struct gwinops curses_gwinops
= {
41 gator_cursesgwin_clear
,
42 gator_cursesgwin_destroy
,
43 gator_cursesgwin_display
,
44 gator_cursesgwin_drawline
,
45 gator_cursesgwin_drawrectangle
,
46 gator_cursesgwin_drawchar
,
47 gator_cursesgwin_drawstring
,
48 gator_cursesgwin_invert
,
49 gator_cursesgwin_getchar
,
50 gator_cursesgwin_getdimensions
,
51 gator_cursesgwin_wait
,
54 struct gwinbaseops gator_curses_gwinbops
= {
55 gator_cursesgwin_create
,
56 gator_cursesgwin_cleanup
,
61 * Macros to map pixel positions to row & column positions.
62 * (Note: for now, they are the identity function!!)
64 #define GATOR_MAP_X_TO_COL(w, x) (x)
65 #define GATOR_MAP_Y_TO_LINE(w, y) (y)
67 /*------------------------------------------------------------------------
68 * gator_cursesgwin_init
71 * Initialize the curses window package.
74 * int adebug: Is debugging turned on?
78 * Error value otherwise.
81 * Nothing interesting.
85 *------------------------------------------------------------------------*/
88 gator_cursesgwin_init(int adebug
)
89 { /*gator_cursesgwin_init */
91 static char rn
[] = "gator_cursesgwin_init"; /*Routine name */
92 struct gator_cursesgwin
*c_data
; /*Ptr to curses-specific data */
95 * Remember if we'll be doing debugging, then init the curses package.
97 curses_debug
= adebug
;
100 fprintf(stderr
, "[%s:%s] Calling initscr()\n", mn
, rn
);
104 * Fill out the base window structure for curses.
108 "[%s:%s] Allocating %" AFS_SIZET_FMT
" bytes for curses window private space in base window\n",
109 mn
, rn
, sizeof(struct gator_cursesgwin
));
110 c_data
= malloc(sizeof(struct gator_cursesgwin
));
111 if (c_data
== (struct gator_cursesgwin
*)0) {
113 "[%s:%s] Can't allocate %" AFS_SIZET_FMT
" bytes for curses window private space in base window\n",
114 mn
, rn
, sizeof(struct gator_cursesgwin
));
119 * Fill in the curses-specific base window info. We assume that chars are 8x13.
122 c_data
->charwidth
= 8;
123 c_data
->charheight
= 13;
124 c_data
->box_vertchar
= '|';
125 c_data
->box_horizchar
= '-';
128 * Fill in the generic base window info.
130 gator_basegwin
.w_type
= GATOR_WIN_CURSES
;
131 gator_basegwin
.w_x
= 0;
132 gator_basegwin
.w_y
= 0;
133 gator_basegwin
.w_width
= c_data
->charwidth
* COLS
;
134 gator_basegwin
.w_height
= c_data
->charheight
* LINES
;
135 gator_basegwin
.w_changed
= 0;
136 gator_basegwin
.w_op
= &curses_gwinops
;
137 gator_basegwin
.w_parent
= NULL
;
140 * Plug the private data into the generic part of the base window.
142 gator_basegwin
.w_data
= (int *)c_data
;
145 * Now, set the terminal into the right mode for handling input
147 raw(); /* curses raw mode */
150 gator_basegwin
.w_frame
= gtxframe_Create();
153 * Clear out the screen and return the good news.
155 wclear(((struct gator_cursesgwin
*)(gator_basegwin
.w_data
))->wp
);
158 } /*gator_cursesgwin_init */
160 /*------------------------------------------------------------------------
161 * gator_cursesgwin_create
164 * Create a curses window (incorrectly).
167 * struct gator_cursesgwin_params *params : Ptr to creation parameters.
170 * Ptr to the created curses window if successful,
171 * Null ptr otherwise.
174 * Nothing interesting.
178 *------------------------------------------------------------------------*/
181 gator_cursesgwin_create(void * rock
)
183 static char rn
[] = "gator_cursesgwin_create"; /*Routine name */
184 struct gator_cursesgwin_params
*params
= (struct gator_cursesgwin_params
*)rock
;
185 struct gwin
*newgwin
; /*Ptr to new curses window */
186 struct gator_cursesgwin
*c_data
; /*Ptr to curses-specific data */
187 WINDOW
*newcursgwin
; /*Ptr to new curses window */
191 "[%s:%s] Allocating %" AFS_SIZET_FMT
" bytes for new gwin structure\n", mn
,
192 rn
, sizeof(struct gwin
));
193 newgwin
= malloc(sizeof(struct gwin
));
194 if (newgwin
== NULL
) {
196 "[%s:%s] Can't malloc() %" AFS_SIZET_FMT
" bytes for new gwin structure: Errno is %d\n",
197 mn
, rn
, sizeof(struct gwin
), errno
);
201 newgwin
->w_type
= GATOR_WIN_CURSES
;
202 newgwin
->w_x
= params
->gwin_params
.cr_x
;
203 newgwin
->w_y
= params
->gwin_params
.cr_y
;
204 newgwin
->w_width
= params
->gwin_params
.cr_width
;
205 newgwin
->w_height
= params
->gwin_params
.cr_height
;
206 newgwin
->w_changed
= 1;
207 newgwin
->w_op
= &curses_gwinops
;
208 newgwin
->w_parent
= params
->gwin_params
.cr_parentwin
;
212 "[%s:%s] Allocating %" AFS_SIZET_FMT
" bytes for curses window private space\n",
213 mn
, rn
, sizeof(struct gator_cursesgwin
));
214 c_data
= malloc(sizeof(struct gator_cursesgwin
));
215 if (c_data
== (struct gator_cursesgwin
*)0) {
217 "[%s:%s] Can't allocate %" AFS_SIZET_FMT
" bytes for curses window private space\n",
218 mn
, rn
, sizeof(struct gator_cursesgwin
));
223 newcursgwin
= newwin(newgwin
->w_height
, /*Number of lines */
224 newgwin
->w_width
, /*Number of columns */
225 newgwin
->w_y
, /*Beginning y value */
226 newgwin
->w_x
); /*Beginning x value */
227 if (newcursgwin
== (WINDOW
*) 0) {
229 "[%s:%s] Failed to create curses window via newwin()\n", mn
,
237 * Now, fill in the curses-specific window info.
239 c_data
->wp
= newcursgwin
;
240 c_data
->charwidth
= params
->charwidth
;
241 c_data
->charheight
= params
->charheight
;
242 c_data
->box_vertchar
= params
->box_vertchar
;
243 c_data
->box_horizchar
= params
->box_horizchar
;
246 * Plug in a frame at the top-level.
248 newgwin
->w_frame
= gtxframe_Create();
251 * Plug the curses private data into the generic window object, then
252 * return the new window's info.
254 newgwin
->w_data
= (int *)c_data
;
257 } /*gator_cursesgwin_create */
259 /*------------------------------------------------------------------------
260 * gator_cursesgwin_cleanup
263 * Clean up, probably right before the caller exits.
266 * struct gwin *gwp : Ptr to base window.
270 * Error value otherwise.
273 * Nothing interesting.
277 *------------------------------------------------------------------------*/
280 gator_cursesgwin_cleanup(struct gwin
*gwp
)
281 { /*gator_cursesgwin_cleanup */
283 static char rn
[] = "gator_cursesgwin_cleanup"; /*Routine name */
284 struct gator_cursesgwin
*cwp
; /*Curses private area ptr */
286 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
289 * Cleaning up in curses is extremely easy - one simple call. We also
290 * want to clear the screen before we go.
293 fprintf(stderr
, "[%s:%s] Calling wclear() on window at %p\n", mn
,
299 * Now, set the terminal back into normal mode.
304 fprintf(stderr
, "[%s:%s] Calling endwin()\n", mn
, rn
);
309 } /*gator_cursesgwin_cleanup */
311 /*------------------------------------------------------------------------
312 * gator_cursesgwin_box
315 * Draw a box around the given curses window.
318 * struct gwin *gwp : Ptr to the curses window to draw
323 * Error value otherwise.
326 * Nothing interesting.
330 *------------------------------------------------------------------------*/
333 gator_cursesgwin_box(struct gwin
*gwp
)
334 { /*gator_cursesgwin_box */
336 static char rn
[] = "gator_cursesgwin_box"; /*Routine name */
337 struct gator_cursesgwin
*cwp
; /*Ptr to curses private area */
339 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
341 fprintf(stderr
, "[%s:%s] Calling box() on window at %p\n", mn
, rn
,
343 box(cwp
->wp
, cwp
->box_vertchar
, cwp
->box_horizchar
);
347 } /*gator_cursesgwin_box */
349 /*------------------------------------------------------------------------
350 * gator_cursesgwin_clear
353 * Clear out the given curses window.
356 * struct gwin *gwp : Ptr to the curses window to clear out.
360 * Error value otherwise.
363 * Nothing interesting.
367 *------------------------------------------------------------------------*/
370 gator_cursesgwin_clear(struct gwin
*gwp
)
371 { /*gator_cursesgwin_clear */
373 static char rn
[] = "gator_cursesgwin_clear"; /*Routine name */
374 struct gator_cursesgwin
*cwp
; /*Ptr to curses private area */
377 * Clearing windows is very easy in curses; just one call will do it.
379 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
381 fprintf(stderr
, "[%s:%s] Calling wclear() on window at %p\n", mn
,
387 } /*gator_cursesgwin_clear */
389 /*------------------------------------------------------------------------
390 * gator_cursesgwin_destroy
393 * Destroy the given curses window.
396 * struct gwin *gwp : Ptr to the curses window to destroy.
400 * Error value otherwise.
403 * Nothing interesting.
407 *------------------------------------------------------------------------*/
410 gator_cursesgwin_destroy(struct gwin
*gwp
)
411 { /*gator_cursesgwin_destroy */
413 static char rn
[] = "gator_cursesgwin_destroy"; /*Routine name */
414 struct gator_cursesgwin
*cwp
; /*Ptr to curses private area */
416 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
418 fprintf(stderr
, "[%s:%s] Calling delwin() on window at %p\n", mn
,
424 } /*gator_cursesgwin_destroy */
426 /*------------------------------------------------------------------------
427 * gator_cursesgwin_display
430 * Display/redraw the given curses window.
433 * struct gwin *gwp : Ptr to the curses window to draw.
437 * Error value otherwise.
440 * Nothing interesting.
444 *------------------------------------------------------------------------*/
447 gator_cursesgwin_display(struct gwin
*gwp
)
448 { /*gator_cursesgwin_display */
450 struct gator_cursesgwin
*cwp
; /*Curses private area ptr */
452 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
454 wclear(cwp
->wp
); /* clear screen */
455 gtxframe_Display(gwp
->w_frame
, gwp
); /* display the frame */
456 wrefresh(cwp
->wp
); /* redraw the guy */
459 } /*gator_cursesgwin_display */
461 /*------------------------------------------------------------------------
462 * gator_cursesgwin_drawline
465 * Draw a line between two points in the given curses
469 * struct gwin *gwp : Ptr to the curses window in which
470 * the line is to be drawn.
471 * struct gwin_lineparams *params : Ptr to other params.
475 * Error value otherwise.
478 * Nothing interesting.
482 *------------------------------------------------------------------------*/
485 gator_cursesgwin_drawline(struct gwin
*gwp
, struct gwin_lineparams
*params
)
486 { /*gator_cursesgwin_drawline */
488 static char rn
[] = "gator_cursesgwin_drawline"; /*Routine name */
491 fprintf(stderr
, "[%s:%s] This routine is currently a no-op\n", mn
,
496 } /*gator_cursesgwin_drawline */
498 /*------------------------------------------------------------------------
499 * gator_cursesgwin_drawrectangle
502 * Draw a rectangle in the given curses window.
505 * struct gwin *gwp : Ptr to the curses window in which
506 * the rectangle is to be drawn.
507 * struct gwin_rectparams *params : Ptr to other params.
511 * Error value otherwise.
514 * Nothing interesting.
518 *------------------------------------------------------------------------*/
521 gator_cursesgwin_drawrectangle(struct gwin
*gwp
, struct gwin_rectparams
*params
)
522 { /*gator_cursesgwin_drawrectangle */
524 static char rn
[] = "gator_cursesgwin_drawrectangle"; /*Routine name */
527 fprintf(stderr
, "[%s:%s] This routine is currently a no-op\n", mn
,
532 } /*gator_cursesgwin_drawrectangle */
534 /*------------------------------------------------------------------------
535 * gator_cursesgwin_drawchar
538 * Draw a character in the given curses window.
541 * struct gwin *gwp : Ptr to the curses window in which
542 * the character is to be drawn.
543 * struct gwin_charparams *params : Ptr to other params.
547 * Error value otherwise.
550 * Nothing interesting.
554 *------------------------------------------------------------------------*/
557 gator_cursesgwin_drawchar(struct gwin
*gwp
, struct gwin_charparams
*params
)
558 { /*gator_cursesgwin_drawchar */
560 static char rn
[] = "gator_cursesgwin_drawchar"; /*Routine name */
561 struct gator_cursesgwin
*cwp
; /*Ptr to curses private area */
562 int curses_x
, curses_y
; /*Mapped x,y positions */
565 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
566 curses_x
= GATOR_MAP_X_TO_COL(cwp
, params
->x
);
567 curses_y
= GATOR_MAP_Y_TO_LINE(cwp
, params
->y
);
570 "[%s:%s] Drawing char '%c' on window at %p at (%d, %d) [line %d, column %d]%s\n",
571 mn
, rn
, params
->c
, cwp
->wp
, params
->x
, params
->y
, curses_y
,
572 curses_x
, (params
->highlight
? ", using standout mode" : ""));
573 wmove(cwp
->wp
, curses_y
, curses_x
);
574 if (params
->highlight
) {
575 code
=wstandout(cwp
->wp
);
579 waddch(cwp
->wp
, params
->c
);
580 if (params
->highlight
) {
581 code
=wstandend(cwp
->wp
);
588 } /*gator_cursesgwin_drawchar */
590 /*------------------------------------------------------------------------
591 * gator_cursesgwin_drawstring
594 * Draw a string in the given curses window.
597 * struct gwin *gwp : Ptr to the curses window in which
598 * the string is to be drawn.
599 * struct gwin_strparams *params : Ptr to other params.
603 * Error value otherwise.
606 * Nothing interesting.
610 *------------------------------------------------------------------------*/
613 gator_cursesgwin_drawstring(struct gwin
*gwp
, struct gwin_strparams
*params
)
614 { /*gator_cursesgwin_drawstring */
616 static char rn
[] = "gator_cursesgwin_drawstring"; /*Routine name */
617 struct gator_cursesgwin
*cwp
; /*Ptr to curses private area */
618 int curses_x
, curses_y
; /*Mapped x,y positions */
621 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
622 curses_x
= GATOR_MAP_X_TO_COL(cwp
, params
->x
);
623 curses_y
= GATOR_MAP_Y_TO_LINE(cwp
, params
->y
);
626 "[%s:%s] Drawing string '%s' on window at %p at (%d, %d) [line %d, column %d]%s\n",
627 mn
, rn
, params
->s
, cwp
->wp
, params
->x
, params
->y
, curses_y
,
628 curses_x
, (params
->highlight
? ", using standout mode" : ""));
629 wmove(cwp
->wp
, curses_y
, curses_x
);
630 if (params
->highlight
) {
631 code
=wstandout(cwp
->wp
);
635 waddstr(cwp
->wp
, params
->s
);
636 if (params
->highlight
) {
637 code
=wstandend(cwp
->wp
);
644 } /*gator_cursesgwin_drawstring */
646 /*------------------------------------------------------------------------
647 * gator_cursesgwin_invert
650 * Invert a region in the given curses window.
653 * struct gwin *gwp : Ptr to the curses window in which
654 * the inverted region lies.
655 * struct gwin_invparams *params : Ptr to other params.
659 * Error value otherwise.
662 * Nothing interesting.
666 *------------------------------------------------------------------------*/
669 gator_cursesgwin_invert(struct gwin
*gwp
, struct gwin_invparams
*params
)
670 { /*gator_cursesgwin_invert */
672 static char rn
[] = "gator_cursesgwin_invert"; /*Routine name */
675 fprintf(stderr
, "[%s:%s] This routine is currently a no-op\n", mn
,
680 } /*gator_cursesgwin_invert */
682 /*------------------------------------------------------------------------
683 * gator_cursesgwin_getchar
686 * Pick up a character from the given window.
689 * struct gwin *gwp : Ptr to the curses window to listen to.
692 * Value of the character read,
696 * Nothing interesting.
700 *------------------------------------------------------------------------*/
703 gator_cursesgwin_getchar(struct gwin
*gwp
)
704 { /*gator_cursesgwin_getchar */
706 return (getc(stdin
));
708 } /*gator_cursesgwin_getchar */
710 /*------------------------------------------------------------------------
711 * gator_cursesgwin_wait
714 * Wait until input is available.
717 * struct gwin *gwp : Ptr to the curses window to wait on.
721 * Error value otherwise.
724 * Nothing interesting.
728 *------------------------------------------------------------------------*/
731 gator_cursesgwin_wait(struct gwin
*gwp
)
732 { /*gator_cursesgwin_wait */
734 while (!LWP_WaitForKeystroke(-1));
738 } /*gator_cursesgwin_wait */
740 /*------------------------------------------------------------------------
741 * gator_cursesgwin_getdimensions
744 * Get the window's X,Y dimensions.
747 * struct gwin *gwp : Ptr to the curses window to examine.
748 * struct gwin_sizeparams *params : Ptr to the size params to set.
752 * Error value otherwise.
755 * Nothing interesting.
759 *------------------------------------------------------------------------*/
762 gator_cursesgwin_getdimensions(struct gwin
*gwp
, struct gwin_sizeparams
*aparms
)
763 { /*gator_cursesgwin_getdimensions */
765 struct gator_cursesgwin
*cwp
; /*Curses-specific data */
767 cwp
= (struct gator_cursesgwin
*)(gwp
->w_data
);
768 getmaxyx(cwp
->wp
, aparms
->maxy
, aparms
->maxx
);
772 } /*gator_cursesgwin_getdimensions */