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;