11 * Soft label key functions
14 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL
);
16 #define MIN_SPACE_SIZE 2
18 #define SLK_MAX_LABEL_LEN 8
20 #define SLK_MAX_NUM_LABELS 12
22 #define SLK_MAX_NUM_SPACES 2
26 char label
[SLK_MAX_LABEL_LEN
];
27 /* Format of soft label
35 struct _softlabelkeys
{
36 struct _softlabel fkeys
[SLK_MAX_NUM_LABELS
];
38 /* Soft label layout format
42 3: 4-4-4 with index line
45 unsigned int max_label_len
;
46 unsigned int maj_space_len
;
47 unsigned int num_labels
;
48 unsigned int num_spaces
;
49 unsigned int spaces
[SLK_MAX_NUM_SPACES
];
50 struct cursor_pos saved_cursor
;
55 static struct _softlabelkeys
*slks
;
58 I either need to break the primitives here, or write a collection of
59 functions specifically for SLKs that directly access the screen
60 functions - since this technically isn't part of stdscr, I think
64 static void _enter_slk ( void ) {
65 _store_curs_pos ( stdscr
, &slks
->saved_cursor
);
66 wattr_get ( stdscr
, &slks
->saved_attrs
, &slks
->saved_pair
, NULL
);
68 wmove ( stdscr
, LINES
, 0 );
69 wattrset ( stdscr
, slks
->attrs
);
72 static void _leave_slk ( void ) {
74 wattr_set ( stdscr
, slks
->saved_attrs
, slks
->saved_pair
, NULL
);
75 _restore_curs_pos ( stdscr
, &slks
->saved_cursor
);
78 static void _print_label ( struct _softlabel sl
) {
80 char str
[SLK_MAX_LABEL_LEN
+ 1];
82 assert ( slks
->max_label_len
<= SLK_MAX_LABEL_LEN
);
85 // protect against gaps in the soft label keys array
86 if ( sl
.label
== NULL
) {
87 memset( str
, space_ch
, (size_t)(slks
->max_label_len
) );
89 /* we need to pad the label with varying amounts of leading
90 pad depending on the format of the label */
92 memset( str
, space_ch
,
93 (size_t)(slks
->max_label_len
94 - strlen(sl
.label
)) / 2 );
97 memset( str
, space_ch
,
98 (size_t)(slks
->max_label_len
99 - strlen(sl
.label
)) );
101 strcat(str
,sl
.label
);
104 memset(str
+strlen(str
), space_ch
,
105 (size_t)(slks
->max_label_len
- strlen(str
)) );
108 // print the formatted label
109 _wputstr ( stdscr
, str
, NOWRAP
, slks
->max_label_len
);
113 * Return the attribute used for the soft function keys
115 * @ret attrs the current attributes of the soft function keys
117 attr_t
slk_attr ( void ) {
118 return ( slks
== NULL ?
0 : slks
->attrs
);
122 * Turn off soft function key attributes
124 * @v attrs attribute bit mask
125 * @ret rc return status code
127 int slk_attroff ( const chtype attrs
) {
130 slks
->attrs
&= ~( attrs
& A_ATTRIBUTES
);
135 * Turn on soft function key attributes
137 * @v attrs attribute bit mask
138 * @ret rc return status code
140 int slk_attron ( const chtype attrs
) {
143 slks
->attrs
|= ( attrs
& A_ATTRIBUTES
);
148 * Set soft function key attributes
150 * @v attrs attribute bit mask
151 * @ret rc return status code
153 int slk_attrset ( const chtype attrs
) {
156 slks
->attrs
= ( attrs
& A_ATTRIBUTES
);
161 * Turn off soft function key attributes
163 * @v attrs attribute bit mask
164 * @v *opts undefined (for future implementation)
165 * @ret rc return status code
167 int slk_attr_off ( const attr_t attrs
, void *opts __unused
) {
168 return slk_attroff( attrs
);
172 * Turn on soft function key attributes
174 * @v attrs attribute bit mask
175 * @v *opts undefined (for future implementation)
176 * @ret rc return status code
178 int slk_attr_on ( attr_t attrs
, void *opts __unused
) {
179 return slk_attron( attrs
);
183 * Set soft function key attributes
185 * @v attrs attribute bit mask
186 * @v colour_pair_number colour pair integer
187 * @v *opts undefined (for future implementation)
188 * @ret rc return status code
190 int slk_attr_set ( const attr_t attrs
, short colour_pair_number
,
191 void *opts __unused
) {
195 if ( ( unsigned short )colour_pair_number
> COLORS
)
198 slks
->attrs
= ( (unsigned short)colour_pair_number
<< CPAIR_SHIFT
) |
199 ( attrs
& A_ATTRIBUTES
);
204 * Clear the soft function key labels from the screen
206 * @ret rc return status code
208 int slk_clear ( void ) {
213 wclrtoeol ( stdscr
);
220 * Set soft label colour pair
222 int slk_colour ( short colour_pair_number
) {
225 if ( ( unsigned short )colour_pair_number
> COLORS
)
228 slks
->attrs
= ( (unsigned short)colour_pair_number
<< CPAIR_SHIFT
)
229 | ( slks
->attrs
& A_ATTRIBUTES
);
235 * Initialise the soft function keys
237 * @v fmt format of keys
238 * @ret rc return status code
240 int slk_init ( int fmt
) {
241 unsigned short nmaj
, nmin
, nblocks
, available_width
;
243 if ( (unsigned)fmt
> 3 ) {
247 /* There seems to be no API call to free this data structure... */
249 slks
= calloc(1,sizeof(*slks
));
253 slks
->attrs
= A_DEFAULT
;
257 nblocks
= 8; nmaj
= 2; nmin
= 5;
258 slks
->spaces
[0] = 2; slks
->spaces
[1] = 4;
261 nblocks
= 8; nmaj
= 1; nmin
= 6;
265 // same allocations as format 3
267 nblocks
= 12; nmaj
= 2; nmin
= 9;
268 slks
->spaces
[0] = 3; slks
->spaces
[1] = 7;
271 nblocks
= 0; nmaj
= 0; nmin
= 0;
275 // determine maximum label length and major space size
276 available_width
= COLS
- ( ( MIN_SPACE_SIZE
* nmaj
) + nmin
);
277 slks
->max_label_len
= available_width
/ nblocks
;
278 slks
->maj_space_len
= MIN_SPACE_SIZE
+
279 ( available_width
% nblocks
) / nmaj
;
280 slks
->num_spaces
= nmaj
;
281 slks
->num_labels
= nblocks
;
283 // strip a line from the screen
290 * Return the label for the specified soft key
292 * @v labnum soft key identifier
293 * @ret label return label
295 char* slk_label ( int labnum
) {
299 return slks
->fkeys
[labnum
].label
;
303 * Restore soft function key labels to the screen
305 * @ret rc return status code
307 int slk_restore ( void ) {
308 unsigned int i
, j
, pos_x
,
309 *next_space
, *last_space
;
319 space_ch
= (chtype
)' ' | slks
->attrs
;
320 next_space
= &(slks
->spaces
[0]);
321 last_space
= &(slks
->spaces
[slks
->num_spaces
-1]);
323 for ( i
= 0; i
< slks
->num_labels
; i
++ ) {
324 _print_label( slks
->fkeys
[i
] );
325 pos_x
+= slks
->max_label_len
;
327 if ( i
== *next_space
) {
328 for ( j
= 0; j
< slks
->maj_space_len
; j
++, pos_x
++ )
329 _wputch ( stdscr
, space_ch
, NOWRAP
);
330 if ( next_space
< last_space
)
334 _wputch ( stdscr
, space_ch
, NOWRAP
);
345 * Configure specified soft key
347 * @v labnum soft label position to configure
348 * @v *label string to use as soft key label
349 * @v fmt justification format of label
350 * @ret rc return status code
352 int slk_set ( int labnum
, const char *label
, int fmt
) {
355 if ( (unsigned short)labnum
>= slks
->num_labels
)
357 if ( (unsigned short)fmt
>= 3 )
360 strncpy(slks
->fkeys
[labnum
].label
, label
,
361 sizeof(slks
->fkeys
[labnum
].label
));
362 slks
->fkeys
[labnum
].fmt
= fmt
;