source: bootcd/isolinux/syslinux-6.03/gpxe/src/hci/mucurses/slk.c @ dd1be7c

Last change on this file since dd1be7c was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 7.6 KB
Line 
1#include <curses.h>
2#include <stddef.h>
3#include <stdlib.h>
4#include <string.h>
5#include <assert.h>
6#include "mucurses.h"
7#include "cursor.h"
8
9/** @file
10 *
11 * Soft label key functions
12 */
13
14#define MIN_SPACE_SIZE 2
15
16#define SLK_MAX_LABEL_LEN 8
17
18#define SLK_MAX_NUM_LABELS 12
19
20#define SLK_MAX_NUM_SPACES 2
21
22struct _softlabel {
23        // label string
24        char label[SLK_MAX_LABEL_LEN];
25        /* Format of soft label
26           0: left justify
27           1: centre justify
28           2: right justify
29         */
30        unsigned int fmt;
31};
32
33struct _softlabelkeys {
34        struct _softlabel fkeys[SLK_MAX_NUM_LABELS];
35        attr_t attrs;
36        /* Soft label layout format
37           0: 3-2-3
38           1: 4-4
39           2: 4-4-4
40           3: 4-4-4 with index line
41        */
42        unsigned int fmt;
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;
49        attr_t saved_attrs;
50        short saved_pair;
51};
52
53static struct _softlabelkeys *slks;
54
55/*
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
59  this should be ok...
60 */
61
62static void _enter_slk ( void ) {
63        _store_curs_pos ( stdscr, &slks->saved_cursor );
64        wattr_get ( stdscr, &slks->saved_attrs, &slks->saved_pair, NULL );
65        LINES++;
66        wmove ( stdscr, LINES, 0 );
67        wattrset ( stdscr, slks->attrs );
68}
69
70static void _leave_slk ( void ) {
71        LINES--;
72        wattr_set ( stdscr, slks->saved_attrs, slks->saved_pair, NULL );
73        _restore_curs_pos ( stdscr, &slks->saved_cursor );
74}
75
76static void _print_label ( struct _softlabel sl ) {
77        int space_ch;
78        char str[SLK_MAX_LABEL_LEN + 1];
79
80        assert ( slks->max_label_len <= SLK_MAX_LABEL_LEN );
81        space_ch = ' ';
82
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) );
86        } else {
87                /* we need to pad the label with varying amounts of leading
88                   pad depending on the format of the label */
89                if ( sl.fmt == 1 ) {
90                        memset( str, space_ch,
91                                (size_t)(slks->max_label_len
92                                         - strlen(sl.label)) / 2 );
93                }
94                if ( sl.fmt == 2 ) {
95                        memset( str, space_ch,
96                                (size_t)(slks->max_label_len
97                                         - strlen(sl.label)) );
98                }
99                strcat(str,sl.label);
100               
101                // post-padding
102                memset(str+strlen(str), space_ch,
103                       (size_t)(slks->max_label_len - strlen(str)) );
104        }
105
106        // print the formatted label
107        _wputstr ( stdscr, str, NOWRAP, slks->max_label_len );
108}
109
110/**
111 * Return the attribute used for the soft function keys
112 *
113 * @ret attrs   the current attributes of the soft function keys
114 */
115attr_t slk_attr ( void ) {
116        return ( slks == NULL ? 0 : slks->attrs );
117}
118
119/**
120 * Turn off soft function key attributes
121 *
122 * @v attrs     attribute bit mask
123 * @ret rc      return status code
124 */
125int slk_attroff ( const chtype attrs ) {
126        if ( slks == NULL )
127                return ERR;
128        slks->attrs &= ~( attrs & A_ATTRIBUTES );
129        return OK;
130}
131
132/**
133 * Turn on soft function key attributes
134 *
135 * @v attrs     attribute bit mask
136 * @ret rc      return status code
137 */
138int slk_attron ( const chtype attrs ) {
139        if ( slks == NULL )
140                return ERR;
141        slks->attrs |= ( attrs & A_ATTRIBUTES );
142        return OK;
143}
144
145/**
146 * Set soft function key attributes
147 *
148 * @v attrs     attribute bit mask
149 * @ret rc      return status code
150 */
151int slk_attrset ( const chtype attrs ) {
152        if ( slks == NULL )
153                return ERR;
154        slks->attrs = ( attrs & A_ATTRIBUTES );
155        return OK;
156}
157
158/**
159 * Turn off soft function key attributes
160 *
161 * @v attrs     attribute bit mask
162 * @v *opts     undefined (for future implementation)
163 * @ret rc      return status code
164 */
165int slk_attr_off ( const attr_t attrs, void *opts __unused ) {
166        return slk_attroff( attrs );
167}
168
169/**
170 * Turn on soft function key attributes
171 *
172 * @v attrs     attribute bit mask
173 * @v *opts     undefined (for future implementation)
174 * @ret rc      return status code
175 */
176int slk_attr_on ( attr_t attrs, void *opts __unused ) {
177        return slk_attron( attrs );
178}
179
180/**
181 * Set soft function key attributes
182 *
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
187 */
188int slk_attr_set ( const attr_t attrs, short colour_pair_number,
189                   void *opts __unused ) {
190        if ( slks == NULL )
191                return ERR;
192
193        if ( ( unsigned short )colour_pair_number > COLORS )
194                return ERR;
195
196        slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) |
197                ( attrs & A_ATTRIBUTES );
198        return OK;
199}
200
201/**
202 * Clear the soft function key labels from the screen
203 *
204 * @ret rc      return status code
205 */
206int slk_clear ( void ) {
207        if ( slks == NULL )
208                return ERR;
209
210        _enter_slk();
211        wclrtoeol ( stdscr );
212        _leave_slk();
213
214        return OK;
215}
216
217/**
218 * Set soft label colour pair
219 */
220int slk_colour ( short colour_pair_number ) {
221        if ( slks == NULL )
222                return ERR;
223        if ( ( unsigned short )colour_pair_number > COLORS )
224                return ERR;
225
226        slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT )
227                | ( slks->attrs & A_ATTRIBUTES );
228
229        return OK;
230}
231
232/**
233 * Initialise the soft function keys
234 *
235 * @v fmt       format of keys
236 * @ret rc      return status code
237 */
238int slk_init ( int fmt ) {
239        unsigned short nmaj, nmin, nblocks, available_width;
240
241        if ( (unsigned)fmt > 3 ) {
242                return ERR;
243        }
244
245        /* There seems to be no API call to free this data structure... */
246        if ( ! slks )
247                slks = calloc(1,sizeof(*slks));
248        if ( ! slks )
249                return ERR;
250
251        slks->attrs = A_DEFAULT;
252        slks->fmt = fmt;
253        switch(fmt) {
254        case 0:
255                nblocks = 8; nmaj = 2; nmin = 5;
256                slks->spaces[0] = 2; slks->spaces[1] = 4;
257                break;
258        case 1:
259                nblocks = 8; nmaj = 1; nmin = 6;
260                slks->spaces[0] = 3;
261                break;
262        case 2:
263                // same allocations as format 3
264        case 3:
265                nblocks = 12; nmaj = 2; nmin = 9;
266                slks->spaces[0] = 3; slks->spaces[1] = 7;
267                break;
268        default:
269                nblocks = 0; nmaj = 0; nmin = 0;
270                break;
271        }
272
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;
280
281        // strip a line from the screen
282        LINES -= 1;
283
284        return OK;
285}
286
287/**
288 * Return the label for the specified soft key
289 *
290 * @v labnum    soft key identifier
291 * @ret label   return label
292 */
293char* slk_label ( int labnum ) {
294        if ( slks == NULL )
295                return NULL;
296
297        return slks->fkeys[labnum].label;
298}
299
300/**
301 * Restore soft function key labels to the screen
302 *
303 * @ret rc      return status code
304 */
305int slk_restore ( void ) {
306        unsigned int i, j, pos_x,
307                *next_space, *last_space;
308        chtype space_ch;
309
310        if ( slks == NULL )
311                return ERR;
312
313        pos_x = 0;
314
315        _enter_slk();
316
317        space_ch = (chtype)' ' | slks->attrs;
318        next_space = &(slks->spaces[0]);
319        last_space = &(slks->spaces[slks->num_spaces-1]);
320
321        for ( i = 0; i < slks->num_labels ; i++ ) {
322                _print_label( slks->fkeys[i] );
323                pos_x += slks->max_label_len;
324
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 )
329                                next_space++;
330                } else {
331                        if ( pos_x < COLS )
332                                _wputch ( stdscr, space_ch, NOWRAP );
333                        pos_x++;
334                }
335        }
336
337        _leave_slk();
338
339        return OK;
340}
341
342/**
343 * Configure specified soft key
344 *
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
349 */
350int slk_set ( int labnum, const char *label, int fmt ) {
351        if ( slks == NULL )
352                return ERR;
353        if ( (unsigned short)labnum >= slks->num_labels )
354                return ERR;
355        if ( (unsigned short)fmt >= 3 )
356                return ERR;
357
358        strncpy(slks->fkeys[labnum].label, label,
359                sizeof(slks->fkeys[labnum].label));
360        slks->fkeys[labnum].fmt = fmt;
361
362        return OK;
363}
Note: See TracBrowser for help on using the repository browser.