11 * Soft label key functions
14 #define MIN_SPACE_SIZE 2
16 #define SLK_MAX_LABEL_LEN 8
18 #define SLK_MAX_NUM_LABELS 12
20 #define SLK_MAX_NUM_SPACES 2
24 char label[SLK_MAX_LABEL_LEN];
25 /* Format of soft label
33 struct _softlabelkeys {
34 struct _softlabel fkeys[SLK_MAX_NUM_LABELS];
36 /* Soft label layout format
40 3: 4-4-4 with index line
43 unsigned int max_label_len;
44 unsigned int maj_space_len;
45 unsigned int num_labels;
46 unsigned int num_spaces;
47 unsigned int spaces[SLK_MAX_NUM_SPACES];
48 struct cursor_pos saved_cursor;
53 static struct _softlabelkeys *slks;
56 I either need to break the primitives here, or write a collection of
57 functions specifically for SLKs that directly access the screen
58 functions - since this technically isn't part of stdscr, I think
62 static void _enter_slk ( void ) {
63 _store_curs_pos ( stdscr, &slks->saved_cursor );
64 wattr_get ( stdscr, &slks->saved_attrs, &slks->saved_pair, NULL );
66 wmove ( stdscr, LINES, 0 );
67 wattrset ( stdscr, slks->attrs );
70 static void _leave_slk ( void ) {
72 wattr_set ( stdscr, slks->saved_attrs, slks->saved_pair, NULL );
73 _restore_curs_pos ( stdscr, &slks->saved_cursor );
76 static void _print_label ( struct _softlabel sl ) {
78 char str[SLK_MAX_LABEL_LEN + 1];
80 assert ( slks->max_label_len <= SLK_MAX_LABEL_LEN );
83 // protect against gaps in the soft label keys array
84 if ( sl.label == NULL ) {
85 memset( str, space_ch, (size_t)(slks->max_label_len) );
87 /* we need to pad the label with varying amounts of leading
88 pad depending on the format of the label */
90 memset( str, space_ch,
91 (size_t)(slks->max_label_len
92 - strlen(sl.label)) / 2 );
95 memset( str, space_ch,
96 (size_t)(slks->max_label_len
97 - strlen(sl.label)) );
102 memset(str+strlen(str), space_ch,
103 (size_t)(slks->max_label_len - strlen(str)) );
106 // print the formatted label
107 _wputstr ( stdscr, str, NOWRAP, slks->max_label_len );
111 * Return the attribute used for the soft function keys
113 * @ret attrs the current attributes of the soft function keys
115 attr_t slk_attr ( void ) {
116 return ( slks == NULL ? 0 : slks->attrs );
120 * Turn off soft function key attributes
122 * @v attrs attribute bit mask
123 * @ret rc return status code
125 int slk_attroff ( const chtype attrs ) {
128 slks->attrs &= ~( attrs & A_ATTRIBUTES );
133 * Turn on soft function key attributes
135 * @v attrs attribute bit mask
136 * @ret rc return status code
138 int slk_attron ( const chtype attrs ) {
141 slks->attrs |= ( attrs & A_ATTRIBUTES );
146 * Set soft function key attributes
148 * @v attrs attribute bit mask
149 * @ret rc return status code
151 int slk_attrset ( const chtype attrs ) {
154 slks->attrs = ( attrs & A_ATTRIBUTES );
159 * Turn off soft function key attributes
161 * @v attrs attribute bit mask
162 * @v *opts undefined (for future implementation)
163 * @ret rc return status code
165 int slk_attr_off ( const attr_t attrs, void *opts __unused ) {
166 return slk_attroff( attrs );
170 * Turn on soft function key attributes
172 * @v attrs attribute bit mask
173 * @v *opts undefined (for future implementation)
174 * @ret rc return status code
176 int slk_attr_on ( attr_t attrs, void *opts __unused ) {
177 return slk_attron( attrs );
181 * Set soft function key attributes
183 * @v attrs attribute bit mask
184 * @v colour_pair_number colour pair integer
185 * @v *opts undefined (for future implementation)
186 * @ret rc return status code
188 int slk_attr_set ( const attr_t attrs, short colour_pair_number,
189 void *opts __unused ) {
193 if ( ( unsigned short )colour_pair_number > COLORS )
196 slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) |
197 ( attrs & A_ATTRIBUTES );
202 * Clear the soft function key labels from the screen
204 * @ret rc return status code
206 int slk_clear ( void ) {
211 wclrtoeol ( stdscr );
218 * Set soft label colour pair
220 int slk_colour ( short colour_pair_number ) {
223 if ( ( unsigned short )colour_pair_number > COLORS )
226 slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT )
227 | ( slks->attrs & A_ATTRIBUTES );
233 * Initialise the soft function keys
235 * @v fmt format of keys
236 * @ret rc return status code
238 int slk_init ( int fmt ) {
239 unsigned short nmaj, nmin, nblocks, available_width;
241 if ( (unsigned)fmt > 3 ) {
245 /* There seems to be no API call to free this data structure... */
247 slks = calloc(1,sizeof(*slks));
251 slks->attrs = A_DEFAULT;
255 nblocks = 8; nmaj = 2; nmin = 5;
256 slks->spaces[0] = 2; slks->spaces[1] = 4;
259 nblocks = 8; nmaj = 1; nmin = 6;
263 // same allocations as format 3
265 nblocks = 12; nmaj = 2; nmin = 9;
266 slks->spaces[0] = 3; slks->spaces[1] = 7;
269 nblocks = 0; nmaj = 0; nmin = 0;
273 // determine maximum label length and major space size
274 available_width = COLS - ( ( MIN_SPACE_SIZE * nmaj ) + nmin );
275 slks->max_label_len = available_width / nblocks;
276 slks->maj_space_len = MIN_SPACE_SIZE +
277 ( available_width % nblocks ) / nmaj;
278 slks->num_spaces = nmaj;
279 slks->num_labels = nblocks;
281 // strip a line from the screen
288 * Return the label for the specified soft key
290 * @v labnum soft key identifier
291 * @ret label return label
293 char* slk_label ( int labnum ) {
297 return slks->fkeys[labnum].label;
301 * Restore soft function key labels to the screen
303 * @ret rc return status code
305 int slk_restore ( void ) {
306 unsigned int i, j, pos_x,
307 *next_space, *last_space;
317 space_ch = (chtype)' ' | slks->attrs;
318 next_space = &(slks->spaces[0]);
319 last_space = &(slks->spaces[slks->num_spaces-1]);
321 for ( i = 0; i < slks->num_labels ; i++ ) {
322 _print_label( slks->fkeys[i] );
323 pos_x += slks->max_label_len;
325 if ( i == *next_space ) {
326 for ( j = 0; j < slks->maj_space_len; j++, pos_x++ )
327 _wputch ( stdscr, space_ch, NOWRAP );
328 if ( next_space < last_space )
332 _wputch ( stdscr, space_ch, NOWRAP );
343 * Configure specified soft key
345 * @v labnum soft label position to configure
346 * @v *label string to use as soft key label
347 * @v fmt justification format of label
348 * @ret rc return status code
350 int slk_set ( int labnum, const char *label, int fmt ) {
353 if ( (unsigned short)labnum >= slks->num_labels )
355 if ( (unsigned short)fmt >= 3 )
358 strncpy(slks->fkeys[labnum].label, label,
359 sizeof(slks->fkeys[labnum].label));
360 slks->fkeys[labnum].fmt = fmt;