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 <afs/param.h>
20 #if defined(AFS_HPUX110_ENV) && !defined(__HP_CURSES)
25 #include <curses.h> /*Curses library*/
27 #include <sys/types.h>
29 #if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV)
36 #include "gtxcurseswin.h" /*Interface definition*/
37 #include "gtxobjects.h"
40 extern int errno; /* everybody else puts it in errno.h */
42 int curses_debug; /*Is debugging turned on?*/
43 static char mn[] = "gator_curseswindows"; /*Module name*/
46 * Version of standard operations for a curses window.
48 struct gwinops curses_gwinops = {
50 gator_cursesgwin_clear,
51 gator_cursesgwin_destroy,
52 gator_cursesgwin_display,
53 gator_cursesgwin_drawline,
54 gator_cursesgwin_drawrectangle,
55 gator_cursesgwin_drawchar,
56 gator_cursesgwin_drawstring,
57 gator_cursesgwin_invert,
58 gator_cursesgwin_getchar,
59 gator_cursesgwin_getdimensions,
60 gator_cursesgwin_wait,
63 struct gwinbaseops gator_curses_gwinbops = {
64 gator_cursesgwin_create,
65 gator_cursesgwin_cleanup,
70 * Macros to map pixel positions to row & column positions.
71 * (Note: for now, they are the identity function!!)
73 #define GATOR_MAP_X_TO_COL(w, x) (x)
74 #define GATOR_MAP_Y_TO_LINE(w, y) (y)
76 /*------------------------------------------------------------------------
77 * gator_cursesgwin_init
80 * Initialize the curses window package.
83 * int adebug: Is debugging turned on?
87 * Error value otherwise.
90 * Nothing interesting.
94 *------------------------------------------------------------------------*/
96 int gator_cursesgwin_init(adebug)
99 { /*gator_cursesgwin_init*/
101 static char rn[] = "gator_cursesgwin_init"; /*Routine name*/
102 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data*/
105 * Remember if we'll be doing debugging, then init the curses package.
107 curses_debug = adebug;
110 fprintf(stderr, "[%s:%s] Calling initscr()\n", mn, rn);
114 * Fill out the base window structure for curses.
117 fprintf(stderr, "[%s:%s] Allocating %d bytes for curses window private space in base window\n", mn, rn, sizeof(struct gator_cursesgwin));
118 c_data = (struct gator_cursesgwin *) malloc(sizeof(struct gator_cursesgwin));
119 if (c_data == (struct gator_cursesgwin *)0){
120 fprintf(stderr, "[%s:%s] Can't allocate %d bytes for curses window private space in base window\n", mn, rn, sizeof(struct gator_cursesgwin));
125 * Fill in the curses-specific base window info. We assume that chars are 8x13.
128 c_data->charwidth = 8;
129 c_data->charheight = 13;
130 c_data->box_vertchar = '|';
131 c_data->box_horizchar = '-';
134 * Fill in the generic base window info.
136 gator_basegwin.w_type = GATOR_WIN_CURSES;
137 gator_basegwin.w_x = 0;
138 gator_basegwin.w_y = 0;
139 gator_basegwin.w_width = c_data->charwidth * COLS;
140 gator_basegwin.w_height = c_data->charheight * LINES;
141 gator_basegwin.w_changed = 0;
142 gator_basegwin.w_op = &curses_gwinops;
143 gator_basegwin.w_parent = (struct gwin *)0;
146 * Plug the private data into the generic part of the base window.
148 gator_basegwin.w_data = (int *)c_data;
151 * Now, set the terminal into the right mode for handling input
153 raw(); /* curses raw mode */
156 gator_basegwin.w_frame = gtxframe_Create();
159 * Clear out the screen and return the good news.
161 wclear(((struct gator_cursesgwin *)(gator_basegwin.w_data))->wp);
164 } /*gator_cursesgwin_init*/
166 /*------------------------------------------------------------------------
167 * gator_cursesgwin_create
170 * Create a curses window (incorrectly).
173 * struct gator_cursesgwin_params *params : Ptr to creation parameters.
176 * Ptr to the created curses window if successful,
177 * Null ptr otherwise.
180 * Nothing interesting.
184 *------------------------------------------------------------------------*/
186 struct gwin *gator_cursesgwin_create(params)
187 struct gator_cursesgwin_params *params;
189 { /*gator_cursesgwin_create*/
191 static char rn[] = "gator_cursesgwin_create"; /*Routine name*/
192 struct gwin *newgwin; /*Ptr to new curses window*/
193 struct gator_cursesgwin *c_data; /*Ptr to curses-specific data*/
194 WINDOW *newcursgwin; /*Ptr to new curses window*/
197 fprintf(stderr, "[%s:%s] Allocating %d bytes for new gwin structure\n", mn, rn, sizeof(struct gwin));
198 newgwin = (struct gwin *) malloc(sizeof(struct gwin));
199 if (newgwin == (struct gwin *)0) {
200 fprintf(stderr, "[%s:%s] Can't malloc() %d bytes for new gwin structure: Errno is %d\n", mn, rn, sizeof(struct gwin), errno);
201 return((struct gwin *)0);
204 newgwin->w_type = GATOR_WIN_CURSES;
205 newgwin->w_x = params->gwin_params.cr_x;
206 newgwin->w_y = params->gwin_params.cr_y;
207 newgwin->w_width = params->gwin_params.cr_width;
208 newgwin->w_height = params->gwin_params.cr_height;
209 newgwin->w_changed = 1;
210 newgwin->w_op = &curses_gwinops;
211 newgwin->w_parent = params->gwin_params.cr_parentwin;
214 fprintf(stderr, "[%s:%s] Allocating %d bytes for curses window private space\n", mn, rn, sizeof(struct gator_cursesgwin));
215 c_data = (struct gator_cursesgwin *) malloc(sizeof(struct gator_cursesgwin));
216 if (c_data == (struct gator_cursesgwin *)0){
217 fprintf(stderr, "[%s:%s] Can't allocate %d bytes for curses window private space\n", mn, rn, sizeof(struct gator_cursesgwin));
219 return((struct gwin *)0);
222 newcursgwin = newwin(newgwin->w_height, /*Number of lines*/
223 newgwin->w_width, /*Number of columns*/
224 newgwin->w_y, /*Beginning y value*/
225 newgwin->w_x); /*Beginning x value*/
226 if (newcursgwin == (WINDOW *)0) {
227 fprintf(stderr, "[%s:%s] Failed to create curses window via newwin()\n", mn, rn);
230 return((struct gwin *)0);
234 * Now, fill in the curses-specific window info.
236 c_data->wp = newcursgwin;
237 c_data->charwidth = params->charwidth;
238 c_data->charheight = params->charheight;
239 c_data->box_vertchar = params->box_vertchar;
240 c_data->box_horizchar = params->box_horizchar;
243 * Plug in a frame at the top-level.
245 newgwin->w_frame = gtxframe_Create();
248 * Plug the curses private data into the generic window object, then
249 * return the new window's info.
251 newgwin->w_data = (int *) c_data;
254 } /*gator_cursesgwin_create*/
256 /*------------------------------------------------------------------------
257 * gator_cursesgwin_cleanup
260 * Clean up, probably right before the caller exits.
263 * struct gwin *gwp : Ptr to base window.
267 * Error value otherwise.
270 * Nothing interesting.
274 *------------------------------------------------------------------------*/
276 int gator_cursesgwin_cleanup(gwp)
279 { /*gator_cursesgwin_cleanup*/
281 static char rn[] = "gator_cursesgwin_cleanup"; /*Routine name*/
282 struct gator_cursesgwin *cwp; /*Curses private area ptr*/
284 cwp = (struct gator_cursesgwin *)(gwp->w_data);
287 * Cleaning up in curses is extremely easy - one simple call. We also
288 * want to clear the screen before we go.
291 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn, rn, cwp->wp);
296 * Now, set the terminal back into normal mode.
301 fprintf(stderr, "[%s:%s] Calling endwin()\n", mn, rn);
306 } /*gator_cursesgwin_cleanup*/
308 /*------------------------------------------------------------------------
309 * gator_cursesgwin_box
312 * Draw a box around the given curses window.
315 * struct gwin *gwp : Ptr to the curses window to draw
320 * Error value otherwise.
323 * Nothing interesting.
327 *------------------------------------------------------------------------*/
329 int gator_cursesgwin_box(gwp)
332 { /*gator_cursesgwin_box*/
334 static char rn[] = "gator_cursesgwin_box"; /*Routine name*/
335 struct gator_cursesgwin *cwp; /*Ptr to curses private area*/
337 cwp = (struct gator_cursesgwin *)(gwp->w_data);
339 fprintf(stderr, "[%s:%s] Calling box() on window at 0x%x\n", mn, rn, cwp->wp);
340 box(cwp->wp, cwp->box_vertchar, cwp->box_horizchar);
344 } /*gator_cursesgwin_box*/
346 /*------------------------------------------------------------------------
347 * gator_cursesgwin_clear
350 * Clear out the given curses window.
353 * struct gwin *gwp : Ptr to the curses window to clear out.
357 * Error value otherwise.
360 * Nothing interesting.
364 *------------------------------------------------------------------------*/
366 int gator_cursesgwin_clear(gwp)
369 { /*gator_cursesgwin_clear*/
371 static char rn[] = "gator_cursesgwin_clear"; /*Routine name*/
372 struct gator_cursesgwin *cwp; /*Ptr to curses private area*/
375 * Clearing windows is very easy in curses; just one call will do it.
377 cwp = (struct gator_cursesgwin *)(gwp->w_data);
379 fprintf(stderr, "[%s:%s] Calling wclear() on window at 0x%x\n", mn, rn, cwp->wp);
384 } /*gator_cursesgwin_clear*/
386 /*------------------------------------------------------------------------
387 * gator_cursesgwin_destroy
390 * Destroy the given curses window.
393 * struct gwin *gwp : Ptr to the curses window to destroy.
397 * Error value otherwise.
400 * Nothing interesting.
404 *------------------------------------------------------------------------*/
406 int gator_cursesgwin_destroy(gwp)
409 { /*gator_cursesgwin_destroy*/
411 static char rn[] = "gator_cursesgwin_destroy"; /*Routine name*/
412 struct gator_cursesgwin *cwp; /*Ptr to curses private area*/
414 cwp = (struct gator_cursesgwin *)(gwp->w_data);
416 fprintf(stderr, "[%s:%s] Calling delwin() on window at 0x%x\n", mn, rn, cwp->wp);
421 } /*gator_cursesgwin_destroy*/
423 /*------------------------------------------------------------------------
424 * gator_cursesgwin_display
427 * Display/redraw the given curses window.
430 * struct gwin *gwp : Ptr to the curses window to draw.
434 * Error value otherwise.
437 * Nothing interesting.
441 *------------------------------------------------------------------------*/
443 int gator_cursesgwin_display(gwp)
446 { /*gator_cursesgwin_display*/
448 struct gator_cursesgwin *cwp; /*Curses private area ptr*/
450 cwp = (struct gator_cursesgwin *)(gwp->w_data);
452 wclear(cwp->wp); /* clear screen */
453 gtxframe_Display(gwp->w_frame, gwp); /* display the frame */
454 wrefresh(cwp->wp); /* redraw the guy */
457 } /*gator_cursesgwin_display*/
459 /*------------------------------------------------------------------------
460 * gator_cursesgwin_drawline
463 * Draw a line between two points in the given curses
467 * struct gwin *gwp : Ptr to the curses window in which
468 * the line is to be drawn.
469 * struct gwin_lineparams *params : Ptr to other params.
473 * Error value otherwise.
476 * Nothing interesting.
480 *------------------------------------------------------------------------*/
482 int gator_cursesgwin_drawline(gwp, params)
484 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, rn);
495 } /*gator_cursesgwin_drawline*/
497 /*------------------------------------------------------------------------
498 * gator_cursesgwin_drawrectangle
501 * Draw a rectangle in the given curses window.
504 * struct gwin *gwp : Ptr to the curses window in which
505 * the rectangle is to be drawn.
506 * struct gwin_rectparams *params : Ptr to other params.
510 * Error value otherwise.
513 * Nothing interesting.
517 *------------------------------------------------------------------------*/
519 int gator_cursesgwin_drawrectangle(gwp, params)
521 struct gwin_rectparams *params;
523 { /*gator_cursesgwin_drawrectangle*/
525 static char rn[] = "gator_cursesgwin_drawrectangle"; /*Routine name*/
528 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn, rn);
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 *------------------------------------------------------------------------*/
556 int gator_cursesgwin_drawchar(gwp, params)
558 struct gwin_charparams *params;
560 { /*gator_cursesgwin_drawchar*/
562 static char rn[] = "gator_cursesgwin_drawchar"; /*Routine name*/
563 struct gator_cursesgwin *cwp; /*Ptr to curses private area*/
564 int curses_x, curses_y; /*Mapped x,y positions*/
566 cwp = (struct gator_cursesgwin *)(gwp->w_data);
567 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
568 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
570 fprintf(stderr, "[%s:%s] Drawing char '%c' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n", mn, rn, params->c, cwp->wp, params->x, params->y, curses_y, curses_x, (params->highlight ? ", using standout mode" : ""));
571 wmove(cwp->wp, curses_y, curses_x);
572 if (params->highlight)
574 waddch(cwp->wp, params->c);
575 if (params->highlight)
580 } /*gator_cursesgwin_drawchar*/
582 /*------------------------------------------------------------------------
583 * gator_cursesgwin_drawstring
586 * Draw a string in the given curses window.
589 * struct gwin *gwp : Ptr to the curses window in which
590 * the string is to be drawn.
591 * struct gwin_strparams *params : Ptr to other params.
595 * Error value otherwise.
598 * Nothing interesting.
602 *------------------------------------------------------------------------*/
604 int gator_cursesgwin_drawstring(gwp, params)
606 struct gwin_strparams *params;
608 { /*gator_cursesgwin_drawstring*/
610 static char rn[] = "gator_cursesgwin_drawstring"; /*Routine name*/
611 struct gator_cursesgwin *cwp; /*Ptr to curses private area*/
612 int curses_x, curses_y; /*Mapped x,y positions*/
614 cwp = (struct gator_cursesgwin *)(gwp->w_data);
615 curses_x = GATOR_MAP_X_TO_COL(cwp, params->x);
616 curses_y = GATOR_MAP_Y_TO_LINE(cwp, params->y);
618 fprintf(stderr, "[%s:%s] Drawing string '%s' on window at 0x%x at (%d, %d) [line %d, column %d]%s\n", mn, rn, params->s, cwp->wp, params->x, params->y, curses_y, curses_x, (params->highlight ? ", using standout mode" : ""));
619 wmove(cwp->wp, curses_y, curses_x);
620 if (params->highlight)
622 waddstr(cwp->wp, params->s);
623 if (params->highlight)
628 } /*gator_cursesgwin_drawstring*/
630 /*------------------------------------------------------------------------
631 * gator_cursesgwin_invert
634 * Invert a region in the given curses window.
637 * struct gwin *gwp : Ptr to the curses window in which
638 * the inverted region lies.
639 * struct gwin_invparams *params : Ptr to other params.
643 * Error value otherwise.
646 * Nothing interesting.
650 *------------------------------------------------------------------------*/
652 int gator_cursesgwin_invert(gwp, params)
654 struct gwin_invparams *params;
656 { /*gator_cursesgwin_invert*/
658 static char rn[] = "gator_cursesgwin_invert"; /*Routine name*/
661 fprintf(stderr, "[%s:%s] This routine is currently a no-op\n", mn, rn);
665 } /*gator_cursesgwin_invert*/
667 /*------------------------------------------------------------------------
668 * gator_cursesgwin_getchar
671 * Pick up a character from the given window.
674 * struct gwin *gwp : Ptr to the curses window to listen to.
677 * Value of the character read,
681 * Nothing interesting.
685 *------------------------------------------------------------------------*/
687 int gator_cursesgwin_getchar(gwp)
690 { /*gator_cursesgwin_getchar*/
694 } /*gator_cursesgwin_getchar*/
696 /*------------------------------------------------------------------------
697 * gator_cursesgwin_wait
700 * Wait until input is available.
703 * struct gwin *gwp : Ptr to the curses window to wait on.
707 * Error value otherwise.
710 * Nothing interesting.
714 *------------------------------------------------------------------------*/
716 int gator_cursesgwin_wait(gwp)
719 { /*gator_cursesgwin_wait*/
721 while (!LWP_WaitForKeystroke(-1));
725 } /*gator_cursesgwin_wait*/
727 /*------------------------------------------------------------------------
728 * gator_cursesgwin_getdimensions
731 * Get the window's X,Y dimensions.
734 * struct gwin *gwp : Ptr to the curses window to examine.
735 * struct gwin_sizeparams *params : Ptr to the size params to set.
739 * Error value otherwise.
742 * Nothing interesting.
746 *------------------------------------------------------------------------*/
748 int gator_cursesgwin_getdimensions(gwp, aparms)
749 struct gwin_sizeparams *aparms;
752 { /*gator_cursesgwin_getdimensions*/
754 struct gator_cursesgwin *cwp; /*Curses-specific data*/
756 cwp = (struct gator_cursesgwin *)(gwp->w_data);
757 aparms->maxx = cwp->wp->_maxx;
758 aparms->maxy = cwp->wp->_maxy;
762 } /*gator_cursesgwin_getdimensions*/