2006-06-08 19:23:37 +02:00
|
|
|
#include <curses.h>
|
|
|
|
#include <stddef.h>
|
2007-01-18 21:06:03 +01:00
|
|
|
#include <stdlib.h>
|
2006-06-08 19:23:37 +02:00
|
|
|
#include <string.h>
|
2006-12-18 22:28:35 +01:00
|
|
|
#include <assert.h>
|
2006-12-18 17:52:21 +01:00
|
|
|
#include "mucurses.h"
|
2006-12-18 22:44:44 +01:00
|
|
|
#include "cursor.h"
|
2006-06-08 19:23:37 +02:00
|
|
|
|
2006-06-21 12:21:40 +02:00
|
|
|
/** @file
|
|
|
|
*
|
|
|
|
* Soft label key functions
|
|
|
|
*/
|
|
|
|
|
2015-03-02 13:04:57 +01:00
|
|
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
2015-03-02 13:02:11 +01:00
|
|
|
|
2006-06-21 12:21:40 +02:00
|
|
|
#define MIN_SPACE_SIZE 2
|
|
|
|
|
2006-12-18 22:28:35 +01:00
|
|
|
#define SLK_MAX_LABEL_LEN 8
|
|
|
|
|
|
|
|
#define SLK_MAX_NUM_LABELS 12
|
|
|
|
|
|
|
|
#define SLK_MAX_NUM_SPACES 2
|
|
|
|
|
2006-06-21 12:21:40 +02:00
|
|
|
struct _softlabel {
|
|
|
|
// label string
|
2006-12-18 22:28:35 +01:00
|
|
|
char label[SLK_MAX_LABEL_LEN];
|
2006-06-21 12:21:40 +02:00
|
|
|
/* Format of soft label
|
|
|
|
0: left justify
|
|
|
|
1: centre justify
|
|
|
|
2: right justify
|
|
|
|
*/
|
2006-12-18 22:11:30 +01:00
|
|
|
unsigned int fmt;
|
2006-06-21 12:21:40 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _softlabelkeys {
|
2006-12-18 22:28:35 +01:00
|
|
|
struct _softlabel fkeys[SLK_MAX_NUM_LABELS];
|
2006-06-21 12:21:40 +02:00
|
|
|
attr_t attrs;
|
|
|
|
/* Soft label layout format
|
|
|
|
0: 3-2-3
|
|
|
|
1: 4-4
|
|
|
|
2: 4-4-4
|
|
|
|
3: 4-4-4 with index line
|
|
|
|
*/
|
2006-12-18 22:11:30 +01:00
|
|
|
unsigned int fmt;
|
|
|
|
unsigned int max_label_len;
|
|
|
|
unsigned int maj_space_len;
|
|
|
|
unsigned int num_labels;
|
|
|
|
unsigned int num_spaces;
|
2006-12-18 22:28:35 +01:00
|
|
|
unsigned int spaces[SLK_MAX_NUM_SPACES];
|
2006-12-18 22:44:44 +01:00
|
|
|
struct cursor_pos saved_cursor;
|
|
|
|
attr_t saved_attrs;
|
|
|
|
short saved_pair;
|
2006-06-21 12:21:40 +02:00
|
|
|
};
|
|
|
|
|
2007-07-27 21:38:45 +02:00
|
|
|
static struct _softlabelkeys *slks;
|
2006-06-21 12:21:40 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
I either need to break the primitives here, or write a collection of
|
|
|
|
functions specifically for SLKs that directly access the screen
|
|
|
|
functions - since this technically isn't part of stdscr, I think
|
|
|
|
this should be ok...
|
|
|
|
*/
|
|
|
|
|
2006-12-18 22:44:44 +01:00
|
|
|
static void _enter_slk ( void ) {
|
|
|
|
_store_curs_pos ( stdscr, &slks->saved_cursor );
|
|
|
|
wattr_get ( stdscr, &slks->saved_attrs, &slks->saved_pair, NULL );
|
|
|
|
LINES++;
|
|
|
|
wmove ( stdscr, LINES, 0 );
|
|
|
|
wattrset ( stdscr, slks->attrs );
|
|
|
|
}
|
|
|
|
|
|
|
|
static void _leave_slk ( void ) {
|
|
|
|
LINES--;
|
|
|
|
wattr_set ( stdscr, slks->saved_attrs, slks->saved_pair, NULL );
|
|
|
|
_restore_curs_pos ( stdscr, &slks->saved_cursor );
|
2006-06-21 12:21:40 +02:00
|
|
|
}
|
2006-06-08 19:23:37 +02:00
|
|
|
|
2006-06-21 17:09:55 +02:00
|
|
|
static void _print_label ( struct _softlabel sl ) {
|
|
|
|
int space_ch;
|
2006-12-18 22:28:35 +01:00
|
|
|
char str[SLK_MAX_LABEL_LEN + 1];
|
2006-06-21 17:09:55 +02:00
|
|
|
|
2006-12-18 22:28:35 +01:00
|
|
|
assert ( slks->max_label_len <= SLK_MAX_LABEL_LEN );
|
2006-06-21 17:09:55 +02:00
|
|
|
space_ch = ' ';
|
|
|
|
|
|
|
|
// protect against gaps in the soft label keys array
|
|
|
|
if ( sl.label == NULL ) {
|
|
|
|
memset( str, space_ch, (size_t)(slks->max_label_len) );
|
|
|
|
} else {
|
|
|
|
/* we need to pad the label with varying amounts of leading
|
|
|
|
pad depending on the format of the label */
|
|
|
|
if ( sl.fmt == 1 ) {
|
|
|
|
memset( str, space_ch,
|
|
|
|
(size_t)(slks->max_label_len
|
|
|
|
- strlen(sl.label)) / 2 );
|
|
|
|
}
|
|
|
|
if ( sl.fmt == 2 ) {
|
|
|
|
memset( str, space_ch,
|
|
|
|
(size_t)(slks->max_label_len
|
|
|
|
- strlen(sl.label)) );
|
|
|
|
}
|
|
|
|
strcat(str,sl.label);
|
|
|
|
|
|
|
|
// post-padding
|
|
|
|
memset(str+strlen(str), space_ch,
|
|
|
|
(size_t)(slks->max_label_len - strlen(str)) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// print the formatted label
|
2006-12-18 22:44:44 +01:00
|
|
|
_wputstr ( stdscr, str, NOWRAP, slks->max_label_len );
|
2006-06-21 17:09:55 +02:00
|
|
|
}
|
|
|
|
|
2006-06-08 19:23:37 +02:00
|
|
|
/**
|
|
|
|
* Return the attribute used for the soft function keys
|
|
|
|
*
|
|
|
|
* @ret attrs the current attributes of the soft function keys
|
|
|
|
*/
|
|
|
|
attr_t slk_attr ( void ) {
|
|
|
|
return ( slks == NULL ? 0 : slks->attrs );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn off soft function key attributes
|
|
|
|
*
|
|
|
|
* @v attrs attribute bit mask
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_attroff ( const chtype attrs ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return ERR;
|
|
|
|
slks->attrs &= ~( attrs & A_ATTRIBUTES );
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn on soft function key attributes
|
|
|
|
*
|
|
|
|
* @v attrs attribute bit mask
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_attron ( const chtype attrs ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return ERR;
|
|
|
|
slks->attrs |= ( attrs & A_ATTRIBUTES );
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set soft function key attributes
|
|
|
|
*
|
|
|
|
* @v attrs attribute bit mask
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_attrset ( const chtype attrs ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return ERR;
|
|
|
|
slks->attrs = ( attrs & A_ATTRIBUTES );
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn off soft function key attributes
|
|
|
|
*
|
|
|
|
* @v attrs attribute bit mask
|
|
|
|
* @v *opts undefined (for future implementation)
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_attr_off ( const attr_t attrs, void *opts __unused ) {
|
|
|
|
return slk_attroff( attrs );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn on soft function key attributes
|
|
|
|
*
|
|
|
|
* @v attrs attribute bit mask
|
|
|
|
* @v *opts undefined (for future implementation)
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_attr_on ( attr_t attrs, void *opts __unused ) {
|
|
|
|
return slk_attron( attrs );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set soft function key attributes
|
|
|
|
*
|
|
|
|
* @v attrs attribute bit mask
|
|
|
|
* @v colour_pair_number colour pair integer
|
|
|
|
* @v *opts undefined (for future implementation)
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_attr_set ( const attr_t attrs, short colour_pair_number,
|
|
|
|
void *opts __unused ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return ERR;
|
|
|
|
|
|
|
|
if ( ( unsigned short )colour_pair_number > COLORS )
|
|
|
|
return ERR;
|
|
|
|
|
|
|
|
slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT ) |
|
|
|
|
( attrs & A_ATTRIBUTES );
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear the soft function key labels from the screen
|
|
|
|
*
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_clear ( void ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return ERR;
|
2006-06-21 17:09:55 +02:00
|
|
|
|
2006-12-18 22:44:44 +01:00
|
|
|
_enter_slk();
|
|
|
|
wclrtoeol ( stdscr );
|
|
|
|
_leave_slk();
|
2006-06-21 17:09:55 +02:00
|
|
|
|
|
|
|
return OK;
|
2006-06-08 19:23:37 +02:00
|
|
|
}
|
|
|
|
|
2006-06-21 12:21:40 +02:00
|
|
|
/**
|
|
|
|
* Set soft label colour pair
|
|
|
|
*/
|
|
|
|
int slk_colour ( short colour_pair_number ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return ERR;
|
|
|
|
if ( ( unsigned short )colour_pair_number > COLORS )
|
|
|
|
return ERR;
|
|
|
|
|
|
|
|
slks->attrs = ( (unsigned short)colour_pair_number << CPAIR_SHIFT )
|
|
|
|
| ( slks->attrs & A_ATTRIBUTES );
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
2006-06-08 19:23:37 +02:00
|
|
|
/**
|
|
|
|
* Initialise the soft function keys
|
|
|
|
*
|
|
|
|
* @v fmt format of keys
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_init ( int fmt ) {
|
2006-06-21 12:21:40 +02:00
|
|
|
unsigned short nmaj, nmin, nblocks, available_width;
|
|
|
|
|
2006-06-08 19:23:37 +02:00
|
|
|
if ( (unsigned)fmt > 3 ) {
|
|
|
|
return ERR;
|
|
|
|
}
|
|
|
|
|
2006-12-18 22:28:35 +01:00
|
|
|
/* There seems to be no API call to free this data structure... */
|
|
|
|
if ( ! slks )
|
|
|
|
slks = calloc(1,sizeof(*slks));
|
|
|
|
if ( ! slks )
|
|
|
|
return ERR;
|
|
|
|
|
2006-06-08 19:23:37 +02:00
|
|
|
slks->attrs = A_DEFAULT;
|
2006-06-21 12:21:40 +02:00
|
|
|
slks->fmt = fmt;
|
|
|
|
switch(fmt) {
|
|
|
|
case 0:
|
|
|
|
nblocks = 8; nmaj = 2; nmin = 5;
|
|
|
|
slks->spaces[0] = 2; slks->spaces[1] = 4;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
nblocks = 8; nmaj = 1; nmin = 6;
|
|
|
|
slks->spaces[0] = 3;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
// same allocations as format 3
|
|
|
|
case 3:
|
|
|
|
nblocks = 12; nmaj = 2; nmin = 9;
|
|
|
|
slks->spaces[0] = 3; slks->spaces[1] = 7;
|
|
|
|
break;
|
2006-06-21 12:38:03 +02:00
|
|
|
default:
|
|
|
|
nblocks = 0; nmaj = 0; nmin = 0;
|
|
|
|
break;
|
2006-06-21 12:21:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// determine maximum label length and major space size
|
|
|
|
available_width = COLS - ( ( MIN_SPACE_SIZE * nmaj ) + nmin );
|
|
|
|
slks->max_label_len = available_width / nblocks;
|
2006-06-21 17:09:55 +02:00
|
|
|
slks->maj_space_len = MIN_SPACE_SIZE +
|
|
|
|
( available_width % nblocks ) / nmaj;
|
2006-06-21 12:21:40 +02:00
|
|
|
slks->num_spaces = nmaj;
|
2006-06-21 17:09:55 +02:00
|
|
|
slks->num_labels = nblocks;
|
2006-06-21 12:21:40 +02:00
|
|
|
|
|
|
|
// strip a line from the screen
|
|
|
|
LINES -= 1;
|
|
|
|
|
2006-06-08 19:23:37 +02:00
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the label for the specified soft key
|
|
|
|
*
|
|
|
|
* @v labnum soft key identifier
|
|
|
|
* @ret label return label
|
|
|
|
*/
|
|
|
|
char* slk_label ( int labnum ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return slks->fkeys[labnum].label;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Restore soft function key labels to the screen
|
|
|
|
*
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_restore ( void ) {
|
2006-12-18 22:12:58 +01:00
|
|
|
unsigned int i, j, pos_x,
|
2006-06-21 12:21:40 +02:00
|
|
|
*next_space, *last_space;
|
|
|
|
chtype space_ch;
|
|
|
|
|
2006-06-21 17:09:55 +02:00
|
|
|
if ( slks == NULL )
|
2006-06-08 19:23:37 +02:00
|
|
|
return ERR;
|
|
|
|
|
2006-06-21 17:09:55 +02:00
|
|
|
pos_x = 0;
|
|
|
|
|
2006-12-18 22:44:44 +01:00
|
|
|
_enter_slk();
|
2006-06-21 12:21:40 +02:00
|
|
|
|
2006-06-21 17:09:55 +02:00
|
|
|
space_ch = (chtype)' ' | slks->attrs;
|
2006-06-21 12:21:40 +02:00
|
|
|
next_space = &(slks->spaces[0]);
|
|
|
|
last_space = &(slks->spaces[slks->num_spaces-1]);
|
|
|
|
|
|
|
|
for ( i = 0; i < slks->num_labels ; i++ ) {
|
2006-06-21 17:09:55 +02:00
|
|
|
_print_label( slks->fkeys[i] );
|
|
|
|
pos_x += slks->max_label_len;
|
|
|
|
|
2006-06-21 12:21:40 +02:00
|
|
|
if ( i == *next_space ) {
|
2006-06-21 17:09:55 +02:00
|
|
|
for ( j = 0; j < slks->maj_space_len; j++, pos_x++ )
|
2006-12-18 22:44:44 +01:00
|
|
|
_wputch ( stdscr, space_ch, NOWRAP );
|
2006-06-21 12:21:40 +02:00
|
|
|
if ( next_space < last_space )
|
|
|
|
next_space++;
|
|
|
|
} else {
|
2006-06-21 17:09:55 +02:00
|
|
|
if ( pos_x < COLS )
|
2006-12-18 22:44:44 +01:00
|
|
|
_wputch ( stdscr, space_ch, NOWRAP );
|
2006-06-21 17:09:55 +02:00
|
|
|
pos_x++;
|
2006-06-21 12:21:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-12-18 22:44:44 +01:00
|
|
|
_leave_slk();
|
|
|
|
|
2006-06-08 19:23:37 +02:00
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configure specified soft key
|
|
|
|
*
|
|
|
|
* @v labnum soft label position to configure
|
|
|
|
* @v *label string to use as soft key label
|
|
|
|
* @v fmt justification format of label
|
|
|
|
* @ret rc return status code
|
|
|
|
*/
|
|
|
|
int slk_set ( int labnum, const char *label, int fmt ) {
|
|
|
|
if ( slks == NULL )
|
|
|
|
return ERR;
|
2006-06-21 17:09:55 +02:00
|
|
|
if ( (unsigned short)labnum >= slks->num_labels )
|
2006-06-08 19:23:37 +02:00
|
|
|
return ERR;
|
|
|
|
if ( (unsigned short)fmt >= 3 )
|
|
|
|
return ERR;
|
|
|
|
|
2006-12-18 22:28:35 +01:00
|
|
|
strncpy(slks->fkeys[labnum].label, label,
|
|
|
|
sizeof(slks->fkeys[labnum].label));
|
2006-06-08 19:23:37 +02:00
|
|
|
slks->fkeys[labnum].fmt = fmt;
|
|
|
|
|
|
|
|
return OK;
|
|
|
|
}
|