|
|
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.