|
|
1.1 root 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:
22: struct _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:
33: struct _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:
53: static 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:
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 );
65: LINES++;
66: wmove ( stdscr, LINES, 0 );
67: wattrset ( stdscr, slks->attrs );
68: }
69:
70: static 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:
76: static 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: */
115: attr_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: */
125: int 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: */
138: int 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: */
151: int 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: */
165: int 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: */
176: int 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: */
188: int 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: */
206: int 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: */
220: int 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: */
238: int 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: */
293: char* 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: */
305: int 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: */
350: int 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.