/* PDCurses */12#include <curspriv.h>34/*man-start**************************************************************56util7----89### Synopsis1011char *unctrl(chtype c);12void filter(void);13void use_env(bool x);14int delay_output(int ms);1516int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs,17short *color_pair, void *opts);18int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs,19short color_pair, const void *opts);20wchar_t *wunctrl(cchar_t *wc);2122int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n);23size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n);24size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n);2526### Description2728unctrl() expands the text portion of the chtype c into a printable29string. Control characters are changed to the "^X" notation; others30are passed through. wunctrl() is the wide-character version of the31function.3233filter() and use_env() are no-ops in PDCurses.3435delay_output() inserts an ms millisecond pause in output.3637getcchar() works in two modes: When wch is not NULL, it reads the38cchar_t pointed to by wcval and stores the attributes in attrs, the39color pair in color_pair, and the text in the wide-character string40wch. When wch is NULL, getcchar() merely returns the number of wide41characters in wcval. In either mode, the opts argument is unused.4243setcchar constructs a cchar_t at wcval from the wide-character text44at wch, the attributes in attr and the color pair in color_pair. The45opts argument is unused.4647Currently, the length returned by getcchar() is always 1 or 0.48Similarly, setcchar() will only take the first wide character from49wch, and ignore any others that it "should" take (i.e., combining50characters). Nor will it correctly handle any character outside the51basic multilingual plane (UCS-2).5253### Return Value5455wunctrl() returns NULL on failure. delay_output() always returns OK.5657getcchar() returns the number of wide characters wcval points to when58wch is NULL; when it's not, getcchar() returns OK or ERR.5960setcchar() returns OK or ERR.6162### Portability63X/Open ncurses NetBSD64unctrl Y Y Y65filter Y Y Y66use_env Y Y Y67delay_output Y Y Y68getcchar Y Y Y69setcchar Y Y Y70wunctrl Y Y Y71PDC_mbtowc - - -72PDC_mbstowcs - - -73PDC_wcstombs - - -7475**man-end****************************************************************/7677#include <stdlib.h>78#include <string.h>7980char *unctrl(chtype c)81{82static char strbuf[3] = {0, 0, 0};8384chtype ic;8586PDC_LOG(("unctrl() - called\n"));8788ic = c & A_CHARTEXT;8990if (ic >= 0x20 && ic != 0x7f) /* normal characters */91{92strbuf[0] = (char)ic;93strbuf[1] = '\0';94return strbuf;95}9697strbuf[0] = '^'; /* '^' prefix */9899if (ic == 0x7f) /* 0x7f == DEL */100strbuf[1] = '?';101else /* other control */102strbuf[1] = (char)(ic + '@');103104return strbuf;105}106107void filter(void)108{109PDC_LOG(("filter() - called\n"));110}111112void use_env(bool x)113{114PDC_LOG(("use_env() - called: x %d\n", x));115}116117int delay_output(int ms)118{119PDC_LOG(("delay_output() - called: ms %d\n", ms));120121return napms(ms);122}123124#ifdef PDC_WIDE125int getcchar(const cchar_t *wcval, wchar_t *wch, attr_t *attrs,126short *color_pair, void *opts)127{128if (!wcval)129return ERR;130131if (wch)132{133if (!attrs || !color_pair)134return ERR;135136*wch = (*wcval & A_CHARTEXT);137*attrs = (*wcval & (A_ATTRIBUTES & ~A_COLOR));138*color_pair = PAIR_NUMBER(*wcval & A_COLOR);139140if (*wch)141*++wch = L'\0';142143return OK;144}145else146return ((*wcval & A_CHARTEXT) != L'\0');147}148149int setcchar(cchar_t *wcval, const wchar_t *wch, const attr_t attrs,150short color_pair, const void *opts)151{152if (!wcval || !wch)153return ERR;154155*wcval = *wch | attrs | COLOR_PAIR(color_pair);156157return OK;158}159160wchar_t *wunctrl(cchar_t *wc)161{162static wchar_t strbuf[3] = {0, 0, 0};163164cchar_t ic;165166PDC_LOG(("wunctrl() - called\n"));167168if (!wc)169return NULL;170171ic = *wc & A_CHARTEXT;172173if (ic >= 0x20 && ic != 0x7f) /* normal characters */174{175strbuf[0] = (wchar_t)ic;176strbuf[1] = L'\0';177return strbuf;178}179180strbuf[0] = '^'; /* '^' prefix */181182if (ic == 0x7f) /* 0x7f == DEL */183strbuf[1] = '?';184else /* other control */185strbuf[1] = (wchar_t)(ic + '@');186187return strbuf;188}189190int PDC_mbtowc(wchar_t *pwc, const char *s, size_t n)191{192# ifdef PDC_FORCE_UTF8193wchar_t key;194int i = -1;195const unsigned char *string;196197if (!s || (n < 1))198return -1;199200if (!*s)201return 0;202203string = (const unsigned char *)s;204205key = string[0];206207/* Simplistic UTF-8 decoder -- only does the BMP, minimal validation */208209if (key & 0x80)210{211if ((key & 0xe0) == 0xc0)212{213if (1 < n)214{215key = ((key & 0x1f) << 6) | (string[1] & 0x3f);216i = 2;217}218}219else if ((key & 0xe0) == 0xe0)220{221if (2 < n)222{223key = ((key & 0x0f) << 12) | ((string[1] & 0x3f) << 6) |224(string[2] & 0x3f);225i = 3;226}227}228}229else230i = 1;231232if (i)233*pwc = key;234235return i;236# else237return mbtowc(pwc, s, n);238# endif239}240241size_t PDC_mbstowcs(wchar_t *dest, const char *src, size_t n)242{243# ifdef PDC_FORCE_UTF8244size_t i = 0, len;245246if (!src || !dest)247return 0;248249len = strlen(src);250251while (*src && i < n)252{253int retval = PDC_mbtowc(dest + i, src, len);254255if (retval < 1)256return -1;257258src += retval;259len -= retval;260i++;261}262# else263size_t i = mbstowcs(dest, src, n);264# endif265dest[i] = 0;266return i;267}268269size_t PDC_wcstombs(char *dest, const wchar_t *src, size_t n)270{271# ifdef PDC_FORCE_UTF8272size_t i = 0;273274if (!src || !dest)275return 0;276277while (*src && i < n)278{279chtype code = *src++;280281if (code < 0x80)282{283dest[i] = code;284i++;285}286else287if (code < 0x800)288{289dest[i] = ((code & 0x07c0) >> 6) | 0xc0;290dest[i + 1] = (code & 0x003f) | 0x80;291i += 2;292}293else294{295dest[i] = ((code & 0xf000) >> 12) | 0xe0;296dest[i + 1] = ((code & 0x0fc0) >> 6) | 0x80;297dest[i + 2] = (code & 0x003f) | 0x80;298i += 3;299}300}301# else302size_t i = wcstombs(dest, src, n);303# endif304dest[i] = '\0';305return i;306}307#endif308309310