/* This is an inclusion for Curses.c */
/* Combined Normal/Wide-Character Functions */
/* April 2014, Edgar Fuß, Mathematisches Institut der Universität Bonn,
<ef@math.uni-bonn.de>
*/
XS(XS_CURSES_getchar) {
dXSARGS;
c_countargs("getchar", items, 0);
WINDOW *win = c_win ? c_sv2window(ST(0), 0) : stdscr;
if (c_x)
if (c_domove(win, ST(c_x-1), ST(c_x)) == ERR)
XSRETURN_UNDEF;
#ifdef C_GET_WCH
wint_t wch;
int ret = wget_wch(win, &wch);
if (ret == OK) {
ST(0) = sv_newmortal();
c_wchar2sv(ST(0), wch);
XSRETURN(1);
} else if (ret == KEY_CODE_YES) {
XST_mUNDEF(0);
ST(1) = sv_newmortal();
sv_setiv(ST(1), (IV)wch);
XSRETURN(2);
} else {
XSRETURN_UNDEF;
}
#else
int key = wgetch(win);
if (key == ERR) {
XSRETURN_UNDEF;
} else if (key < KEY_MIN) {
ST(0) = sv_newmortal();
c_wchar2sv(ST(0), key);
XSRETURN(1);
} else {
XST_mUNDEF(0);
ST(1) = sv_newmortal();
sv_setiv(ST(1), (IV)key);
XSRETURN(2);
}
#endif
}
XS(XS_CURSES_ungetchar) {
bool succeeded;
wchar_t wc;
dXSARGS;
c_exactargs("ungetchar", items, 1);
c_sv2GetWchar(ST(0), &wc, &succeeded);
if (!succeeded)
XSRETURN_NO;
#ifdef C_UNGET_WCH
int ret;
ret = unget_wch(wc);
if (ret == OK)
XSRETURN_YES;
else
XSRETURN_NO;
#else
if (wc > 0xff)
XSRETURN_NO;
else {
int ret;
ret = ungetch(wc);
if (ret == OK)
XSRETURN_YES;
else
XSRETURN_NO;
}
#endif
}
XS(XS_CURSES_getstring) {
dXSARGS;
c_countargs("getstring", items, 0);
WINDOW *win = c_win ? c_sv2window(ST(0), 0) : stdscr;
if (c_x)
if (c_domove(win, ST(c_x-1), ST(c_x)) == ERR)
XSRETURN_UNDEF;
#ifdef C_GETN_WSTR
wchar_t buf[1000];
if (wgetn_wstr(win, (wint_t *)buf, (sizeof buf/sizeof *buf) - 1) == ERR)
XSRETURN_UNDEF;
ST(0) = sv_newmortal();
c_wstr2sv(ST(0), buf);
XSRETURN(1);
#else
unsigned char buf[1000];
if (wgetnstr(win, (char *)buf, (sizeof buf/sizeof *buf) - 1) == ERR)
XSRETURN_UNDEF;
ST(0) = sv_newmortal();
c_bstr2sv(ST(0), buf);
XSRETURN(1);
#endif
}
XS(XS_CURSES_addstring) {
dXSARGS;
c_countargs("addstring", items, 1);
WINDOW *win = c_win ? c_sv2window(ST(0), 0) : stdscr;
if (c_x)
if (c_domove(win, ST(c_x-1), ST(c_x)) == ERR)
XSRETURN_NO;
#ifdef C_ADDNWSTR
int ret;
size_t len;
wchar_t *wstr = c_sv2wstr(ST(c_arg), &len);
if (wstr == NULL)
XSRETURN_NO;
ret = waddnwstr(win, wstr, len);
free(wstr);
if (ret == OK)
XSRETURN_YES;
else
XSRETURN_NO;
#else
int ret;
size_t len;
int need_free;
unsigned char *bstr = c_sv2bstr(ST(c_arg), &len, &need_free);
if (bstr == NULL)
XSRETURN_NO;
ret = waddnstr(win, (char *)bstr, len);
if (need_free) free(bstr);
if (ret == OK)
XSRETURN_YES;
else
XSRETURN_NO;
#endif
}
XS(XS_CURSES_insstring) {
dXSARGS;
c_countargs("insstring", items, 1);
WINDOW *win = c_win ? c_sv2window(ST(0), 0) : stdscr;
if (c_x)
if (c_domove(win, ST(c_x-1), ST(c_x)) == ERR)
XSRETURN_NO;
#ifdef C_INS_NWSTR
int ret;
size_t len;
wchar_t *wstr = c_sv2wstr(ST(c_arg), &len);
if (wstr == NULL)
XSRETURN_NO;
ret = wins_nwstr(win, wstr, len);
free(wstr);
if (ret == OK)
XSRETURN_YES;
else
XSRETURN_NO;
#else
int ret;
size_t len;
int need_free;
unsigned char *bstr = c_sv2bstr(ST(c_arg), &len, &need_free);
if (bstr == NULL)
XSRETURN_NO;
ret = winsnstr(win, (char *)bstr, len);
if (need_free) free(bstr);
if (ret == OK)
XSRETURN_YES;
else
XSRETURN_NO;
#endif
}
XS(XS_CURSES_instring) {
int x, y;
dXSARGS;
c_countargs("instring", items, 0);
WINDOW *win = c_win ? c_sv2window(ST(0), 0) : stdscr;
if (c_x)
if (c_domove(win, ST(c_x-1), ST(c_x)) == ERR)
XSRETURN_UNDEF;
getmaxyx(win, y, x); /* Macro: not &y, &x! */
#ifdef C_INNWSTR
int ret;
wchar_t *buf = malloc((x + 1) * sizeof *buf);
if (buf == NULL) croak("insstring: malloc");
ret = winnwstr(win, buf, x);
if (ret == ERR) {
free(buf);
XSRETURN_UNDEF;
}
ST(0) = sv_newmortal();
c_wstr2sv(ST(0), buf);
free(buf);
XSRETURN(1);
#else
int ret;
unsigned char *buf = malloc(x + 1);
if (buf == NULL) croak("insstring: malloc");
ret = winnstr(win, (char *)buf, x);
if (ret == ERR) {
free(buf);
XSRETURN_UNDEF;
}
ST(0) = sv_newmortal();
c_bstr2sv(ST(0), buf);
free(buf);
XSRETURN(1);
#endif
}