slk_wset(int i, const wchar_t *astr, int format) { int result = ERR; size_t arglen; const wchar_t *str; char *mystr; mbstate_t state; T((T_CALLED("slk_wset(%d, %s, %d)"), i, _nc_viswbuf(astr), format)); init_mb(state); str = astr; if ((arglen = wcsrtombs(NULL, &str, 0, &state)) != (size_t) -1) { if ((mystr = (char *) _nc_doalloc(0, arglen + 1)) != 0) { str = astr; if (wcsrtombs(mystr, &str, arglen, &state) != (size_t) -1) { /* glibc documentation claims that the terminating L'\0' * is written, but it is not... */ mystr[arglen] = 0; result = slk_set(i, mystr, format); } free(mystr); } } returnCode(result); }
NCURSES_SP_NAME(unget_wch) (NCURSES_SP_DCLx const wchar_t wch) { int result = OK; mbstate_t state; size_t length; int n; T((T_CALLED("unget_wch(%p, %#lx)"), (void *) SP_PARM, (unsigned long) wch)); init_mb(state); length = _nc_wcrtomb(0, wch, &state); if (length != (size_t) (-1) && length != 0) { char *string; if ((string = (char *) malloc(length)) != 0) { init_mb(state); /* ignore the result, since we already validated the character */ IGNORE_RC((int) wcrtomb(string, wch, &state)); for (n = (int) (length - 1); n >= 0; --n) { if (NCURSES_SP_NAME(ungetch) (NCURSES_SP_ARGx UChar(string[n])) !=OK) { result = ERR; break; } } free(string); } else { result = ERR; } } else { result = ERR; } returnCode(result); }
_nc_build_wch(WINDOW *win, ARG_CH_T ch) { char *buffer = WINDOW_EXT(win, addch_work); int len; int x = win->_curx; int y = win->_cury; mbstate_t state; wchar_t result; if ((WINDOW_EXT(win, addch_used) != 0) && (WINDOW_EXT(win, addch_x) != x || WINDOW_EXT(win, addch_y) != y)) { /* discard the incomplete multibyte character */ WINDOW_EXT(win, addch_used) = 0; TR(TRACE_VIRTPUT, ("Alert discarded multibyte on move (%d,%d) -> (%d,%d)", WINDOW_EXT(win, addch_y), WINDOW_EXT(win, addch_x), y, x)); } WINDOW_EXT(win, addch_x) = x; WINDOW_EXT(win, addch_y) = y; init_mb(state); buffer[WINDOW_EXT(win, addch_used)] = (char) CharOf(CHDEREF(ch)); WINDOW_EXT(win, addch_used) += 1; buffer[WINDOW_EXT(win, addch_used)] = '\0'; if ((len = (int) mbrtowc(&result, buffer, (size_t) WINDOW_EXT(win, addch_used), &state)) > 0) { attr_t attrs = AttrOf(CHDEREF(ch)); if_EXT_COLORS(int pair = GetPair(CHDEREF(ch))); SetChar(CHDEREF(ch), result, attrs); if_EXT_COLORS(SetPair(CHDEREF(ch), pair)); WINDOW_EXT(win, addch_used) = 0; } else if (len == -1) { /* * An error occurred. We could either discard everything, * or assume that the error was in the previous input. * Try the latter. */ TR(TRACE_VIRTPUT, ("Alert! mbrtowc returns error")); /* handle this with unctrl() */ WINDOW_EXT(win, addch_used) = 0; } return len; }
NCURSES_SP_NAME(slk_set) (NCURSES_SP_DCLx int i, const char *astr, int format) { SLK *slk; int offset; int numchrs; int numcols; int limit; const char *str = astr; const char *p; T((T_CALLED("slk_set(%p, %d, \"%s\", %d)"), (void *) SP_PARM, i, str, format)); if (SP_PARM == 0 || (slk = SP_PARM->_slk) == 0 || i < 1 || i > slk->labcnt || format < 0 || format > 2) returnCode(ERR); if (str == 0) str = ""; --i; /* Adjust numbering of labels */ limit = MAX_SKEY_LEN(SP_PARM->slk_format); while (isspace(UChar(*str))) str++; /* skip over leading spaces */ p = str; #if USE_WIDEC_SUPPORT numcols = 0; while (*p != 0) { mbstate_t state; wchar_t wc; size_t need; init_mb(state); need = mbrtowc(0, p, strlen(p), &state); if (need == (size_t) -1) break; mbrtowc(&wc, p, need, &state); if (!iswprint((wint_t) wc)) break; if (wcwidth(wc) + numcols > limit) break; numcols += wcwidth(wc); p += need; } numchrs = (p - str); #else while (isprint(UChar(*p))) p++; /* The first non-print stops */ numcols = (p - str); if (numcols > limit) numcols = limit; numchrs = numcols; #endif FreeIfNeeded(slk->ent[i].ent_text); if ((slk->ent[i].ent_text = strdup(str)) == 0) returnCode(ERR); slk->ent[i].ent_text[numchrs] = '\0'; if ((slk->ent[i].form_text = (char *) _nc_doalloc(slk->ent[i].form_text, (unsigned) (limit + numchrs + 1)) ) == 0) returnCode(ERR); switch (format) { default: case 0: /* left-justified */ offset = 0; break; case 1: /* centered */ offset = (limit - numcols) / 2; break; case 2: /* right-justified */ offset = limit - numcols; break; } if (offset <= 0) offset = 0; else memset(slk->ent[i].form_text, ' ', (unsigned) offset); memcpy(slk->ent[i].form_text + offset, slk->ent[i].ent_text, (unsigned) numchrs); if (offset < limit) { memset(slk->ent[i].form_text + offset + numchrs, ' ', (unsigned) (limit - (offset + numcols))); } slk->ent[i].form_text[numchrs - numcols + limit] = 0; slk->ent[i].dirty = TRUE; returnCode(OK); }