iPXE
settings_ui.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <curses.h>
31 #include <ipxe/console.h>
32 #include <ipxe/settings.h>
33 #include <ipxe/editbox.h>
34 #include <ipxe/keys.h>
35 #include <ipxe/ansicol.h>
36 #include <ipxe/jumpscroll.h>
37 #include <ipxe/settings_ui.h>
38 #include <config/branding.h>
39 
40 /** @file
41  *
42  * Option configuration console
43  *
44  */
45 
46 /* Screen layout */
47 #define TITLE_ROW 1U
48 #define SETTINGS_LIST_ROW 3U
49 #define SETTINGS_LIST_COL 1U
50 #define SETTINGS_LIST_ROWS ( LINES - 6U - SETTINGS_LIST_ROW )
51 #define INFO_ROW ( LINES - 5U )
52 #define ALERT_ROW ( LINES - 2U )
53 #define INSTRUCTION_ROW ( LINES - 2U )
54 #define INSTRUCTION_PAD " "
55 
56 /** Layout of text within a setting row */
57 #define SETTING_ROW_TEXT( cols ) struct { \
58  char start[0]; \
59  char pad1[1]; \
60  union { \
61  char settings[ cols - 1 - 1 - 1 - 1 ]; \
62  struct { \
63  char name[15]; \
64  char pad2[1]; \
65  char value[ cols - 1 - 15 - 1 - 1 - 1 - 1 ]; \
66  } setting; \
67  } u; \
68  char pad3[1]; \
69  char nul; \
70 } __attribute__ (( packed ))
71 
72 /** A settings user interface row */
74  /** Target configuration settings block
75  *
76  * Valid only for rows that lead to new settings blocks.
77  */
78  struct settings *settings;
79  /** Configuration setting origin
80  *
81  * Valid only for rows that represent individual settings.
82  */
83  struct settings *origin;
84  /** Configuration setting
85  *
86  * Valid only for rows that represent individual settings.
87  */
88  struct setting setting;
89  /** Screen row */
90  unsigned int row;
91  /** Edit box widget used for editing setting */
92  struct edit_box editbox;
93  /** Editing in progress flag */
94  int editing;
95  /** Buffer for setting's value */
96  char value[256]; /* enough size for a DHCP string */
97 };
98 
99 /** A settings user interface */
100 struct settings_ui {
101  /** Settings block */
103  /** Jump scroller */
105  /** Current row */
107 };
108 
109 /**
110  * Select a setting
111  *
112  * @v ui Settings user interface
113  * @v index Index of setting row
114  * @ret count Number of setting rows
115  */
116 static unsigned int select_setting_row ( struct settings_ui *ui,
117  unsigned int index ) {
118  SETTING_ROW_TEXT ( COLS ) *text;
119  struct settings *settings;
120  struct setting *setting;
121  struct setting *previous = NULL;
122  unsigned int count = 0;
123 
124  /* Initialise structure */
125  memset ( &ui->row, 0, sizeof ( ui->row ) );
126  ui->row.row = ( SETTINGS_LIST_ROW + index - ui->scroll.first );
127 
128  /* Include parent settings block, if applicable */
129  if ( ui->settings->parent && ( count++ == index ) ) {
130  ui->row.settings = ui->settings->parent;
131  snprintf ( ui->row.value, sizeof ( ui->row.value ),
132  "../" );
133  }
134 
135  /* Include any child settings blocks, if applicable */
136  list_for_each_entry ( settings, &ui->settings->children, siblings ) {
137  if ( count++ == index ) {
138  ui->row.settings = settings;
139  snprintf ( ui->row.value, sizeof ( ui->row.value ),
140  "%s/", settings->name );
141  }
142  }
143 
144  /* Include any applicable settings */
146 
147  /* Skip inapplicable settings */
148  if ( ! setting_applies ( ui->settings, setting ) )
149  continue;
150 
151  /* Skip duplicate settings */
152  if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
153  continue;
154  previous = setting;
155 
156  /* Read current setting value and origin */
157  if ( count++ == index ) {
159  &ui->row.setting, ui->row.value,
160  sizeof ( ui->row.value ) );
161  }
162  }
163 
164  /* Initialise edit box */
165  init_editbox ( &ui->row.editbox, ui->row.value,
166  sizeof ( ui->row.value ), NULL, ui->row.row,
168  offsetof ( typeof ( *text ), u.setting.value ) ),
169  sizeof ( text->u.setting.value ), 0 );
170 
171  return count;
172 }
173 
174 /**
175  * Copy string without NUL termination
176  *
177  * @v dest Destination
178  * @v src Source
179  * @v len Maximum length of destination
180  * @ret len Length of (unterminated) string
181  */
182 static size_t string_copy ( char *dest, const char *src, size_t len ) {
183  size_t src_len;
184 
185  src_len = strlen ( src );
186  if ( len > src_len )
187  len = src_len;
188  memcpy ( dest, src, len );
189  return len;
190 }
191 
192 /**
193  * Draw setting row
194  *
195  * @v ui Settings UI
196  */
197 static void draw_setting_row ( struct settings_ui *ui ) {
198  SETTING_ROW_TEXT ( COLS ) text;
199  unsigned int curs_offset;
200  char *value;
201 
202  /* Fill row with spaces */
203  memset ( &text, ' ', sizeof ( text ) );
204  text.nul = '\0';
205 
206  /* Construct row content */
207  if ( ui->row.settings ) {
208 
209  /* Construct space-padded name */
210  curs_offset = ( offsetof ( typeof ( text ), u.settings ) +
211  string_copy ( text.u.settings,
212  ui->row.value,
213  sizeof ( text.u.settings ) ) );
214 
215  } else {
216 
217  /* Construct dot-padded name */
218  memset ( text.u.setting.name, '.',
219  sizeof ( text.u.setting.name ) );
220  string_copy ( text.u.setting.name, ui->row.setting.name,
221  sizeof ( text.u.setting.name ) );
222 
223  /* Construct space-padded value */
224  value = ui->row.value;
225  if ( ! *value )
226  value = "<not specified>";
227  curs_offset = ( offsetof ( typeof ( text ), u.setting.value ) +
228  string_copy ( text.u.setting.value, value,
229  sizeof ( text.u.setting.value )));
230  }
231 
232  /* Print row */
233  if ( ( ui->row.origin == ui->settings ) || ( ui->row.settings != NULL ))
234  attron ( A_BOLD );
235  mvprintw ( ui->row.row, SETTINGS_LIST_COL, "%s", text.start );
236  attroff ( A_BOLD );
237  move ( ui->row.row, ( SETTINGS_LIST_COL + curs_offset ) );
238 }
239 
240 /**
241  * Edit setting ui
242  *
243  * @v ui Settings UI
244  * @v key Key pressed by user
245  * @ret key Key returned to application, or zero
246  */
247 static int edit_setting ( struct settings_ui *ui, int key ) {
248  assert ( ui->row.setting.name != NULL );
249  ui->row.editing = 1;
250  return edit_editbox ( &ui->row.editbox, key );
251 }
252 
253 /**
254  * Save setting ui value back to configuration settings
255  *
256  * @v ui Settings UI
257  */
258 static int save_setting ( struct settings_ui *ui ) {
259  assert ( ui->row.setting.name != NULL );
260  return storef_setting ( ui->settings, &ui->row.setting, ui->row.value );
261 }
262 
263 /**
264  * Print message centred on specified row
265  *
266  * @v row Row
267  * @v fmt printf() format string
268  * @v args printf() argument list
269  */
270 static void vmsg ( unsigned int row, const char *fmt, va_list args ) {
271  char buf[COLS];
272  size_t len;
273 
274  len = vsnprintf ( buf, sizeof ( buf ), fmt, args );
275  mvprintw ( row, ( ( COLS - len ) / 2 ), "%s", buf );
276 }
277 
278 /**
279  * Print message centred on specified row
280  *
281  * @v row Row
282  * @v fmt printf() format string
283  * @v .. printf() arguments
284  */
285 static void msg ( unsigned int row, const char *fmt, ... ) {
286  va_list args;
287 
288  va_start ( args, fmt );
289  vmsg ( row, fmt, args );
290  va_end ( args );
291 }
292 
293 /**
294  * Clear message on specified row
295  *
296  * @v row Row
297  */
298 static void clearmsg ( unsigned int row ) {
299  move ( row, 0 );
300  clrtoeol();
301 }
302 
303 /**
304  * Print alert message
305  *
306  * @v fmt printf() format string
307  * @v args printf() argument list
308  */
309 static void valert ( const char *fmt, va_list args ) {
310  clearmsg ( ALERT_ROW );
312  vmsg ( ALERT_ROW, fmt, args );
313  sleep ( 2 );
315  clearmsg ( ALERT_ROW );
316 }
317 
318 /**
319  * Print alert message
320  *
321  * @v fmt printf() format string
322  * @v ... printf() arguments
323  */
324 static void alert ( const char *fmt, ... ) {
325  va_list args;
326 
327  va_start ( args, fmt );
328  valert ( fmt, args );
329  va_end ( args );
330 }
331 
332 /**
333  * Draw title row
334  *
335  * @v ui Settings UI
336  */
337 static void draw_title_row ( struct settings_ui *ui ) {
338  const char *name;
339 
340  clearmsg ( TITLE_ROW );
341  name = settings_name ( ui->settings );
342  attron ( A_BOLD );
343  msg ( TITLE_ROW, PRODUCT_SHORT_NAME " configuration settings%s%s",
344  ( name[0] ? " - " : "" ), name );
345  attroff ( A_BOLD );
346 }
347 
348 /**
349  * Draw information row
350  *
351  * @v ui Settings UI
352  */
353 static void draw_info_row ( struct settings_ui *ui ) {
354  char buf[32];
355 
356  /* Draw nothing unless this row represents a setting */
357  clearmsg ( INFO_ROW );
358  clearmsg ( INFO_ROW + 1 );
359  if ( ! ui->row.setting.name )
360  return;
361 
362  /* Determine a suitable setting name */
363  setting_name ( ( ui->row.origin ?
364  ui->row.origin : ui->settings ),
365  &ui->row.setting, buf, sizeof ( buf ) );
366 
367  /* Draw row */
368  attron ( A_BOLD );
369  msg ( INFO_ROW, "%s - %s", buf, ui->row.setting.description );
370  attroff ( A_BOLD );
371  color_set ( CPAIR_URL, NULL );
372  msg ( ( INFO_ROW + 1 ), PRODUCT_SETTING_URI, ui->row.setting.name );
374 }
375 
376 /**
377  * Draw instruction row
378  *
379  * @v ui Settings UI
380  */
381 static void draw_instruction_row ( struct settings_ui *ui ) {
382 
384  if ( ui->row.editing ) {
386  "Enter - accept changes" INSTRUCTION_PAD
387  "Ctrl-C - discard changes" );
388  } else {
390  "%sCtrl-X - exit configuration utility",
391  ( ( ui->row.origin == ui->settings ) ?
392  "Ctrl-D - delete setting" INSTRUCTION_PAD : "" ) );
393  }
394 }
395 
396 /**
397  * Draw the current block of setting rows
398  *
399  * @v ui Settings UI
400  */
401 static void draw_setting_rows ( struct settings_ui *ui ) {
402  unsigned int i;
403 
404  /* Draw ellipses before and/or after the list as necessary */
406  mvaddstr ( ( SETTINGS_LIST_ROW - 1 ), ( SETTINGS_LIST_COL + 1 ),
407  jump_scroll_is_first ( &ui->scroll ) ? " " : "..." );
409  ( SETTINGS_LIST_COL + 1 ),
410  jump_scroll_is_last ( &ui->scroll ) ? " " : "..." );
412 
413  /* Draw visible settings. */
414  for ( i = 0 ; i < SETTINGS_LIST_ROWS ; i++ ) {
415  if ( ( ui->scroll.first + i ) < ui->scroll.count ) {
416  select_setting_row ( ui, ( ui->scroll.first + i ) );
417  draw_setting_row ( ui );
418  } else {
419  clearmsg ( SETTINGS_LIST_ROW + i );
420  }
421  }
422 }
423 
424 /**
425  * Select settings block
426  *
427  * @v ui Settings UI
428  * @v settings Settings block
429  */
430 static void select_settings ( struct settings_ui *ui,
431  struct settings *settings ) {
432 
434  ui->scroll.count = select_setting_row ( ui, 0 );
436  ui->scroll.current = 0;
437  ui->scroll.first = 0;
438  draw_title_row ( ui );
439  draw_setting_rows ( ui );
440  select_setting_row ( ui, 0 );
441 }
442 
443 static int main_loop ( struct settings *settings ) {
444  struct settings_ui ui;
445  unsigned int previous;
446  int redraw = 1;
447  int move;
448  int key;
449  int rc;
450 
451  /* Print initial screen content */
453  memset ( &ui, 0, sizeof ( ui ) );
454  select_settings ( &ui, settings );
455 
456  while ( 1 ) {
457 
458  /* Redraw rows if necessary */
459  if ( redraw ) {
460  draw_info_row ( &ui );
461  draw_instruction_row ( &ui );
462  color_set ( ( ui.row.editing ?
464  draw_setting_row ( &ui );
466  curs_set ( ui.row.editing );
467  redraw = 0;
468  }
469 
470  /* Edit setting, if we are currently editing */
471  if ( ui.row.editing ) {
472 
473  /* Sanity check */
474  assert ( ui.row.setting.name != NULL );
475 
476  /* Redraw edit box */
478  draw_editbox ( &ui.row.editbox );
480 
481  /* Process keypress */
482  key = edit_setting ( &ui, getkey ( 0 ) );
483  switch ( key ) {
484  case CR:
485  case LF:
486  if ( ( rc = save_setting ( &ui ) ) != 0 )
487  alert ( " %s ", strerror ( rc ) );
488  /* Fall through */
489  case CTRL_C:
490  select_setting_row ( &ui, ui.scroll.current );
491  redraw = 1;
492  break;
493  default:
494  /* Do nothing */
495  break;
496  }
497 
498  continue;
499  }
500 
501  /* Otherwise, navigate through settings */
502  key = getkey ( 0 );
503  move = jump_scroll_key ( &ui.scroll, key );
504  if ( move ) {
505  previous = ui.scroll.current;
506  jump_scroll_move ( &ui.scroll, move );
507  if ( ui.scroll.current != previous ) {
508  draw_setting_row ( &ui );
509  redraw = 1;
510  if ( jump_scroll ( &ui.scroll ) )
511  draw_setting_rows ( &ui );
512  select_setting_row ( &ui, ui.scroll.current );
513  }
514  continue;
515  }
516 
517  /* Handle non-navigation keys */
518  switch ( key ) {
519  case CTRL_D:
520  if ( ! ui.row.setting.name )
521  break;
522  if ( ( rc = delete_setting ( ui.settings,
523  &ui.row.setting ) ) != 0 ){
524  alert ( " %s ", strerror ( rc ) );
525  }
526  select_setting_row ( &ui, ui.scroll.current );
527  redraw = 1;
528  break;
529  case CTRL_X:
530  return 0;
531  case CR:
532  case LF:
533  if ( ui.row.settings ) {
534  select_settings ( &ui, ui.row.settings );
535  redraw = 1;
536  }
537  /* Fall through */
538  default:
539  if ( ui.row.setting.name ) {
540  edit_setting ( &ui, key );
541  redraw = 1;
542  }
543  break;
544  }
545  }
546 }
547 
548 int settings_ui ( struct settings *settings ) {
549  int rc;
550 
551  initscr();
552  start_color();
554  curs_set ( 0 );
555  erase();
556 
557  rc = main_loop ( settings );
558 
559  endwin();
560 
561  return rc;
562 }
int getkey(unsigned long timeout)
Get single keypress.
Definition: getkey.c:71
MuCurses header file.
int editing
Editing in progress flag.
Definition: settings_ui.c:94
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
#define va_end(ap)
Definition: stdarg.h:9
Editable text box widget.
#define PRODUCT_SHORT_NAME
Definition: branding.h:28
int fetchf_setting(struct settings *settings, const struct setting *setting, struct settings **origin, struct setting *fetched, char *buf, size_t len)
Fetch formatted value of setting.
Definition: settings.c:1233
int erase(void)
Completely clear the screen.
Definition: clear.c:97
int settings_ui(struct settings *settings)
Definition: settings_ui.c:548
static void draw_setting_row(struct settings_ui *ui)
Draw setting row.
Definition: settings_ui.c:197
struct settings * parent
Parent settings block.
Definition: settings.h:138
static int attroff(int attrs)
Definition: curses.h:508
#define CPAIR_EDIT
Editable text.
Definition: ansicol.h:49
A settings user interface.
Definition: settings_ui.c:100
static int main_loop(struct settings *settings)
Definition: settings_ui.c:443
struct settings_ui_row row
Current row.
Definition: settings_ui.c:106
static void clearmsg(unsigned int row)
Clear message on specified row.
Definition: settings_ui.c:298
static int delete_setting(struct settings *settings, const struct setting *setting)
Delete setting.
Definition: settings.h:526
#define start_color()
Definition: curses.h:396
int endwin(void)
Finalise console environment.
Definition: wininit.c:31
A settings user interface row.
Definition: settings_ui.c:73
#define mvprintw(y, x, fmt,...)
Definition: curses.h:648
const char * settings_name(struct settings *settings)
Return settings block name.
Definition: settings.c:345
#define SETTINGS_LIST_ROW
Definition: settings_ui.c:48
static void draw_instruction_row(struct settings_ui *ui)
Draw instruction row.
Definition: settings_ui.c:381
Branding configuration.
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
const char * description
Description.
Definition: settings.h:30
static unsigned int select_setting_row(struct settings_ui *ui, unsigned int index)
Select a setting.
Definition: settings_ui.c:116
A jump scroller.
Definition: jumpscroll.h:13
#define CPAIR_NORMAL
Normal text.
Definition: ansicol.h:40
struct settings * origin
Configuration setting origin.
Definition: settings_ui.c:83
const char * name
Name.
Definition: settings.h:28
#define SETTINGS
Configuration setting table.
Definition: settings.h:53
#define CTRL_X
Definition: keys.h:41
static void valert(const char *fmt, va_list args)
Print alert message.
Definition: settings_ui.c:309
static int save_setting(struct settings_ui *ui)
Save setting ui value back to configuration settings.
Definition: settings_ui.c:258
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct settings * settings_target(struct settings *settings)
Redirect to target settings block.
Definition: settings.c:552
static void draw_setting_rows(struct settings_ui *ui)
Draw the current block of setting rows.
Definition: settings_ui.c:401
WINDOW * initscr(void)
Initialise console environment.
Definition: wininit.c:17
static void draw_info_row(struct settings_ui *ui)
Draw information row.
Definition: settings_ui.c:353
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define PRODUCT_SETTING_URI
Definition: branding.h:170
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
unsigned int first
First visible item.
Definition: jumpscroll.h:21
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
unsigned int count
Total number of items.
Definition: jumpscroll.h:17
int jump_scroll(struct jump_scroller *scroll)
Jump scroll to new page (if applicable)
Definition: jumpscroll.c:119
#define CPAIR_ALERT
Error text.
Definition: ansicol.h:52
#define CTRL_C
Definition: keys.h:20
static int edit_editbox(struct edit_box *box, int key) __nonnull
Edit text box widget.
Definition: editbox.h:57
#define CPAIR_URL
URL text.
Definition: ansicol.h:55
struct settings * settings
Target configuration settings block.
Definition: settings_ui.c:78
An editable text box widget.
Definition: editbox.h:16
User interaction.
static void * dest
Definition: strings.h:176
#define ALERT_ROW
Definition: settings_ui.c:52
#define TITLE_ROW
Definition: settings_ui.c:47
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
Configuration settings.
int storef_setting(struct settings *settings, const struct setting *setting, const char *value)
Store formatted value of setting.
Definition: settings.c:1323
static void vmsg(unsigned int row, const char *fmt, va_list args)
Print message centred on specified row.
Definition: settings_ui.c:270
struct settings * settings
Settings block.
Definition: settings_ui.c:102
Option configuration console.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void init_editbox(struct edit_box *box, char *buf, size_t len, WINDOW *win, unsigned int row, unsigned int col, unsigned int width, unsigned int flags)
Initialise text box widget.
Definition: editbox.c:50
static void select_settings(struct settings_ui *ui, struct settings *settings)
Select settings block.
Definition: settings_ui.c:430
int setting_applies(struct settings *settings, const struct setting *setting)
Check applicability of setting.
Definition: settings.c:573
static int clrtoeol(void)
Definition: curses.h:553
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
A settings block.
Definition: settings.h:132
#define INSTRUCTION_ROW
Definition: settings_ui.c:53
#define CPAIR_SEPARATOR
Unselectable text (e.g.
Definition: ansicol.h:46
const char * name
Name.
Definition: settings.h:136
#define INFO_ROW
Definition: settings_ui.c:51
#define COLS
Definition: curses.h:111
#define INSTRUCTION_PAD
Definition: settings_ui.c:54
#define LF
Definition: keys.h:47
A setting.
Definition: settings.h:23
void draw_editbox(struct edit_box *box)
Draw text box widget.
Definition: editbox.c:69
static int jump_scroll_is_last(struct jump_scroller *scroll)
Check if jump scroller is currently on last page.
Definition: jumpscroll.h:41
int curs_set(int visibility)
Set cursor visibility.
Definition: mucurses.c:153
uint32_t len
Length.
Definition: ena.h:14
__builtin_va_list va_list
Definition: stdarg.h:6
char value[256]
Buffer for setting's value.
Definition: settings_ui.c:96
Key definitions.
unsigned int row
Screen row.
Definition: settings_ui.c:90
struct setting setting
Configuration setting.
Definition: settings_ui.c:88
static void alert(const char *fmt,...)
Print alert message.
Definition: settings_ui.c:324
uint16_t count
Number of entries.
Definition: ena.h:22
struct jump_scroller scroll
Jump scroller.
Definition: settings_ui.c:104
static int jump_scroll_is_first(struct jump_scroller *scroll)
Check if jump scroller is currently on first page.
Definition: jumpscroll.h:30
struct edit_box editbox
Edit box widget used for editing setting.
Definition: settings_ui.c:92
static int move(int y, int x)
Definition: curses.h:593
#define CPAIR_SELECT
Highlighted text.
Definition: ansicol.h:43
#define SETTINGS_LIST_COL
Definition: settings_ui.c:49
int jump_scroll_key(struct jump_scroller *scroll, int key)
Jump scrolling.
Definition: jumpscroll.c:42
Jump scrolling.
#define CR
Definition: keys.h:48
int ssize_t const char * fmt
Definition: vsprintf.h:72
unsigned int rows
Maximum number of visible rows.
Definition: jumpscroll.h:15
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
struct list_head children
Child settings blocks.
Definition: settings.h:142
#define color_set(cpno, opts)
Definition: curses.h:240
static void draw_title_row(struct settings_ui *ui)
Draw title row.
Definition: settings_ui.c:337
#define CTRL_D
Definition: keys.h:21
union @16 u
#define va_start(ap, last)
Definition: stdarg.h:7
#define A_BOLD
Definition: curses.h:138
static size_t string_copy(char *dest, const char *src, size_t len)
Copy string without NUL termination.
Definition: settings_ui.c:182
static int edit_setting(struct settings_ui *ui, int key)
Edit setting ui.
Definition: settings_ui.c:247
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21
unsigned int current
Currently selected item.
Definition: jumpscroll.h:19
#define SETTINGS_LIST_ROWS
Definition: settings_ui.c:50
int setting_name(struct settings *settings, const struct setting *setting, char *buf, size_t len)
Return full setting name.
Definition: settings.c:1610
int setting_cmp(const struct setting *a, const struct setting *b)
Compare two settings.
Definition: settings.c:1124
unsigned int sleep(unsigned int secs)
Sleep (interruptibly) for a fixed number of seconds.
Definition: timer.c:133
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
String functions.
static int mvaddstr(int y, int x, const char *str)
Definition: curses.h:617
#define SETTING_ROW_TEXT(cols)
Layout of text within a setting row.
Definition: settings_ui.c:57
union @375 key
Sense key.
Definition: scsi.h:18
ANSI colours.
int jump_scroll_move(struct jump_scroller *scroll, int move)
Move scroller.
Definition: jumpscroll.c:78
static int attron(int attrs)
Definition: curses.h:512
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
Write a formatted string to a buffer.
Definition: vsprintf.c:351
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:285