static void send_bytes(int portfd, const unsigned char* buf, int n, WINDOW* win) { ssize_t written = 0; while (written < n) { ssize_t rc = write(portfd, &buf[written], n - written); if (rc >= 0) written += rc; else if (errno != EINTR) exit_error("send bytes", errno); } int xmax, ymax; getmaxyx(win, ymax, xmax); --xmax; if (n > xmax) { buf += n - xmax; n = xmax; } int x, y; getyx(win, y, x); int ndel = x + n - xmax; if (ndel > 0) { wmove(win, y, 0); for (int i = 0; i < ndel; ++i) wdelch(win); wmove(win, y, x - ndel); } for (int i = 0; i < n; ++i) { cchar_t cc; wchar_t wc[CCHARW_MAX]; attr_t attrs; short color_pair; wgetbkgrnd(win, &cc); getcchar(&cc, wc, &attrs, &color_pair, 0); wc[0] = kc_to_wide_char(buf[i]); setcchar(&cc, wc, attrs, color_pair, 0); wadd_wch(win, &cc); } while (tcdrain(portfd) < 0) { if (errno != EINTR) exit_error("send bytes", errno); } }
/** * winpair_yx -- return the color pair of a window at (y,x) */ short winpair_yx(WINDOW *win, int y, int x) { cchar_t cch; wchar_t wch; short color; attr_t attr; mvwin_wch(win, y, x, &cch); /* Get the cch at (y,x) */ getcchar(&cch, &wch, &attr, &color, NULL); return (color); }
/** * is_blank -- return TRUE if wide-character at (y,x) is blank, else FALSE * @win: pointer to a window * @y : y-coordinate to extract wide-character at * @x : x-coordiante to extract wide-character at */ bool is_blank(WINDOW *win, int y, int x) { cchar_t cch; wchar_t wch; attr_t attr; short color; mvwin_wch(win, y, x, &cch); getcchar(&cch, &wch, &attr, &color, NULL); return (wch == L' ') ? true : false; }
WINDOW* window_create_shadow(WINDOW *window,WINDOW *window_below) { /* WINDOW *window_below; */ extern WINDOW *SCREEN_WINDOW; WINDOW *shadow_window; gint width,height; gint beg_x,beg_y; gint x,y; #ifdef _VIPER_WIDE cchar_t wcval; wchar_t wch; attr_t attrs; short color_pair; #else chtype char_attr; #endif if(window==NULL) return window; getmaxyx(window,height,width); getbegyx(window,beg_y,beg_x); if(window_below==NULL) window_below=SCREEN_WINDOW; shadow_window=newwin(height,width,beg_y+1,beg_x+1); for(y=0;y<height;y++) { for(x=0;x<width;x++) { #ifdef _VIPER_WIDE mvwin_wch(window_below,beg_y+y+1,beg_x+x+1,&wcval); getcchar(&wcval,&wch,&attrs,&color_pair,NULL); setcchar(&wcval,&wch,attrs, viper_color_pair(COLOR_WHITE,COLOR_BLACK),NULL); mvwadd_wch(shadow_window,y,x,&wcval); #else char_attr=mvwinch(window_below,beg_y+y+1,beg_x+x+1); mvwaddch(shadow_window,y,x,char_attr & A_CHARTEXT); if((char_attr & A_ALTCHARSET)==A_ALTCHARSET) mvwchgat(shadow_window,y,x,1,A_NORMAL | A_ALTCHARSET, viper_color_pair(COLOR_WHITE,COLOR_BLACK),NULL); else mvwchgat(shadow_window,y,x,1,A_NORMAL, viper_color_pair(COLOR_WHITE,COLOR_BLACK),NULL); #endif } } return shadow_window; }
static void receive_kctext(int portfd, WINDOW* win) { unsigned char buf[64]; ssize_t count; while ((count = read(portfd, buf, sizeof buf)) < 0) switch (errno) { case EINTR: continue; #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) case EWOULDBLOCK: #endif case EAGAIN: return; default: exit_error("receive KC text", errno); } cchar_t cc; wchar_t wc[CCHARW_MAX]; attr_t attrs; short color_pair; wgetbkgrnd(win, &cc); getcchar(&cc, wc, &attrs, &color_pair, 0); for (ssize_t i = 0; i < count; ++i) { unsigned int byte = buf[i]; if (byte != 0x00 && byte != 0x03 && byte != 0x0D) { wc[0] = (byte == 0x0A) ? L'\n' : kc_to_wide_char(byte); setcchar(&cc, wc, attrs, color_pair, 0); wadd_wch(win, &cc); } } wnoutrefresh(win); }
int main(int argc, char *argv[]) { int optc; int option_differences = 0, option_differences_cumulative = 0, option_help = 0, option_version = 0; double interval = 2; char *command; int command_length = 0; /* not including final \0 */ setlocale(LC_ALL, ""); progname = argv[0]; while ((optc = getopt_long(argc, argv, "+d::hn:vt", longopts, (int *) 0)) != EOF) { switch (optc) { case 'd': option_differences = 1; if (optarg) option_differences_cumulative = 1; break; case 'h': option_help = 1; break; case 't': show_title = 0; break; case 'n': { char *str; interval = strtod(optarg, &str); if (!*optarg || *str) do_usage(); if(interval < 0.1) interval = 0.1; if(interval > ~0u/1000000) interval = ~0u/1000000; } break; case 'v': option_version = 1; break; default: do_usage(); break; } } if (option_version) { fprintf(stderr, "%s\n", VERSION); if (!option_help) exit(0); } if (option_help) { fprintf(stderr, usage, progname); fputs(" -d, --differences[=cumulative]\thighlight changes between updates\n", stderr); fputs("\t\t(cumulative means highlighting is cumulative)\n", stderr); fputs(" -h, --help\t\t\t\tprint a summary of the options\n", stderr); fputs(" -n, --interval=<seconds>\t\tseconds to wait between updates\n", stderr); fputs(" -v, --version\t\t\t\tprint the version number\n", stderr); fputs(" -t, --no-title\t\t\tturns off showing the header\n", stderr); exit(0); } if (optind >= argc) do_usage(); command = strdup(argv[optind++]); command_length = strlen(command); for (; optind < argc; optind++) { char *endp; int s = strlen(argv[optind]); command = realloc(command, command_length + s + 2); /* space and \0 */ endp = command + command_length; *endp = ' '; memcpy(endp + 1, argv[optind], s); command_length += 1 + s; /* space then string length */ command[command_length] = '\0'; } get_terminal_size(); /* Catch keyboard interrupts so we can put tty back in a sane state. */ signal(SIGINT, die); signal(SIGTERM, die); signal(SIGHUP, die); signal(SIGWINCH, winch_handler); /* Set up tty for curses use. */ curses_started = 1; initscr(); nonl(); noecho(); cbreak(); for (;;) { time_t t = time(NULL); char *ts = ctime(&t); int tsl = strlen(ts); char *header; FILE *p; int x, y; int oldeolseen = 1; mbstate_t mbs; if (screen_size_changed) { get_terminal_size(); resizeterm(height, width); clear(); /* redrawwin(stdscr); */ screen_size_changed = 0; first_screen = 1; } if (show_title) { // left justify interval and command, // right justify time, clipping all to fit window width asprintf(&header, "Every %.1fs: %.*s", interval, min(width - 1, command_length), command); mvaddstr(0, 0, header); if (strlen(header) > (size_t) (width - tsl - 1)) mvaddstr(0, width - tsl - 4, "... "); mvaddstr(0, width - tsl + 1, ts); free(header); } if (!(p = popen(command, "r"))) { perror("popen"); do_exit(2); } memset(&mbs, 0, sizeof(mbs)); for (y = show_title; y < height; y++) { int eolseen = 0, tabpending = 0; for (x = 0; x < width; x++) { wint_t c = L' '; int attr = 0, c_width; cchar_t cc; wchar_t wstr[2]; if (!eolseen) { /* if there is a tab pending, just spit spaces until the next stop instead of reading characters */ if (!tabpending) do c = readwc(p, &mbs); while (c != WEOF && !iswprint(c) && c != L'\n' && c != L'\t'); if (c == L'\n') if (!oldeolseen && x == 0) { x = -1; continue; } else eolseen = 1; else if (c == L'\t') tabpending = 1; if (c == WEOF || c == L'\n' || c == L'\t') c = L' '; if (tabpending && (((x + 1) % 8) == 0)) tabpending = 0; } wstr[0] = c; wstr[1] = 0; setcchar (&cc, wstr, 0, 0, NULL); move(y, x); if (option_differences) { cchar_t oldc; wchar_t oldwstr[2]; attr_t attrs; short colors; in_wch(&oldc); getcchar(&oldc, oldwstr, &attrs, &colors, NULL); attr = !first_screen && (wstr[0] != oldwstr[0] || (option_differences_cumulative && attrs)); } if (attr) standout(); add_wch(&cc); if (attr) standend(); c_width = wcwidth(c); if (c_width > 1) x += c_width - 1; } oldeolseen = eolseen; } pclose(p); first_screen = 0; refresh(); usleep(interval * 1000000); } endwin(); return 0; }