1 /* Public Domain Curses */
5 RCSID("$Id: slk.c,v 1.61 2008/07/13 16:08:18 wmcbrine Exp $")
7 /*man-start**************************************************************
12 int slk_init(int fmt);
13 int slk_set(int labnum, const char *label, int justify);
14 int slk_refresh(void);
15 int slk_noutrefresh(void);
16 char *slk_label(int labnum);
18 int slk_restore(void);
20 int slk_attron(const chtype attrs);
21 int slk_attr_on(const attr_t attrs, void *opts);
22 int slk_attrset(const chtype attrs);
23 int slk_attr_set(const attr_t attrs, short color_pair, void *opts);
24 int slk_attroff(const chtype attrs);
25 int slk_attr_off(const attr_t attrs, void *opts);
26 int slk_color(short color_pair);
28 int slk_wset(int labnum, const wchar_t *label, int justify);
30 int PDC_mouse_in_slk(int y, int x);
31 void PDC_slk_free(void);
32 void PDC_slk_initialize(void);
34 wchar_t *slk_wlabel(int labnum)
37 These functions manipulate a window that contain Soft Label Keys
38 (SLK). To use the SLK functions, a call to slk_init() must be
39 made BEFORE initscr() or newterm(). slk_init() removes 1 or 2
40 lines from the useable screen, depending on the format selected.
42 The line(s) removed from the screen are used as a separate
43 window, in which SLKs are displayed.
45 slk_init() requires a single parameter which describes the
46 format of the SLKs as follows:
50 2 4-4-4 format (ncurses extension)
51 3 4-4-4 format with index line (ncurses extension)
53 55 5-5 format (pdcurses format)
55 slk_refresh(), slk_noutrefresh() and slk_touch() are analogous
56 to refresh(), noutrefresh() and touch().
59 All functions return OK on success and ERR on error.
61 Portability X/Open BSD SYS V
77 PDC_mouse_in_slk - - -
79 PDC_slk_initialize - - -
82 **man-end****************************************************************/
86 enum { LABEL_NORMAL
= 8, LABEL_EXTENDED
= 10, LABEL_NCURSES_EXTENDED
= 12 };
88 static int label_length
= 0;
89 static int labels
= 0;
90 static int label_fmt
= 0;
91 static int label_line
= 0;
92 static bool hidden
= FALSE
;
99 } *slk
= (struct SLK
*)NULL
;
101 /* slk_init() is the slk initialization routine.
102 This must be called before initscr().
104 label_fmt = 0, 1 or 55.
107 2 = 4-4-4 format (ncurses extension for PC 12 function keys)
108 3 = 4-4-4 format (ncurses extension for PC 12 function keys -
110 55 = 5 - 5 format (extended for PC, 10 function keys) */
112 int slk_init(int fmt
)
114 PDC_LOG(("slk_init() - called\n"));
121 case 0: /* 3 - 2 - 3 */
122 labels
= LABEL_NORMAL
;
126 labels
= LABEL_NORMAL
;
130 labels
= LABEL_NCURSES_EXTENDED
;
133 case 3: /* 4 4 4 with index */
134 labels
= LABEL_NCURSES_EXTENDED
;
138 labels
= LABEL_EXTENDED
;
147 slk
= calloc(labels
, sizeof(struct SLK
));
152 return slk
? OK
: ERR
;
155 /* draw a single button */
157 static void _drawone(int num
)
166 switch (slk
[num
].format
)
173 col
= (label_length
- slen
) / 2;
175 if (col
+ slen
> label_length
)
180 col
= label_length
- slen
;
183 wmove(SP
->slk_winptr
, label_line
, slk
[num
].start_col
);
185 for (i
= 0; i
< label_length
; ++i
)
186 waddch(SP
->slk_winptr
, (i
>= col
&& i
< (col
+ slen
)) ?
187 slk
[num
].label
[i
- col
] : ' ');
190 /* redraw each button */
192 static void _redraw(void)
196 for (i
= 0; i
< labels
; ++i
)
200 /* slk_set() Used to set a slk label to a string.
202 labnum = 1 - 8 (or 10) (number of the label)
203 label = string (8 or 7 bytes total), or NULL
204 justify = 0 : left, 1 : center, 2 : right */
206 int slk_set(int labnum
, const char *label
, int justify
)
211 PDC_mbstowcs(wlabel
, label
, 31);
212 return slk_wset(labnum
, wlabel
, justify
);
214 PDC_LOG(("slk_set() - called\n"));
216 if (labnum
< 1 || labnum
> labels
|| justify
< 0 || justify
> 2)
221 if (!label
|| !(*label
))
223 /* Clear the label */
225 *slk
[labnum
].label
= 0;
226 slk
[labnum
].format
= 0;
233 /* Skip leading spaces */
235 while (label
[j
] == ' ')
240 for (i
= 0; i
< label_length
; i
++)
242 chtype ch
= label
[i
+ j
];
244 slk
[labnum
].label
[i
] = ch
;
250 /* Drop trailing spaces */
252 while ((i
+ j
) && (label
[i
+ j
- 1] == ' '))
255 slk
[labnum
].label
[i
] = 0;
256 slk
[labnum
].format
= justify
;
266 int slk_refresh(void)
268 PDC_LOG(("slk_refresh() - called\n"));
270 return (slk_noutrefresh() == ERR
) ? ERR
: doupdate();
273 int slk_noutrefresh(void)
275 PDC_LOG(("slk_noutrefresh() - called\n"));
277 return wnoutrefresh(SP
->slk_winptr
);
280 char *slk_label(int labnum
)
282 static char temp
[33];
284 wchar_t *wtemp
= slk_wlabel(labnum
);
286 PDC_wcstombs(temp
, wtemp
, 32);
291 PDC_LOG(("slk_label() - called\n"));
293 if (labnum
< 1 || labnum
> labels
)
296 for (i
= 0, p
= slk
[labnum
- 1].label
; *p
; i
++)
306 PDC_LOG(("slk_clear() - called\n"));
309 werase(SP
->slk_winptr
);
310 return wrefresh(SP
->slk_winptr
);
313 int slk_restore(void)
315 PDC_LOG(("slk_restore() - called\n"));
319 return wrefresh(SP
->slk_winptr
);
324 PDC_LOG(("slk_touch() - called\n"));
326 return touchwin(SP
->slk_winptr
);
329 int slk_attron(const chtype attrs
)
333 PDC_LOG(("slk_attron() - called\n"));
335 rc
= wattron(SP
->slk_winptr
, attrs
);
341 int slk_attr_on(const attr_t attrs
, void *opts
)
343 PDC_LOG(("slk_attr_on() - called\n"));
345 return slk_attron(attrs
);
348 int slk_attroff(const chtype attrs
)
352 PDC_LOG(("slk_attroff() - called\n"));
354 rc
= wattroff(SP
->slk_winptr
, attrs
);
360 int slk_attr_off(const attr_t attrs
, void *opts
)
362 PDC_LOG(("slk_attr_off() - called\n"));
364 return slk_attroff(attrs
);
367 int slk_attrset(const chtype attrs
)
371 PDC_LOG(("slk_attrset() - called\n"));
373 rc
= wattrset(SP
->slk_winptr
, attrs
);
379 int slk_color(short color_pair
)
383 PDC_LOG(("slk_color() - called\n"));
385 rc
= wcolor_set(SP
->slk_winptr
, color_pair
, NULL
);
391 int slk_attr_set(const attr_t attrs
, short color_pair
, void *opts
)
393 PDC_LOG(("slk_attr_set() - called\n"));
395 return slk_attrset(attrs
| COLOR_PAIR(color_pair
));
398 static void _slk_calc(void)
400 int i
, center
, col
= 0;
401 label_length
= COLS
/ labels
;
403 if (label_length
> 31)
408 case 0: /* 3 - 2 - 3 F-Key layout */
412 slk
[0].start_col
= col
;
413 slk
[1].start_col
= (col
+= label_length
);
414 slk
[2].start_col
= (col
+= label_length
);
418 slk
[3].start_col
= center
- label_length
+ 1;
419 slk
[4].start_col
= center
+ 1;
421 col
= COLS
- (label_length
* 3) + 1;
423 slk
[5].start_col
= col
;
424 slk
[6].start_col
= (col
+= label_length
);
425 slk
[7].start_col
= (col
+= label_length
);
428 case 1: /* 4 - 4 F-Key layout */
430 for (i
= 0; i
< 8; i
++)
432 slk
[i
].start_col
= col
;
436 col
= COLS
- (label_length
* 4) + 1;
441 case 2: /* 4 4 4 F-Key layout */
442 case 3: /* 4 4 4 F-Key layout with index */
444 for (i
= 0; i
< 4; i
++)
446 slk
[i
].start_col
= col
;
452 slk
[4].start_col
= center
- (label_length
* 2) + 1;
453 slk
[5].start_col
= center
- label_length
- 1;
454 slk
[6].start_col
= center
+ 1;
455 slk
[7].start_col
= center
+ label_length
+ 1;
457 col
= COLS
- (label_length
* 4) + 1;
459 for (i
= 8; i
< 12; i
++)
461 slk
[i
].start_col
= col
;
467 default: /* 5 - 5 F-Key layout */
469 for (i
= 0; i
< 10; i
++)
471 slk
[i
].start_col
= col
;
475 col
= COLS
- (label_length
* 5) + 1;
481 /* make sure labels are all in window */
486 void PDC_slk_initialize(void)
500 if ( !(SP
->slk_winptr
= newwin(SP
->slklines
, COLS
,
501 LINES
- SP
->slklines
, 0)) )
504 wattrset(SP
->slk_winptr
, A_REVERSE
);
509 /* if we have an index line, display it now */
516 save_attr
= SP
->slk_winptr
->_attrs
;
517 wattrset(SP
->slk_winptr
, A_NORMAL
);
518 wmove(SP
->slk_winptr
, 0, 0);
519 whline(SP
->slk_winptr
, 0, COLS
);
521 for (i
= 0; i
< labels
; i
++)
522 mvwprintw(SP
->slk_winptr
, 0, slk
[i
].start_col
, "F%d", i
+ 1);
524 SP
->slk_winptr
->_attrs
= save_attr
;
527 touchwin(SP
->slk_winptr
);
531 void PDC_slk_free(void)
537 delwin(SP
->slk_winptr
);
538 SP
->slk_winptr
= (WINDOW
*)NULL
;
542 slk
= (struct SLK
*)NULL
;
552 int PDC_mouse_in_slk(int y
, int x
)
556 PDC_LOG(("PDC_mouse_in_slk() - called: y->%d x->%d\n", y
, x
));
558 /* If the line on which the mouse was clicked is NOT the last line
559 of the screen, we are not interested in it. */
561 if (!slk
|| !SP
->slk_winptr
|| (y
!= SP
->slk_winptr
->_begy
+ label_line
))
564 for (i
= 0; i
< labels
; i
++)
565 if (x
>= slk
[i
].start_col
&& x
< (slk
[i
].start_col
+ label_length
))
572 int slk_wset(int labnum
, const wchar_t *label
, int justify
)
574 PDC_LOG(("slk_wset() - called\n"));
576 if (labnum
< 1 || labnum
> labels
|| justify
< 0 || justify
> 2)
581 if (!label
|| !(*label
))
583 /* Clear the label */
585 *slk
[labnum
].label
= 0;
586 slk
[labnum
].format
= 0;
593 /* Skip leading spaces */
595 while (label
[j
] == L
' ')
600 for (i
= 0; i
< label_length
; i
++)
602 chtype ch
= label
[i
+ j
];
604 slk
[labnum
].label
[i
] = ch
;
610 /* Drop trailing spaces */
612 while ((i
+ j
) && (label
[i
+ j
- 1] == L
' '))
615 slk
[labnum
].label
[i
] = 0;
616 slk
[labnum
].format
= justify
;
625 wchar_t *slk_wlabel(int labnum
)
627 static wchar_t temp
[33];
631 PDC_LOG(("slk_wlabel() - called\n"));
633 if (labnum
< 1 || labnum
> labels
)
636 for (i
= 0, p
= slk
[labnum
- 1].label
; *p
; i
++)