2
3
4
5
6
7
8
9
10
11
12
13
16
17
26#include "ui_ncurses_internal.h"
27#include <ncursesw/ncurses.h>
28#include <ncursesw/panel.h>
31#include "ui_notcurses_internal.h"
32#include <notcurses/notcurses.h>
48
49
50
52 "black",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
53 "white",
"orange",
"bg",
"abg",
"bblack",
"bred",
"bgreen",
54 "byellow",
"bblue",
"bcyan",
"bmagenta",
"bwhite",
"borange",
""};
167
168
169
170
171
172
173
174
175
176
214 memset(&mbstate, 0,
sizeof(mbstate));
244
245
246
247
248
249
250
251
253 if (rgb->r == rgb->g && rgb->g == rgb->b) {
258 return ((rgb->r - 8) / 10) + 231;
260 uint r_index = (rgb->r < 45) ? 0 : (rgb->r - 60) / 40 + 1;
261 uint g_index = (rgb->g < 45) ? 0 : (rgb->g - 60) / 40 + 1;
262 uint b_index = (rgb->b < 45) ? 0 : (rgb->b - 60) / 40 + 1;
263 return 16 + (36 * r_index) + (6 * g_index) + b_index;
267
268
269
270
271
272
273
276
277
281 rgb.r = rgb.g = rgb.b = 0;
286 }
else if (idx >= 16 && idx <= 231) {
288 rgb.r = (idx / 36) % 6 * 51;
289 rgb.g = (idx / 6) % 6 * 51;
290 rgb.b = (idx % 6) * 51;
291 }
else if (idx >= 232 && idx <= 255) {
292 uint gray = (idx - 232) * 11;
293 rgb.r = rgb.g = rgb.b = gray;
299
300
301
302
303
304
305
306
308 if (rgb->r == rgb->g && rgb->r == rgb->b) {
310 rgb->r = (
int)(pow((rgb->r / 255.0f), 1.0f /
GRAY_GAMMA) * 255.0f);
317 rgb->r = (
int)(pow((rgb->r / 255.0f), 1.0f /
RED_GAMMA) * 255.0f);
319 rgb->g = (
int)(pow((rgb->g / 255.0f), 1.0f /
GREEN_GAMMA) * 255.0f);
321 rgb->b = (
int)(pow((rgb->b / 255.0f), 1.0f /
BLUE_GAMMA) * 255.0f);
324
325
326
327
328
329
330
331
332
376
377
378
379
380
381
382
383
394 wc[0] = wc[1] = L'\0';
395 mbstate_t state = {0};
396 size_t len = mbrtowc(wc, &mbc, MB_CUR_MAX, &state);
405 const char *src_ptr = mb_str;
406 mbstate_t state = {0};
407 size_t wc_count = mbsrtowcs(NULL, &src_ptr, 0, &state);
408 if (wc_count == (size_t)-1)
411 wmemset((wchar_t *)&state, 0,
sizeof(state) /
sizeof(wchar_t));
412 wchar_t *wc_str = malloc((wc_count + 1) *
sizeof(wchar_t));
415 mbsrtowcs(wc_str, &src_ptr, wc_count + 1, &state);
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
438uint mbstr_to_cellstr(UiCell *cmplx_buf,
const char *str,
const UiCell *cell_base, uint *p,
const uint atmost) {
451 getcchar(cell_base, &wstr[0], &attrs, &cp,
nullptr);
453 memset(&mbstate, 0,
sizeof(mbstate));
454 if (pos && *pos >= atmost - 1)
456 while (str[i] !=
'\0') {
458 len = mbrtowc(wstr, s, MB_CUR_MAX, &mbstate);
467 if (setcchar(&cc, wstr, attrs, cp,
nullptr) != ERR) {
468 if (len > 0 && (*pos + len) < atmost)
469 cmplx_buf[(*pos)++] = cc;
475 setcchar(&cc, wstr, attrs, cp,
nullptr);
476 cmplx_buf[*pos] = cc;
493 memset(&mbstate, 0,
sizeof(mbstate));
494 if (pos && *pos >= atmost - 1)
496 while (str[i] !=
'\0') {
498 len = mbrtowc(wstr, s, MB_CUR_MAX, &mbstate);
508 if (len > 0 && (*pos + len) < atmost)
509 cmplx_buf[(*pos)++] = cc;
516 cmplx_buf[*pos] = cc;
523 Perror("Maximum number of surfaces (%d) exceeded");
528 wlines =
min(wlines, maxy - 2);
529 wcols =
min(wcols, maxx - 2);
541 Perror("Maximum number of surfaces (%d) exceeded");
545 Perror("Maximum number of surfaces (%d) exceeded");
550 wlines =
min(wlines, maxy - 2);
551 wcols =
min(wcols, maxx - 2);
552 split_x =
min(split_x, maxx - 2);
553 uint split_wlines =
min(wlines + split_y + 1, maxy - 2);
554 wcols =
min(wcols, maxx - 2);
570
571
572
573
574
575
588 for (x = 1; x < maxx - 1; x++)
593 for (y = 1; y < maxy - 1; y++) {
600 for (x = 1; x < maxx - 1; x++)
607
608
609
610
611
612
613
614
615
616
620 for (uint x = 1; x < maxx - 1; x++)
626
627
628
629
630
631
632
633
634
635
636
640 uint y = separator_line;
652 l = wcswidth(text_wc, wcslen(text_wc));
656 l =
min(l, maxx - 7);
667
668
669
670
671
672
673
674
675
677 if (!title || !*title)
688 l = wcswidth(title_wc, wcslen(title_wc));
689 l =
min(l, maxx - 7);
704
705
708
709
710
711
712
713
714
715int answer_yn(
char *msg0,
char *msg1,
char *msg2,
char *msg3) {
717 uint line, pos, msg_l, msg0_l, msg1_l, msg2_l, msg3_l;
720 fprintf(stderr,
"\n\n%s\n%s\n%s\n%s\n\n", msg0, msg1, msg2, msg3);
736 msg_l =
max(msg0_l, msg1_l);
737 msg_l =
max(msg_l, msg2_l);
738 msg_l =
max(msg_l, msg3_l);
739 msg_l =
max(msg_l, chyron
->l);
740 msg_l =
min(msg_l, maxx - 4);
742 pos = ((maxx - msg_l) - 4) / 2;
743 line = (maxy - 6) / 2;
747 msg_l + 2
, line
, pos
, title
);
761 event
.y = event
.x = -1;
771
772
773
774
775
776
777
780 uint line, pos, msg_l, msg0_l, msg1_l, msg2_l, msg3_l;
783 fprintf(stderr,
"\n\n%s\n", msg0);
784 fprintf(stderr,
"%s\n", msg1);
785 fprintf(stderr,
"%s\n", msg2);
786 fprintf(stderr,
"%s\n\n", msg3);
802 msg_l =
max(msg0_l, msg1_l);
803 msg_l =
max(msg_l, msg2_l);
804 msg_l =
max(msg_l, msg3_l);
805 msg_l =
max(msg_l, chyron
->l);
806 msg_l =
min(msg_l, maxx - 4);
808 pos = ((maxx - msg_l) - 4) / 2;
809 line = (maxy - 6) / 2;
813 msg_l + 2
, line
, pos
, title
);
826 event
.y = event
.x = -1;
837
838
839
840
844 uint line, pos, cols;
846 bool f_xwgetch =
true;
847 if (emsg_str[0] ==
'␛' && emsg_str[1] ==
'w') {
853 fprintf(stderr,
"\n%s\n", emsg);
864 cols =
max(cols, chyron
->l);
866 pos = (maxx - cols - 4) / 2;
867 line = (maxy - 4) / 2;
871 4
, line
, line
, pos
, title
);
880 event
.y = event
.x = -1;
890
891
892
893
894
900 fprintf(stderr,
"\n%s\n", title);
901 fprintf(stderr,
"%s\n", action_str);
907 len =
max(strlen(title), strlen(action_str));
910 col = (maxx - len - 4) / 2;
911 line = (maxy - 4) / 2;
914 line
, line
, col
, title
);
921 event
.y = event
.x = -1;
928
929
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
948 Chyron *chyron = (Chyron *)calloc(1,
sizeof(Chyron));
954 chyron
->key[i] = (ChyronKey *)calloc(1,
sizeof(ChyronKey));
955 if (!chyron
->key[i]) {
956 abend(-1
, "calloc chyron->key[i] failed");
963 bool a_toi_error =
false;
979
980
981
982
983
990 if (chyron
->key[i]) {
991 free(chyron
->key[i]);
992 chyron
->key[i] =
nullptr;
1000
1001
1002
1003
1004
1012
1013
1014
1015
1016
1017
1018
1019
1020
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1055
1056
1057
1058
1059
1064
1065
1066
1067
1068
1073
1074
1075
1076
1077
1083
1084
1085
1086
1087
1092
1093
1094
1095
1101
1102
1103
1104
1105
1106
1107
1108
1109
1140 chyron
->l = end_pos;
1147 chyron
->l = end_pos;
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1200
1201
1202
1203
1208 fprintf(stderr,
"\n\nABEND: %s (code: %d)\n", s, ec);
#define CHYRON_KEY_MAXLEN
#define min(x, y)
min macro evaluates two expressions, returning least result
#define max(a, b)
max macro evaluates two expressions, returning greatest result.
int ui_mvwadd_wchstr(UiSurface *s, uint w, uint y, uint x, const UiCell *cell)
int ui_bkgdset(UiSurface *s, uint w, const UiCell *cell)
int ui_mvwaddnwstr(UiSurface *s, uint w, uint y, uint x, const wchar_t *wstr, int m)
int ui_mvwadd_wchnstr(UiSurface *s, uint w, uint y, uint x, const UiCell *cell, uint m)
int ui_get_event(UiSurface *s, uint w, UiEvent *ev, int timeout_ms)
Wait for an input event on target (or stdscr if NULL).
int ui_draw_text(UiSurface *s, uint w, uint y, uint x, const char *text)
void ui_surface_destroy(UiSurface *s)
int ui_wmove(UiSurface *s, uint w, uint y, uint x)
UiSurface * ui_surface[UI_SFC_MAX]
void ui_get_screen_size(uint *lines, uint *cols)
int ui_wclrtoeol(UiSurface *s, uint w)
UiCell ui_cell_from_ucp(const wchar_t *ucp, const uint32_t *fg, const uint32_t *bg)
int ui_curs_set(int visibility)
UiSurface * ui_box_surface_new(UiSurface *parent, uint p, uint lines, uint cols, uint y, uint x, char *title)
int ui_surface_addwin(UiSurface *s, uint w, uint p, uint lines, uint cols, uint y, uint x)
int ui_chg_color(uint16_t color_idx, uint32_t *color)
int ui_getmaxx(UiSurface *s, uint w)
uint ui_add_pair(uint fg, uint bg)
int ui_getcchar(const UiCell *uc, wchar_t *wstr, attr_t *attrs, uint16_t *pair, void *opts)
int ui_getmaxy(UiSurface *s, uint w)
int ui_setcchar(cchar_t *wch, const wchar_t *wc, const attr_t attrs, short pair, const void *opts)
uint rgb_to_xterm256_idx(RGB *rgb)
Convert RGB color to XTerm 256 color index.
int surface_box_win_new(uint wlines, uint wcols, uint wbegy, uint wbegx, char *wtitle)
char const colors_text[][10]
Color names for .minitrc overrides.
wchar_t * mbstr_to_wcstr(const char *mb_str)
void initialize_cells(SIO *sio)
Initialize local color variables and color pairs based on SIO settings.
int border_draw(UiSurface *sfc)
bool init_clr_palette(SIO *sio)
Initialize color palette based on SIO settings.
int surface_split_box_win_new(uint wlines, uint wcols, uint split_y, uint split_x, uint wbegy, uint wbegx, char *wtitle)
void mbc_to_wc(wchar_t wc[2], const char mbc)
void apply_gamma(RGB *rgb)
Apply gamma correction to RGB color.
RGB xterm256_idx_to_rgb(uint idx)
Convert XTerm 256 color index to RGB.
int assign_chyron_win(Chyron *chyron, UiSurface *sfc, uint win, char *y)
int border_ysplit(UiSurface *sfc, uint y)
Draw a box with a separator line around the specified window.
int border_ysplit_text(UiSurface *sfc, char *text, uint separator_line)
Draw a box with a separator line and text around the specified window.
int cm_surface_destroy(UiSurface *sfc)
Destroy the most recently created surface.
int border_title(UiSurface *sfc, char *title)
Draw a box with a title around the specified window.
void destroy_curses()
Gracefully shut down NCurses and restore terminal settings.
bool action_disposition(char *title, char *action_str)
Display a simple action disposition message window or print to stderr.
int answer_yn(char *msg0, char *msg1, char *msg2, char *msg3)
Accept a single letter answer.
int Perror(char *emsg_str)
Display a simple error message window or print to stderr.
void abend(int ec, char *s)
Abnormal program termination.
int display_error(char *msg0, char *msg1, char *msg2, char *msg3)
Display an error message window or print to stderr.
void set_chyron_key_cb(Chyron *chyron, uint k, char *s, uint kc, UiCell cell_base)
Set chyron key with color pair (cp).
Chyron * destroy_chyron(Chyron *chyron)
Destroy Chyron structure.
void compile_chyron(Chyron *chyron)
construct the chyron string from the chyron structure
int get_chyron_key(Chyron *chyron, uint x)
Get keycode from chyron.
void activate_all_chyron_keys(Chyron *chyron)
Deactivate chyron key.
void unset_chyron_key(Chyron *chyron, uint k)
Unset chyron key.
void activate_chyron_key(Chyron *chyron, uint k)
Activate chyron key.
uint mbstr_to_cellstr(UiCell *cmplx_buf, const char *str, const UiCell *cell_base, uint *pos, const uint atmost)
Convert multibyte string to complex character array.
void deactivate_all_chyron_keys(Chyron *chyron)
Deactivate all chyron keys.
Chyron * new_chyron()
Create and initialize Chyron structure.
bool is_set_chyron_key(Chyron *chyron, uint k)
Check if function key label is set.
void display_chyron(UiSurface *sfc, uint w, Chyron *chyron, uint line, uint col)
Display chyron on the specified line and column of the surface.
void deactivate_chyron_key(Chyron *chyron, uint k)
Deactivate chyron key.
void set_chyron_key(Chyron *chyron, uint k, char *s, uint kc)
Set chyron key with default color pair (cp_nt_rev).
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
size_t strnz(char *, size_t)
terminates string at New Line, Carriage Return, or max_len
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
int a_toi(char *, bool *)
a safer alternative to atoi() for converting ASCII strings to integers.
bool restore_shell_tioctl()
restore_shell_tioctl() - restore shell terminal settings
void sig_dfl_mode()
Set signal handlers to default behavior.
char text[CHYRON_KEY_MAXLEN]
ChyronKey * key[CHYRON_KEYS]