2
3
4
5
6
7
10#define _XOPEN_SOURCE_EXTENDED 1
40
41
43
44
45
46
47
48
53
54
55
56
57
58
59
60
64 memset(caps, 0,
sizeof(*caps));
76
77
79
80
81
82
83
84
85
86
87
88UiRuntime *
ui_init(
const UiConfig *cfg, SIO *sio) {
89 setlocale(LC_ALL,
"en_US.UTF-8");
90 ui = calloc(1,
sizeof(*
ui));
94 if (ttyname_r(STDIN_FILENO, tty_name,
sizeof(tty_name)) != 0) {
99 ui->tty_fp = fopen(tty_name,
"r+");
100 if (
ui->tty_fp == NULL) {
106 NotCursesOptions nc_opts = {
107 .flags = NCOPTION_SUPPRESS_BANNERS |
108 NCOPTION_NO_QUIT_SIGHANDLERS,
110 ui->nc = notcurses_init(&nc_opts,
ui->tty_fp);
111 if (
ui->nc == NULL) {
118 notcurses_render(
ui->nc);
120 if (
ui->nc == NULL) {
127 notcurses_mice_enable(
ui->nc, NCMICE_BUTTON_EVENT);
128 notcurses_cursor_disable(
ui->nc);
129 notcurses_stddim_yx(
ui->nc, &
ui->lines, &
ui->cols);
135 stdsfc->meta[i].lines = 0;
139 stdsfc->meta[i].hidden =
false;
143 stdsfc->meta[BOX].lines =
ui->lines;
147 stdsfc->mplane[BOX] = stdplane;
148 if (!
stdsfc->mplane[BOX]) {
149 notcurses_stop(
ui->nc);
159 notcurses_stop(
ui->nc);
168 notcurses_stop(
ui->nc);
176 if (!
ui->border_style)
177 ui->border_style = UI_BORDER_ROUNDED;
179 switch (
ui->border_style) {
180 case UI_BORDER_SINGLE:
183 case UI_BORDER_DOUBLE:
186 case UI_BORDER_ROUNDED:
189 case UI_BORDER_HEAVY:
200 ui->tty_fd = notcurses_inputready_fd(
ui->nc);
207
208
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224UiSurface *
ui_surface_new(ss_t w, UiSurface *parent, uint p, uint lines, uint cols, uint y, uint x) {
227 UiSurface *s = calloc(1,
sizeof(*s));
229 ui_log(ERROR,
"Failed to allocate memory for UiSurface\n");
232 ui_log(INFO,
_(
"Memory allocated for new surface"));
235 ncplane_options plane_opts = {
242 s->meta[w].lines = lines;
243 s->meta[w].cols = cols;
244 s->meta[w].hidden =
false;
245 if (parent && parent->mplane[p]) {
246 s->mplane[w] = ncplane_create(parent->mplane[p], &plane_opts);
248 ui_log(ERROR,
_(
"Failed to create mplane: %d"), w);
252 s->mplane[w] = ncplane_create(stdplane, &plane_opts);
254 ui_log(ERROR,
_(
"Failed to create stdplane"));
257 ui_log(ERROR,
_(
"mplane[%d] created"), w);
259 notcurses_stop(
ui->nc);
266
267
268
269
270
271
272
273
274
275
276
277
278
279UiSurface *
ui_surface_box(UiSurface *parent, uint p, uint lines, uint cols, uint y, uint x,
const char *wtitle) {
282 UiSurface *s = calloc(1,
sizeof(*s));
287 ncplane_options plane_opts = {
295 s->meta[BOX].lines = lines + 2;
296 s->meta[BOX].cols = cols + 2;
297 s->meta[BOX].hidden =
false;
299 if (parent && parent->mplane[p]) {
300 s->mplane[BOX] = ncplane_create(parent->mplane[p], &plane_opts);
303 s->mplane[BOX] = ncplane_create(stdplane, &plane_opts);
305 if (!s->mplane[BOX]) {
309 ncplane_set_base(s->mplane[BOX],
313 ncplane_set_channels(s->mplane[BOX],
cell_box.channels);
319
320
321
322
323
324
325
326
327
328
329
330
331
332
335 ncplane_dim_yx(s->mplane[p], &plines, &pcols);
336 pcols =
min(pcols, cols);
337 plines =
min(plines, lines);
338 ncplane_options plane_opts = {
346 s->meta[w].lines = plines - y;
347 s->meta[w].cols = pcols - x;
348 s->meta[w].hidden =
false;
349 s->mplane[w] = ncplane_create(s->mplane[p], &plane_opts);
351 ui_log(ERROR,
_(
"failed to create mplane[%d]"), w);
352 notcurses_stop(
ui->nc);
356 ncplane_set_base(s->mplane[w],
" ", 0,
cell_nt.channels);
357 ncplane_set_channels(s->mplane[w],
cell_nt.channels);
364
365
366
367
368
369
370
371
372
373
374
375
376
377
379 ncplane_options plane_opts = {
387 s->meta[w].lines = lines;
388 s->meta[w].cols = cols;
389 s->meta[w].hidden =
false;
390 s->mplane[w] = ncplane_create(s->mplane[p], &plane_opts);
392 ui_log(ERROR,
_(
"failed to create mplane[%d]"), w);
393 notcurses_stop(
ui->nc);
397 ncplane_set_base(s->mplane[w],
" ", 0,
cell_nt.channels);
398 ncplane_set_channels(s->mplane[w],
cell_nt.channels);
404
405
406
407
408
409
414
415
416
417
418
419
425 ui_log(INFO,
_(
"Destroying surface: %d"),
sfc_ptr);
431 if (
stdsfc->mplane[BOX]) {
432 ui_log(INFO,
_(
"Destroying mplane[%d]"), BOX);
433 ncplane_erase(
stdsfc->mplane[BOX]);
434 ncplane_destroy(
stdsfc->mplane[BOX]);
435 stdsfc->mplane[BOX] = NULL;
442 ui_log(INFO,
_(
"Destroying stdsfc"));
446 ui_log(INFO,
_(
"Calling notcurses_stop"));
447 notcurses_stop(
ui->nc);
450 if (ui_pair != NULL) {
451 ui_log(INFO,
_(
"Destroying ui_pair"));
455 if (ui_color != NULL) {
456 ui_log(INFO,
_(
"Destroying ui_color"));
461 ui_log(INFO,
_(
"Destroying ui->sio"));
466 ui_log(INFO,
_(
"Destroying ui"));
473
474
475
476
477
478
484 if (s->mplane[w] != NULL) {
485 ui_log(INFO,
_(
"Destroying mplane[%d]"), w);
486 ncplane_erase(s->mplane[w]);
487 ncplane_destroy(s->mplane[w]);
495 ui_log(INFO,
_(
"Destroying surface: s"));
501
502
504
505
506
507
508
509
510
511
512
513
514
520 if (!s->meta[w].hidden)
521 return ncplane_move_yx(s->mplane[w], y, x) == 0 ? 0 : -1;
525
526
527
528
529
530
531
532
533
537 return ncplane_resize_simple(s->mplane[w], (
unsigned int)lines,
538 (
unsigned int)cols) == 0
543
544
545
546
547
551 ncplane_erase_region(stdplane, 0, 0, 0, 0);
555
556
557
558
559
560
561
562
566 ncplane_erase_region(stdplane, 0, 0, 0, 0);
570
571
572
573
574
575
576
577
581 ncplane_erase_region(s->mplane[w], 0, 0, 0, 0);
585
586
587
588
589
590
591
592
596 ncplane_erase_region(s->mplane[w], 0, 0, 0, 0);
600
601
602
603
604
605
606
607
611 ncplane_move_top(s->mplane[w]);
615
616
617
618
619
620
621
622
626 if (s->meta[w].hidden) {
627 s->meta[w].hidden =
false;
628 ncplane_move_yx(s->mplane[w], s->meta[w].y, s->meta[w].x);
633
634
635
636
637
638
639
640
644 if (!s->meta[w].hidden) {
645 s->meta[w].hidden =
true;
647 ncplane_move_yx(s->mplane[w], -s->meta[w].lines - 1, 0);
655
656
657
658
659
660
661
662
663
664int ui_wmove(UiSurface *s, ss_t w, uint y, uint x) {
667 if (ncplane_cursor_move_yx(s->mplane[w], y, x) != 0)
672
673
674
675
676
677
678
679
680
684 if (ncplane_cursor_move_yx(s->mplane[w], y, x) != 0)
689
690
691
692
693
694
695
696
698 notcurses_cursor_yx(
ui->nc, y, x);
701
702
703
704
705
706
707
708
712 ncplane_abs_yx(s->mplane[w], y, x);
715
716
717
718
719
720
721
722
723void ui_getyx(UiSurface *s, ss_t w, uint *y, uint *x) {
726 ncplane_cursor_yx(s->mplane[w], y, x);
729
730
731
732
733
734
735
736
740 ncplane_dim_yx(s->mplane[w], y, x);
743
744
745
746
747
748
749
750
755 ncplane_dim_yx(s->mplane[w], &y, &x);
759
760
761
762
763
764
765
770 ncplane_dim_yx(s->mplane[w], &y, &x);
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
791 ncplane_dim_yx(s->mplane[w], &rows, &cols);
795 ncplane_scrollup(s->mplane[w], r);
801 if ((uint)r >= rows) {
802 ncplane_erase(s->mplane[w]);
807 for (
int src_row = (
int)(rows - r) - 1; src_row >= 0; src_row--) {
808 int dst_row = src_row + r;
809 for (uint col = 0; col < cols; col++) {
810 nccell c = NCCELL_TRIVIAL_INITIALIZER;
811 ncplane_at_yx_cell(s->mplane[w], src_row, col, &c);
812 ncplane_putc_yx(s->mplane[w], dst_row, col, &c);
813 nccell_release(s->mplane[w], &c);
817 for (
int row = 0; row < r; row++) {
818 for (uint col = 0; col < cols; col++) {
819 ncplane_putchar_yx(s->mplane[w], row, col,
' ');
826
827
829
830
831
832
833
834
835
836
840 ncplane_set_scrolling(s->mplane[w], enable);
844
845
846
847
848
849
850
858
859
860
861
862
863
864
872
873
874
875
876
877
878
879
888
889
890
891
892
893
894
902
903
905
906
907
908
909
913 unsigned int r = 0, c = 0;
914 notcurses_stddim_yx(
ui->nc, &r, &c);
923
924
925
929 notcurses_render(
ui->nc);
932
933
934
938 notcurses_render(
ui->nc);
941
942
943
944
945
946
947
948
952 notcurses_leave_alternate_screen(
ui->nc);
956
957
958
959
960
961
962
963
967 notcurses_enter_alternate_screen(
ui->nc);
968 notcurses_render(
ui->nc);
978
979
980
981
982
983
984
989 ui->cursor_visible =
false;
990 notcurses_cursor_disable(
ui->nc);
992 ui->cursor_visible =
true;
994 notcurses_cursor_yx(
ui->nc, &y, &x);
995 int rc = notcurses_cursor_enable(
ui->nc, y, x);
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1015 ui->cursor_visible =
false;
1016 notcurses_cursor_disable(
ui->nc);
1019 ncplane_abs_yx(s->mplane[w], &yy, &xx);
1022 ui->cursor_visible =
true;
1023 int rc = notcurses_cursor_enable(
ui->nc, y, x);
1029
1030
1031
1032
1033
1034
1035
1036
1041 ui->cursor_visible =
false;
1042 notcurses_cursor_disable(
ui->nc);
1045 ncplane_cursor_yx(s->mplane[w], &y, &x);
1047 ncplane_abs_yx(s->mplane[w], &yy, &xx);
1050 ui->cursor_visible =
true;
1051 return notcurses_cursor_enable(
ui->nc, y, x) == 0 ? 0 : -1;
1056
1057
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069int ui_bkgd(UiSurface *s, ss_t w,
const UiCell *cell) {
1072 ncplane_set_styles(s->mplane[w], cell->stylemask);
1073 ncplane_set_channels(s->mplane[w], cell->channels);
1074 ncplane_set_base(s->mplane[w],
" ",
1075 cell->stylemask, cell->channels);
1076 s->meta[w].bkgd_cell = *cell;
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1093 ncplane_set_styles(s->mplane[w], cell->stylemask);
1094 ncplane_set_channels(s->mplane[w], cell->channels);
1095 s->meta[w].bkgd_cell = *cell;
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1114 ncplane_set_styles(s->mplane[w], cell->stylemask);
1115 ncplane_set_channels(s->mplane[w], cell->channels);
1116 ncplane_set_base(s->mplane[w],
" ",
1117 cell->stylemask, cell->channels);
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1134 ncplane_set_styles(s->mplane[w], cell->stylemask);
1135 ncplane_set_channels(s->mplane[w], cell->channels);
1136 ncplane_set_base(s->mplane[w],
" ",
1137 cell->stylemask, cell->channels);
1141
1142
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1166 if (!cell || !wstr || !style || !pair)
1169 gc
.u32 = cell->gcluster;
1171 *style = cell->stylemask;
1173 UiChannels channels;
1174 channels.fb = cell->channels;
1176 rgb.r = channels.f_r;
1177 rgb.g = channels.f_g;
1178 rgb.b = channels.f_b;
1181 rgb.r = channels.b_r;
1182 rgb.g = channels.b_g;
1183 rgb.b = channels.b_b;
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1208 const wchar_t *wstr,
1216 unicode_to_utf8_gcluster(*wstr, &gc);
1217 nccell_set_styles(cell, style);
1218 UiChannels *chan = (UiChannels *)&cell->channels;
1224 nccell_load_egc32(sfc->mplane[w], cell, gc
.u32);
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1242 GCluster *gc = (GCluster *)&cell.gcluster;
1243 wchar_t wstr[2] = {ucp[0], L'\0'};
1245 cell.width = wcwidth(wstr[0]);
1247 unicode_to_utf8_gcluster(wstr[0], gc);
1249 UiChannels *chan = (UiChannels *)&cell.channels;
1252 chan->b_a = chan->f_a = 0x40;
1256
1257
1259
1260
1261
1262
1263
1264
1265
1266
1267
1274 if (rgb->r == tmp.r && rgb->g == tmp.g && rgb->b == tmp.b)
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1305 if (ui_pair[i].fg == fg && ui_pair[i].bg == bg)
1314 return (EXIT_FAILURE);
1324
1325
1326
1327
1328
1330 *fg = ui_pair[pair].fg;
1331 *bg = ui_pair[pair].bg;
1335
1336
1337
1338
1339
1340
1341
1342
1343
1349 UiChannels ui_channels = {};
1352 ui_channels.f_a = 0x40;
1353 ui_channels.f_r = ui_color[fg].r;
1354 ui_channels.f_g = ui_color[fg].g;
1355 ui_channels.f_b = ui_color[fg].b;
1356 bg = ui_pair[pair].bg;
1358 ui_channels.b_a = 0x40;
1359 ui_channels.b_r = ui_color[bg].r;
1360 ui_channels.b_g = ui_color[bg].g;
1361 ui_channels.b_b = ui_color[bg].b;
1362 return ui_channels.fb;
1365
1366
1367
1368
1369
1370
1371
1372
1373
1380 if (rgb.r == ui_color[i].r && rgb.g == ui_color[i].g && rgb.b == ui_color[i].b)
1399
1400
1401
1402
1403
1404
1405
1408 sscanf(s,
"#%02hhX%02hhX%02hhX", &rgb.r, &rgb.g, &rgb.b);
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1426 *r = ui_color[color].r;
1427 *g = ui_color[color].g;
1428 *b = ui_color[color].b;
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1465 *fg = ui_pair[pair].fg;
1466 *bg = ui_pair[pair].bg;
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1489
1490
1491
1492
1493
1494
1495
1496
1497
1504 if (color_idx < 16) {
1515
1516
1518
1519
1520
1521
1522
1529
1530
1531
1532
1533
1534
1535
1540 return s->mplane[w];
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562uint ui_mbstr_to_cellstr(UiSurface *sfc, ss_t w, UiCell *cmplx_buf,
const char *str,
const UiCell *cell_base, uint *p,
const uint atmost) {
1568 uint i = 0, len = 0;
1573 ui_get_nccell(sfc, w, cell_base, &wstr[0], &style, &cp);
1575 memset(&mbstate, 0,
sizeof(mbstate));
1576 if (pos && *pos >= atmost - 1)
1578 while (str[i] !=
'\0') {
1580 len = mbrtowc(wstr, s, MB_CUR_MAX, &mbstate);
1589 if (ui_set_nccell(sfc, w, &cc, wstr, style, cp) !=
ERR) {
1590 if (len > 0 && (*pos + len) < atmost)
1591 cmplx_buf[(*pos)++] = cc;
1597 ui_set_nccell(sfc, w, &cc, wstr, style, cp);
1598 cmplx_buf[*pos] = cc;
#define min(x, y)
min macro evaluates two expressions, returning least result
int ui_border_draw(UiSurface *sfc)
int ui_surface_resize(UiSurface *s, ss_t w, uint lines, uint cols)
Resize a UiSurface to new dimensions.
int ui_surface_addwin(UiSurface *s, ss_t w, uint p, uint lines, uint cols, uint y, uint x)
Add a new window to the specified UiSurface.
const wchar_t * border_none
UiRuntime * ui_init(const UiConfig *config, SIO *sio)
Initialize the UI runtime with the given configuration and SIO.
void ui_render()
Render the UI by updating panels and refreshing the display.
void ui_getyx(UiSurface *s, ss_t w, uint *lines, uint *cols)
Get the current cursor position within a window of a UI surface.
int ui_setscrreg(UiSurface *s, ss_t w, uint top, uint bottom)
Set the scrolling region for a UiSurface.
int ui_wmove(UiSurface *s, ss_t w, uint y, uint x)
Move the cursor to a specified position within a UiSurface.
void ui_getmaxyx(UiSurface *s, ss_t w, uint *lines, uint *cols)
Get the maximum dimensions of a UiSurface.
int ui_cursor_enable_yx(UiSurface *s, ss_t w, uint y, uint x, bool visible)
Enable or disable the cursor at a specific position within a UiSurface.
int ui_wscrl(UiSurface *s, ss_t w, int rows)
Scroll the contents of a UiSurface by a specified number of lines.
int ui_idcok(UiSurface *s, ss_t w, bool enable)
Enable or disable the use of the insert/delete character capabilities for a UiSurface.
int ui_surface_addpad(UiSurface *s, ss_t w, uint view_win, uint lines, uint cols, uint begy, uint begx)
Add a new pad to the specified UiSurface.
int ui_cursor_move(UiSurface *s, ss_t w, uint y, uint x)
Move the cursor to a specified position within a UiSurface.
int ui_suspend()
Suspend the UI, saving the current program state and ending the window session.
void ui_surface_destroy(UiSurface *s)
Destroy a UiSurface, cleaning up its windows and panels.
int ui_border_title(UiSurface *sfc, const char *title)
Draw a box with a title around the specified window.
void ui_update_panels()
Update the panels in the UI.
int ui_bkgd(UiSurface *s, ss_t w, const UiCell *cell)
Set the background of a specific window within a UiSurface.
int ui_idlok(UiSurface *s, ss_t w, bool enable)
Enable or disable the use of the insert/delete line capabilities for a UiSurface.
const wchar_t * border_double
int ui_surface_move(UiSurface *s, ss_t w, uint y, uint x)
Move a UiSurface to a new position on the screen.
int ui_getmaxy(UiSurface *s, ss_t w)
Get the maximum number of lines (rows) of a UiSurface.
UiSurface * ui_surface_box(UiSurface *parent, uint p, uint lines, uint cols, uint y, uint x, const char *title)
Create a new UI surface with a border box and optional title.
const wchar_t * border_single
void ui_get_screen_size(uint *lines, uint *cols)
Get the current screen size (number of lines and columns).
int ui_surface_show(UiSurface *s, ss_t w)
Show a UiSurface, making it visible on the screen.
int ui_erase()
Erase the entire screen.
void ui_shutdown()
Shutdown the UI runtime, cleaning up resources and freeing memory.
UiSurface * ui_surface_new(ss_t w, UiSurface *parent, uint p, uint lines, uint cols, uint y, uint x)
Create a new UI surface with the specified parameters.
void ui_initialize_sio(SIO *sio)
int ui_curs_set(int visibility)
Set the visibility of the cursor.
int ui_resume()
Resume the UI, restoring the previous program state and updating the display.
int ui_bkgrndset(UiSurface *s, ss_t w, const UiCell *cell)
Set the background for new content to be written to a specific window within a UiSurface.
int ui_top_surface(UiSurface *s, ss_t w)
Hide a UiSurface, making it invisible on the screen.
int ui_wclear(UiSurface *s, ss_t w)
Clear the contents of a UiSurface or all surfaces.
void ui_endwin()
End the UI application, cleaning up resources and shutting down the UI runtime.
int ui_cursor_enable(UiSurface *s, ss_t w, bool visible)
Enable or disable the cursor for a UiSurface.
int ui_clear()
Clear the entire screen.
int ui_getmaxx(UiSurface *s, ss_t w)
Get the maximum number of columns of a UiSurface.
const wchar_t * border_heavy
int ui_surface_hide(UiSurface *s, ss_t w)
Hide a UiSurface, making it invisible on the screen.
const wchar_t * border_rounded
int ui_bkgrnd(UiSurface *s, ss_t w, const UiCell *cell)
Set the background of a specific window within a UiSurface.
int ui_scrollok(UiSurface *s, ss_t w, bool enable)
Enable or disable scrolling for a UiSurface.
void ui_get_caps(UiCaps *caps)
Get the UI backend capabilities.
int ui_bkgdset(UiSurface *s, ss_t w, const UiCell *cell)
Set the background for new content to be written to a specific window within a UiSurface.
int ui_werase(UiSurface *s, ss_t w)
Erase the contents of a UiSurface or all surfaces.
int ui_keypad(UiSurface *s, ss_t w, bool enable)
Enable or disable the keypad for a UiSurface.
int ui_get_pair(uint16_t pair, uint *fg, uint *bg)
Get the foreground and background color indices for a given color pair index.
void ui_abs_yx(UiSurface *s, ss_t w, int *y, int *x)
Get the absolute cursor position within a window of a UI surface.
uint ui_init_color_hex(char *s)
Initialize a color from a hexadecimal string representation.
struct notcurses * ui_notcurses_get_nc()
Get the pointer to the Notcurses context associated with the UI.
int ui_get_nccell(UiSurface *sfc, ss_t w, const UiCell *cell, wchar_t *wstr, UiStyle *style, short *pair)
Get the properties of a cell at the current cursor position in a window of a UI surface.
uint64_t ui_get_channels_from_pair(uint16_t pair)
Get the combined foreground and background color channels for a given color pair index.
int ui_set_nccell(UiSurface *sfc, ss_t w, UiCell *cell, const wchar_t *wstr, const UiStyle style, short pair)
Set the properties of a cell at the current cursor position in a window of a UI surface.
void ui_cursor_yx(int *y, int *x)
Get the current cursor position within a window of a UI surface.
NcPlane * ui_notcurses_surface_get_plane(const UiSurface *s, ss_t w)
Get the pointer to the NcPlane associated with a specific window in a UI surface.
UiLogLevel ui_min_log_level
void ui_apply_gamma(RGB *rgb)
Apply gamma correction to RGB color.
int ui_pair_content(uint pair, uint *fg, uint *bg)
Get the foreground and background colors of a specified color pair.
int ui_init_color(uint color, uint r, uint g, uint b)
Initialize a color in the curses color table with specified RGB values.
int ui_init_pair(uint pair, uint fg, uint bg)
Initialize a color pair in the curses color table with specified foreground and background colors.
uint ui_add_pair(uint fg, uint bg)
Add a new color pair to the UI, or retrieve the index of an existing pair.
UiSurface * ui_surface[UI_SFC_MAX]
int ui_color_content(uint color, uint *r, uint *g, uint *b)
RGB ui_hex_to_rgb(char *s)
Convert a hexadecimal color string to an RGB structure.
UiCell ui_cell_from_ucp(const wchar_t *ucp, const uint32_t *fg, const uint32_t *bg)
Convert a Unicode code point to a curses UiCell with specified foreground and background colors.
int ui_color_from_rgb(RGB *rgb)
Convert RGB to curses color index, adding new color if necessary.
int ui_chg_color(uint16_t color_idx, uint32_t *color)
Change the RGB color value for a given color index.
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
int ui_display_error(char *msg0, char *msg1, char *msg2, char *msg3)
Display an error message window or print to stderr.
UiBackend ui_get_backend()
Get the UI backend type.
UiBorderStyle border_style