Skip to content
Snippets Groups Projects
js_uifc.c 39.8 KiB
Newer Older
/* Synchronet "uifc" (user interface) object */
Rob Swindell's avatar
Rob Swindell committed

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/
#ifndef JAVASCRIPT
#define JAVASCRIPT
#endif
#include "sbbs.h"
#include "uifc.h"
#include "ciolib.h"
struct showbuf_ctx_private {
	int bar;
	int left;
	int top;
	int width;
	int height;
};
struct getstrxy_ctx_private {
	PROP_CUR
	, PROP_BAR
	, PROP_LEFT
	, PROP_TOP
	, PROP_WIDTH
	, PROP_HEIGHT
	, PROP_LASTKEY
};
static JSBool js_list_ctx_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
	jsval                    idval;
	jsint                    tiny;
	struct list_ctx_private* p;
	if ((p = (struct list_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
	switch (tiny) {
			*vp = INT_TO_JSVAL(p->cur);
			*vp = INT_TO_JSVAL(p->bar);
			*vp = INT_TO_JSVAL(p->left);
			*vp = INT_TO_JSVAL(p->top);
			*vp = INT_TO_JSVAL(p->width);
			break;
	}
	return JS_TRUE;
}
static JSBool js_list_ctx_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
{
	jsval                    idval;
	jsint                    tiny;
	int32                    i = 0;
	struct list_ctx_private* p;
	if ((p = (struct list_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
	if (!JS_ValueToInt32(cx, *vp, &i))
static JSBool js_showbuf_ctx_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
	jsval                       idval;
	jsint                       tiny;
	struct showbuf_ctx_private* p;
	if ((p = (struct showbuf_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
			*vp = INT_TO_JSVAL(p->cur);
			break;
		case PROP_BAR:
			*vp = INT_TO_JSVAL(p->bar);
			break;
		case PROP_LEFT:
			*vp = INT_TO_JSVAL(p->left);
			break;
		case PROP_TOP:
			*vp = INT_TO_JSVAL(p->top);
			break;
		case PROP_WIDTH:
			*vp = INT_TO_JSVAL(p->width);
			break;
		case PROP_HEIGHT:
			*vp = INT_TO_JSVAL(p->height);
			break;
	}
	return JS_TRUE;
}
static JSBool js_showbuf_ctx_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
{
	jsval                       idval;
	jsint                       tiny;
	int32                       i = 0;
	struct showbuf_ctx_private* p;
	if ((p = (struct showbuf_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
	if (!JS_ValueToInt32(cx, *vp, &i))
		return JS_FALSE;
			break;
		case PROP_BAR:
			break;
		case PROP_LEFT:
			break;
		case PROP_TOP:
			break;
		case PROP_WIDTH:
			break;
		case PROP_HEIGHT:
			break;
	}
	return JS_TRUE;
}
static JSBool js_getstrxy_ctx_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
	jsval                        idval;
	jsint                        tiny;
	struct getstrxy_ctx_private* p;
	if ((p = (struct getstrxy_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
		case PROP_LASTKEY:
			*vp = INT_TO_JSVAL(p->lastkey);
			break;
	}
	return JS_TRUE;
}
static JSBool js_getstrxy_ctx_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
{
	jsval                        idval;
	jsint                        tiny;
	int32                        i = 0;
	struct getstrxy_ctx_private* p;
	if ((p = (struct getstrxy_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
	if (!JS_ValueToInt32(cx, *vp, &i))
		return JS_FALSE;
		case PROP_LASTKEY:
static const char* uifc_list_ctx_prop_desc[] = {
	"Currently selected item"
	, "0-based Line number in the currently displayed set that is highlighted"
	, "left column"
	, "top line"
	, "forced width"
	, NULL
static const char* uifc_showbuf_ctx_prop_desc[] = {
	"Currently selected item"
	, "0-based Line number in the currently displayed set that is highlighted"
	, "left column"
	, "top line"
	, "forced width"
	, "forced height"
	, NULL
Deucе's avatar
Deucе committed
static const char* uifc_getstrxy_ctx_prop_desc[] = {
	"Last pressed key"
	, NULL
Deucе's avatar
Deucе committed
static void
js_list_ctx_finalize(JSContext *cx, JSObject *obj)
{
	struct list_ctx_private* p;
	if ((p = (struct list_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_SetPrivate(cx, obj, NULL);
Deucе's avatar
Deucе committed
static void
js_showbuf_ctx_finalize(JSContext *cx, JSObject *obj)
{
	struct showbuf_ctx_private* p;
	if ((p = (struct showbuf_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_SetPrivate(cx, obj, NULL);
Deucе's avatar
Deucе committed
static void
js_getstrxy_ctx_finalize(JSContext *cx, JSObject *obj)
{
	struct getstrxy_ctx_private* p;
	if ((p = (struct getstrxy_ctx_private*)JS_GetPrivate(cx, obj)) == NULL)
	JS_SetPrivate(cx, obj, NULL);
static JSClass            js_uifc_list_ctx_class = {
	"CTX"                   /* name			*/
	, JSCLASS_HAS_PRIVATE    /* flags		*/
	, JS_PropertyStub        /* addProperty	*/
	, JS_PropertyStub        /* delProperty	*/
	, js_list_ctx_get        /* getProperty	*/
	, js_list_ctx_set        /* setProperty	*/
	, JS_EnumerateStub       /* enumerate	*/
	, JS_ResolveStub         /* resolve		*/
	, JS_ConvertStub         /* convert		*/
	, js_list_ctx_finalize   /* finalize		*/
static JSClass            js_uifc_showbuf_ctx_class = {
	"CTX"                   /* name			*/
	, JSCLASS_HAS_PRIVATE    /* flags		*/
	, JS_PropertyStub        /* addProperty	*/
	, JS_PropertyStub        /* delProperty	*/
	, js_showbuf_ctx_get     /* getProperty	*/
	, js_showbuf_ctx_set     /* setProperty	*/
	, JS_EnumerateStub       /* enumerate	*/
	, JS_ResolveStub         /* resolve		*/
	, JS_ConvertStub         /* convert		*/
	, js_showbuf_ctx_finalize    /* finalize		*/
static JSClass            js_uifc_getstrxy_ctx_class = {
	"CTX"                   /* name			*/
	, JSCLASS_HAS_PRIVATE    /* flags		*/
	, JS_PropertyStub        /* addProperty	*/
	, JS_PropertyStub        /* delProperty	*/
	, js_getstrxy_ctx_get    /* getProperty	*/
	, js_getstrxy_ctx_set    /* setProperty	*/
	, JS_EnumerateStub       /* enumerate	*/
	, JS_ResolveStub         /* resolve		*/
	, JS_ConvertStub         /* convert		*/
	, js_getstrxy_ctx_finalize   /* finalize		*/
static jsSyncPropertySpec js_uifc_list_class_properties[] = {
/*       name			,tinyid                 ,flags,             ver */
	{   "cur", PROP_CUR, JSPROP_ENUMERATE,  317 },
	{   "bar", PROP_BAR, JSPROP_ENUMERATE,  317 },
	{   "left", PROP_LEFT, JSPROP_ENUMERATE,  31802 },
	{   "top", PROP_TOP, JSPROP_ENUMERATE,  31802 },
	{   "width", PROP_WIDTH, JSPROP_ENUMERATE,  31802 },
	{0}
};
static jsSyncPropertySpec js_uifc_showbuf_class_properties[] = {
/*       name           ,tinyid                 ,flags,             ver */
	{   "cur", PROP_CUR, JSPROP_ENUMERATE,  31802 },
	{   "bar", PROP_BAR, JSPROP_ENUMERATE,  31802 },
	{   "left", PROP_LEFT, JSPROP_ENUMERATE,  31802 },
	{   "top", PROP_TOP, JSPROP_ENUMERATE,  31802 },
	{   "width", PROP_WIDTH, JSPROP_ENUMERATE,  31802 },
	{   "height", PROP_HEIGHT, JSPROP_ENUMERATE,  31802 },
	{0}
};
static jsSyncPropertySpec js_uifc_getstrxy_class_properties[] = {
/*       name           ,tinyid                 ,flags,             ver */
	{   "lastkey", PROP_LASTKEY, JSPROP_ENUMERATE,  31802 },
	{0}
};
/* Constructor */
static JSBool js_list_ctx_constructor(JSContext *cx, uintN argc, jsval *arglist)
{
	jsval *                  argv = JS_ARGV(cx, arglist);
	JSObject *               obj = JS_THIS_OBJECT(cx, arglist);
	struct list_ctx_private* p;
	obj = JS_NewObject(cx, &js_uifc_list_ctx_class, NULL, NULL);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
	if ((p = (struct list_ctx_private *)calloc(1, sizeof(struct list_ctx_private))) == NULL) {
		JS_ReportError(cx, "calloc failed");
		return JS_FALSE;
	}
	if (!JS_SetPrivate(cx, obj, p)) {
		JS_ReportError(cx, "JS_SetPrivate failed");
		return JS_FALSE;
	}
	p->bar = INT_MAX;
	if (argc > 0 && JSVAL_IS_NUMBER(argv[0]))
		p->cur = JSVAL_TO_INT(argv[0]);
	if (argc > 1 && JSVAL_IS_NUMBER(argv[1]))
		p->bar = JSVAL_TO_INT(argv[1]);
	if (argc > 2 && JSVAL_IS_NUMBER(argv[2]))
		p->left = JSVAL_TO_INT(argv[2]);
	if (argc > 3 && JSVAL_IS_NUMBER(argv[3]))
		p->top = JSVAL_TO_INT(argv[3]);
	if (argc > 4 && JSVAL_IS_NUMBER(argv[4]))
		p->width = JSVAL_TO_INT(argv[4]);
	js_SyncResolve(cx, obj, NULL, js_uifc_list_class_properties, NULL, NULL, 0);
#ifdef BUILD_JSDOCS
	js_DescribeSyncObject(cx, obj, "Class used to retain UIFC list menu context", 317);
	js_DescribeSyncConstructor(cx, obj, "To create a new UIFCListContext object: <tt>var ctx = new UIFCListContext();</tt>");
	js_CreateArrayOfStrings(cx, obj, "_property_desc_list", uifc_list_ctx_prop_desc, JSPROP_READONLY);
#endif
	return JS_TRUE;
}
static JSBool js_showbuf_ctx_constructor(JSContext *cx, uintN argc, jsval *arglist)
{
	jsval *                     argv = JS_ARGV(cx, arglist);
	JSObject *                  obj = JS_THIS_OBJECT(cx, arglist);
	struct showbuf_ctx_private* p;
	obj = JS_NewObject(cx, &js_uifc_showbuf_ctx_class, NULL, NULL);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
	if ((p = (struct showbuf_ctx_private *)calloc(1, sizeof(struct showbuf_ctx_private))) == NULL) {
		JS_ReportError(cx, "calloc failed");
		return JS_FALSE;
	}
	p->height = INT_MAX;
	p->width = INT_MAX;
	if (argc > 0 && JSVAL_IS_NUMBER(argv[0]))
		p->cur = JSVAL_TO_INT(argv[0]);
	if (argc > 1 && JSVAL_IS_NUMBER(argv[1]))
		p->bar = JSVAL_TO_INT(argv[1]);
	if (argc > 2 && JSVAL_IS_NUMBER(argv[2]))
		p->left = JSVAL_TO_INT(argv[2]);
	if (argc > 3 && JSVAL_IS_NUMBER(argv[3]))
		p->top = JSVAL_TO_INT(argv[3]);
	if (argc > 4 && JSVAL_IS_NUMBER(argv[4]))
		p->width = JSVAL_TO_INT(argv[4]);
	if (argc > 5 && JSVAL_IS_NUMBER(argv[5]))
		p->height = JSVAL_TO_INT(argv[5]);
	if (!JS_SetPrivate(cx, obj, p)) {
		JS_ReportError(cx, "JS_SetPrivate failed");
		return JS_FALSE;
	}
	js_SyncResolve(cx, obj, NULL, js_uifc_showbuf_class_properties, NULL, NULL, 0);
#ifdef BUILD_JSDOCS
	js_DescribeSyncObject(cx, obj, "Class used to retain UIFC showbuf context", 317);
	js_DescribeSyncConstructor(cx, obj, "To create a new UIFCShowbufContext object: <tt>var ctx = new UIFCShowbufContext();</tt>");
	js_CreateArrayOfStrings(cx, obj, "_property_desc_list", uifc_showbuf_ctx_prop_desc, JSPROP_READONLY);
#endif
	return JS_TRUE;
}
static JSBool js_getstrxy_ctx_constructor(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject *                   obj = JS_THIS_OBJECT(cx, arglist);
	struct getstrxy_ctx_private* p;
	obj = JS_NewObject(cx, &js_uifc_getstrxy_ctx_class, NULL, NULL);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(obj));
	if ((p = (struct getstrxy_ctx_private *)calloc(1, sizeof(struct getstrxy_ctx_private))) == NULL) {
		JS_ReportError(cx, "calloc failed");
		return JS_FALSE;
	}
	if (!JS_SetPrivate(cx, obj, p)) {
		JS_ReportError(cx, "JS_SetPrivate failed");
		return JS_FALSE;
	}
	js_SyncResolve(cx, obj, NULL, js_uifc_getstrxy_class_properties, NULL, NULL, 0);
#ifdef BUILD_JSDOCS
	js_DescribeSyncObject(cx, obj, "Class used to retain UIFC getstrxy context", 317);
	js_DescribeSyncConstructor(cx, obj, "To create a new UIFCGetStrXYContext object: <tt>var ctx = new UIFCGetStrXYContext();</tt>");
Deucе's avatar
Deucе committed
	js_CreateArrayOfStrings(cx, obj, "_property_desc_list", uifc_getstrxy_ctx_prop_desc, JSPROP_READONLY);
#endif
	return JS_TRUE;
}
/* Properties */
enum {
	PROP_INITIALIZED    /* read-only */
	, PROP_MODE
	, PROP_CHANGES
	, PROP_SAVNUM
	, PROP_SCRN_LEN
	, PROP_SCRN_WIDTH
	, PROP_ESC_DELAY
	, PROP_HELPBUF
	, PROP_HCOLOR
	, PROP_LCOLOR
	, PROP_BCOLOR
	, PROP_CCOLOR
	, PROP_LBCOLOR
	, PROP_LIST_HEIGHT
static JSBool js_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
	jsval      idval;
	jsint      tiny;
	uifcapi_t* uifc;
	if ((uifc = (uifcapi_t*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
	switch (tiny) {
			*vp = BOOLEAN_TO_JSVAL(uifc->initialized);
		case PROP_MODE:
			*vp = UINT_TO_JSVAL(uifc->mode);
			break;
		case PROP_CHANGES:
			*vp = BOOLEAN_TO_JSVAL(uifc->changes);
			break;
		case PROP_SAVNUM:
			*vp = INT_TO_JSVAL(uifc->savnum);
			break;
		case PROP_SCRN_LEN:
			*vp = INT_TO_JSVAL(uifc->scrn_len);
			break;
		case PROP_SCRN_WIDTH:
			*vp = INT_TO_JSVAL(uifc->scrn_width);
			break;
		case PROP_ESC_DELAY:
			*vp = INT_TO_JSVAL(uifc->esc_delay);
			break;
		case PROP_HELPBUF:
			*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, uifc->helpbuf));
			break;
		case PROP_HCOLOR:
			*vp = INT_TO_JSVAL(uifc->hclr);
			break;
		case PROP_LCOLOR:
			*vp = INT_TO_JSVAL(uifc->lclr);
			break;
		case PROP_BCOLOR:
			*vp = INT_TO_JSVAL(uifc->bclr);
			break;
		case PROP_CCOLOR:
			*vp = INT_TO_JSVAL(uifc->cclr);
			break;
		case PROP_LBCOLOR:
			*vp = INT_TO_JSVAL(uifc->lbclr);
			break;
		case PROP_LIST_HEIGHT:
			*vp = INT_TO_JSVAL(uifc->list_height);
static JSBool js_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
	jsval      idval;
	jsint      tiny;
	int32      i = 0;
	uifcapi_t* uifc;
	if ((uifc = (uifcapi_t*)JS_GetPrivate(cx, obj)) == NULL)
	JS_IdToValue(cx, id, &idval);
	tiny = JSVAL_TO_INT(idval);
	if (tiny == PROP_CHANGES)
		return JS_ValueToBoolean(cx, *vp, &uifc->changes);
	else if (tiny == PROP_HELPBUF) {
		if (uifc->helpbuf)
deuce's avatar
deuce committed
			free(uifc->helpbuf);
deuce's avatar
deuce committed
		JSVALUE_TO_MSTRING(cx, *vp, uifc->helpbuf, NULL);
	if (!JS_ValueToInt32(cx, *vp, &i))
			break;
		case PROP_SAVNUM:
			if (i == uifc->savnum - 1 && uifc->restore != NULL)
			break;
		case PROP_SCRN_LEN:
			uifc->scrn_len = i;
			break;
		case PROP_SCRN_WIDTH:
			uifc->scrn_width = i;
			break;
		case PROP_ESC_DELAY:
			uifc->esc_delay = i;
			break;
		case PROP_LIST_HEIGHT:
			uifc->list_height = i;
			break;
		case PROP_HCOLOR:
			uifc->hclr = (char)i;
		case PROP_LCOLOR:
			uifc->lclr = (char)i;
		case PROP_BCOLOR:
			uifc->bclr = (char)i;
		case PROP_CCOLOR:
			uifc->cclr = (char)i;
		case PROP_LBCOLOR:
			uifc->lbclr = (char)i;
}
static jsSyncPropertySpec js_properties[] = {
/*		 name,				tinyid,						flags,		ver	*/
	{   "initialized",      PROP_INITIALIZED,   JSPROP_ENUMERATE | JSPROP_READONLY, 314 },
	{   "mode",             PROP_MODE,          JSPROP_ENUMERATE,   314 },
	{   "changes",          PROP_CHANGES,       JSPROP_ENUMERATE,   314 },
	{   "save_num",         PROP_SAVNUM,        JSPROP_ENUMERATE,   314 },
	{   "screen_length",    PROP_SCRN_LEN,      JSPROP_ENUMERATE,   314 },
	{   "screen_width",     PROP_SCRN_WIDTH,    JSPROP_ENUMERATE,   314 },
	{   "list_height",      PROP_LIST_HEIGHT,   JSPROP_ENUMERATE,   314 },
	{   "esc_delay",        PROP_ESC_DELAY,     JSPROP_ENUMERATE,   314 },
	{   "help_text",        PROP_HELPBUF,       JSPROP_ENUMERATE,   314 },
	{   "background_color", PROP_BCOLOR,        JSPROP_ENUMERATE,   314 },
	{   "frame_color",      PROP_HCOLOR,        JSPROP_ENUMERATE,   314 },
	{   "text_color",       PROP_LCOLOR,        JSPROP_ENUMERATE,   314 },
	{   "inverse_color",    PROP_CCOLOR,        JSPROP_ENUMERATE,   314 },
	{   "lightbar_color",   PROP_LBCOLOR,       JSPROP_ENUMERATE,   314 },
deuce's avatar
deuce committed
#ifdef BUILD_JSDOCS
static const char*        uifc_prop_desc[] = {
	"UIFC library has been successfully initialized"
	, "Current mode flags (see <tt>uifcdefs.js</tt>)"
	, "A change has occurred in an input call.  You are expected to set this to false before calling the input if you care about it."
	, "Save buffer depth (advanced)"
	, "Current screen length"
	, "Current screen width"
	, "When <tt>WIN_FIXEDHEIGHT</tt> mode flag is set, specifies the height used by a list method"
	, "Delay before a single ESC char is parsed and assumed to not be an ANSI sequence (advanced)"
	, "Text that will be displayed when F1 or '?' keys are pressed"
	, "Background colour"
	, "Frame colour"
	, "Text colour"
	, "Inverse colour"
	, "Lightbar colour"
	, NULL
deuce's avatar
deuce committed
};
#endif
/* Convenience functions */
static uifcapi_t* get_uifc(JSContext *cx, JSObject *obj)
{
	uifcapi_t* uifc;
	if ((uifc = (uifcapi_t*)JS_GetPrivate(cx, obj)) == NULL)
	if (!uifc->initialized) {
		JS_ReportError(cx, "UIFC not initialized");
js_uifc_init(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *  obj = JS_THIS_OBJECT(cx, arglist);
	jsval *     argv = JS_ARGV(cx, arglist);
	int         ciolib_mode = CIOLIB_MODE_AUTO;
	const char* title_def = "Synchronet";
	char*       title = (char *)title_def;
	char*       mode;
	uifcapi_t*  uifc;
	jsrefcount  rc;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if ((uifc = (uifcapi_t*)JS_GetPrivate(cx, obj)) == NULL)
deuce's avatar
deuce committed
		JSVALUE_TO_MSTRING(cx, argv[0], title, NULL);
		HANDLE_PENDING(cx, title);
		JSVALUE_TO_ASTRING(cx, argv[1], mode, 16, NULL);
		if (mode != NULL) {
			if (!stricmp(mode, "STDIO"))
				ciolib_mode = -1;
			else if (!stricmp(mode, "AUTO"))
				ciolib_mode = CIOLIB_MODE_AUTO;
			else if (!stricmp(mode, "X"))
				ciolib_mode = CIOLIB_MODE_X;
			else if (!stricmp(mode, "CURSES"))
				ciolib_mode = CIOLIB_MODE_CURSES;
			else if (!stricmp(mode, "CURSES_IBM"))
				ciolib_mode = CIOLIB_MODE_CURSES_IBM;
			else if (!stricmp(mode, "CURSES_ASCII"))
				ciolib_mode = CIOLIB_MODE_CURSES_ASCII;
			else if (!stricmp(mode, "ANSI"))
				ciolib_mode = CIOLIB_MODE_ANSI;
			else if (!stricmp(mode, "CONIO"))
				ciolib_mode = CIOLIB_MODE_CONIO;
			else if (!stricmp(mode, "SDL"))
				ciolib_mode = CIOLIB_MODE_SDL;
	rc = JS_SUSPENDREQUEST(cx);
	if (ciolib_mode == -1) {
		if (uifcinix(uifc)) {
			if (title != title_def)
deuce's avatar
deuce committed
				free(title);
		if (initciolib(ciolib_mode)) {
			if (title != title_def)
deuce's avatar
deuce committed
				free(title);
		if (uifcini32(uifc)) {
			if (title != title_def)
deuce's avatar
deuce committed
				free(title);
	JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
	if (title != title_def)
deuce's avatar
deuce committed
		free(title);
js_uifc_bail(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
	rc = JS_SUSPENDREQUEST(cx);
deuce's avatar
deuce committed
static JSBool
js_uifc_showhelp(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
deuce's avatar
deuce committed
	uifcapi_t* uifc;
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
	rc = JS_SUSPENDREQUEST(cx);
deuce's avatar
deuce committed
	uifc->showhelp();
	JS_RESUMEREQUEST(cx, rc);
deuce's avatar
deuce committed
}
js_uifc_msg(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      str = NULL;
	uifcapi_t* uifc;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
deuce's avatar
deuce committed
	JSVALUE_TO_MSTRING(cx, argv[0], str, NULL);
	HANDLE_PENDING(cx, str);
	rc = JS_SUSPENDREQUEST(cx);
deuce's avatar
deuce committed
	free(str);
js_uifc_pop(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      str = NULL;
	uifcapi_t* uifc;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
deuce's avatar
deuce committed
		JSVALUE_TO_MSTRING(cx, argv[0], str, NULL);
		HANDLE_PENDING(cx, str);
	rc = JS_SUSPENDREQUEST(cx);
deuce's avatar
deuce committed
		free(str);
js_uifc_input(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      str;
	char*      org = NULL;
	char*      prompt = NULL;
	int32      maxlen = 0;
	int32      left = 0;
	int32      top = 0;
	int32      mode = 0;
	int32      kmode = 0;
	uifcapi_t* uifc;
	uintN      argn = 0;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
	if (argn < argc && JSVAL_IS_NUMBER(argv[argn])
	    && !JS_ValueToInt32(cx, argv[argn++], &mode))
	if (argn < argc && JSVAL_IS_NUMBER(argv[argn])
	    && !JS_ValueToInt32(cx, argv[argn++], &left))
	if (argn < argc && JSVAL_IS_NUMBER(argv[argn])
	    && !JS_ValueToInt32(cx, argv[argn++], &top))
	if (argn < argc && JSVAL_IS_STRING(argv[argn])) {
		JSVALUE_TO_MSTRING(cx, argv[argn], prompt, NULL);
		argn++;
		HANDLE_PENDING(cx, prompt);
		if (prompt == NULL)
	if (argn < argc && JSVAL_IS_STRING(argv[argn])) {
		JSVALUE_TO_MSTRING(cx, argv[argn], org, NULL);
		argn++;
		if (JS_IsExceptionPending(cx)) {
			if (prompt)
deuce's avatar
deuce committed
				free(prompt);
			return JS_FALSE;
		}
		if (org == NULL) {
			if (prompt)
				free(prompt);
	if (argn < argc && JSVAL_IS_NUMBER(argv[argn])
	    && !JS_ValueToInt32(cx, argv[argn++], &maxlen)) {
		if (prompt)
deuce's avatar
deuce committed
			free(prompt);
deuce's avatar
deuce committed
			free(org);
	if (argn < argc && JSVAL_IS_NUMBER(argv[argn])
	    && !JS_ValueToInt32(cx, argv[argn++], &kmode)) {
		if (prompt)
deuce's avatar
deuce committed
			free(prompt);
deuce's avatar
deuce committed
			free(org);
	if (!maxlen)
		maxlen = 40;
	if ((str = (char*)malloc(maxlen + 1)) == NULL) {
		if (prompt)
deuce's avatar
deuce committed
			free(prompt);
deuce's avatar
deuce committed
			free(org);
	memset(str, 0, maxlen + 1);
	if (org) {
		strncpy(str, org, maxlen);
deuce's avatar
deuce committed
		free(org);
	}
	rc = JS_SUSPENDREQUEST(cx);
	if (uifc->input(mode, left, top, prompt, str, maxlen, kmode) < 0) {
deuce's avatar
deuce committed
			free(prompt);
deuce's avatar
deuce committed
			free(str);
deuce's avatar
deuce committed
		free(prompt);
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str)));
	if (str)
js_uifc_list(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *               obj = JS_THIS_OBJECT(cx, arglist);
	jsval *                  argv = JS_ARGV(cx, arglist);
	char*                    title = NULL;
	int32                    left = 0;
	int32                    top = 0;
	int32                    width = 0;
	int32                    dflt = 0;
	int32 *                  dptr = &dflt;
	int32                    bar = 0;
	int32 *                  bptr = &bar;
	int32                    mode = 0;
	JSObject*                objarg;
	uifcapi_t*               uifc;
	uintN                    argn = 0;
	jsval                    val;
	jsuint                   i;
	jsuint                   numopts;
	str_list_t               opts = NULL;
	char *                   opt = NULL;
	size_t                   opt_sz = 0;
	jsrefcount               rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
	if (argn < argc && JSVAL_IS_NUMBER(argv[argn])
	    && !JS_ValueToInt32(cx, argv[argn++], &mode))
	for (; argn < argc; argn++) {
		if (JSVAL_IS_STRING(argv[argn])) {
			free(title);
			JSVALUE_TO_MSTRING(cx, argv[argn], title, NULL);
			HANDLE_PENDING(cx, title);
		if (!JSVAL_IS_OBJECT(argv[argn]))
		if ((objarg = JSVAL_TO_OBJECT(argv[argn])) == NULL) {
			free(title);
		if (JS_IsArrayObject(cx, objarg)) {
			if (!JS_GetArrayLength(cx, objarg, &numopts)) {
				free(title);
			if (opts == NULL)
				opts = strListInit();
			for (i = 0; i < numopts; i++) {
				if (!JS_GetElement(cx, objarg, i, &val))
deuce's avatar
deuce committed
				JSVALUE_TO_RASTRING(cx, val, opt, &opt_sz, NULL);
				if (JS_IsExceptionPending(cx)) {
					if (title)
deuce's avatar
deuce committed
						free(title);
				}
				strListPush(&opts, opt);
			FREE_AND_NULL(opt);
		else if (JS_GetClass(cx, objarg) == &js_uifc_list_ctx_class) {
			p = JS_GetPrivate(cx, objarg);
			if (p != NULL) {
				dptr = &(p->cur);
				bptr = &(p->bar);
				left = p->left;
				top = p->top;
				width = p->width;
			}
		}
	if (title == NULL || opts == NULL) {
		JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
		rc = JS_SUSPENDREQUEST(cx);
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(uifc->list(mode | WIN_BLANKOPTS, left, top, width, (int*)dptr, (int*)bptr, title, opts)));
		free(title);
static JSBool
js_uifc_scrn(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      str = NULL;
	uifcapi_t* uifc;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
	JSVALUE_TO_MSTRING(cx, argv[0], str, NULL);
	HANDLE_PENDING(cx, str);
	rc = JS_SUSPENDREQUEST(cx);
	uifc->scrn(str);
	free(str);
	JS_RESUMEREQUEST(cx, rc);
}
static JSBool
js_uifc_timedisplay(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	JSBool     force = JS_FALSE;
	uifcapi_t* uifc;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
	if (argc > 0)
		force = JSVAL_TO_BOOLEAN(argv[0]);
	rc = JS_SUSPENDREQUEST(cx);
	uifc->timedisplay(force);
	JS_RESUMEREQUEST(cx, rc);
}
static JSBool
js_uifc_bottomline(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	int        mode;
	uifcapi_t* uifc;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);
	if ((uifc = get_uifc(cx, obj)) == NULL)
	if (argc == 0) {
		JS_ReportError(cx, "No mode specified");
	}
	mode = JSVAL_TO_INT(argv[0]);
	rc = JS_SUSPENDREQUEST(cx);
	uifc->bottomline(mode);
	JS_RESUMEREQUEST(cx, rc);
}
static JSBool
js_uifc_getstrxy(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject *                   obj = JS_THIS_OBJECT(cx, arglist);
	jsval *                      argv = JS_ARGV(cx, arglist);
	char*                        str;
	char*                        org = NULL;
	int32                        left = 0;
	int32                        top = 0;
	int32                        width = 0;
	int32                        maxlen = 0;
	int32                        mode = 0;
	uifcapi_t*                   uifc;