diff --git a/src/sbbs3/conobj.cpp b/src/sbbs3/conobj.cpp index 96407eefb72c81879510c057619aa7fcccaa75fe..e46628ac4dd671615c1ac68caf8e13cb3550f41f 100644 --- a/src/sbbs3/conobj.cpp +++ b/src/sbbs3/conobj.cpp @@ -39,7 +39,9 @@ #ifdef JAVASCRIPT +/*****************************/ /* Console Object Properites */ +/*****************************/ enum { CON_PROP_ONLINE ,CON_PROP_STATUS @@ -141,8 +143,288 @@ static JSBool js_console_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) return(JS_TRUE); } +#define CON_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY + +static struct JSPropertySpec js_console_properties[] = { +/* name ,tinyid ,flags ,getter,setter */ + + { "online" ,CON_PROP_ONLINE ,CON_PROP_FLAGS ,NULL,NULL}, + { "status" ,CON_PROP_STATUS ,CON_PROP_FLAGS ,NULL,NULL}, + { "line_counter" ,CON_PROP_LNCNTR ,CON_PROP_FLAGS ,NULL,NULL}, + { "top_of_screen" ,CON_PROP_TOS ,CON_PROP_FLAGS ,NULL,NULL}, + { "rows" ,CON_PROP_ROWS ,CON_PROP_FLAGS ,NULL,NULL}, + { "autoterm" ,CON_PROP_AUTOTERM ,CON_PROP_FLAGS ,NULL,NULL}, + { "timeout" ,CON_PROP_TIMEOUT ,CON_PROP_FLAGS ,NULL,NULL}, + { "timeleft_warning" ,CON_PROP_TIMELEFT_WARN ,CON_PROP_FLAGS ,NULL,NULL}, + {0} +}; + +/**************************/ +/* Console Object Methods */ +/**************************/ + +static JSBool +js_inkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char key[2]; + long mode=0; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc && JSVAL_IS_INT(argv[0])) + mode=JSVAL_TO_INT(argv[0]); + key[0]=sbbs->inkey(mode); + key[1]=0; + + js_str = JS_NewStringCopyZ(cx, key); + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_getkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char key[2]; + long mode=0; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc && JSVAL_IS_INT(argv[0])) + mode=JSVAL_TO_INT(argv[0]); + key[0]=sbbs->getkey(mode); + key[1]=0; + + js_str = JS_NewStringCopyZ(cx, key); + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_getstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *p; + long mode=0; + uintN i; + size_t maxlen=0; + sbbs_t* sbbs; + JSString* js_str=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_INT(argv[i])) { + if(!maxlen) + maxlen=JSVAL_TO_INT(argv[i]); + else + mode=JSVAL_TO_INT(argv[i]); + continue; + } + if(JSVAL_IS_STRING(argv[i])) { + js_str = JS_ValueToString(cx, argv[i]); + if (!js_str) + return(JS_FALSE); + } + } + + if(!maxlen) maxlen=128; + + if((p=(char *)calloc(1,maxlen+1))==NULL) + return(JS_FALSE); + + if(js_str!=NULL) + sprintf(p,"%.*s",maxlen,JS_GetStringBytes(js_str)); + + sbbs->getstr(p,maxlen,mode); + + js_str = JS_NewStringCopyZ(cx, p); + + free(p); + + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_getnum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + ulong maxnum=~0; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc && JSVAL_IS_INT(argv[0])) + maxnum=JSVAL_TO_INT(argv[0]); + + *rval = INT_TO_JSVAL(sbbs->getnum(maxnum)); + + return(JS_TRUE); +} + +static JSBool +js_getkeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char key[2]; + uintN i; + long val; + ulong maxnum=~0; + sbbs_t* sbbs; + JSString* js_str=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_INT(argv[i])) { + maxnum=JSVAL_TO_INT(argv[i]); + continue; + } + if(JSVAL_IS_STRING(argv[i])) { + js_str = JS_ValueToString(cx, argv[i]); + } + } + if (!js_str) + return(JS_FALSE); + + val=sbbs->getkeys(JS_GetStringBytes(js_str),maxnum); + + if(val==-1) { // abort + *rval = INT_TO_JSVAL(0); + } else if(val<0) { // number + val&=~0x80000000; + *rval = INT_TO_JSVAL(val); + } else { // key + key[0]=(uchar)val; + key[1]=0; + js_str = JS_NewStringCopyZ(cx, key); + *rval = STRING_TO_JSVAL(js_str); + } + + return(JS_TRUE); +} + +static JSBool +js_gettemplate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char str[128]; + long mode=0; + uintN i; + sbbs_t* sbbs; + JSString* js_str=NULL; + JSString* js_fmt=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_STRING(argv[i])) { + if(js_fmt==NULL) + js_fmt = JS_ValueToString(cx, argv[i]); + else + js_str = JS_ValueToString(cx, argv[i]); + } else if (JSVAL_IS_INT(argv[i])) + mode=JSVAL_TO_INT(argv[i]); + } + + if(js_fmt==NULL) + return(JS_FALSE); + + if(js_str==NULL) + str[0]=0; + else + sprintf(str, "%.*s", sizeof(str)-1, JS_GetStringBytes(js_str)); + + sbbs->gettmplt(str,JS_GetStringBytes(js_fmt),mode); + js_str = JS_NewStringCopyZ(cx, str); + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_ungetstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char* p; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + p=JS_GetStringBytes(js_str); + + while(p && *p) + sbbs->ungetkey(*(p++)); + + return(JS_TRUE); +} + +static JSBool +js_yesno(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + *rval = BOOLEAN_TO_JSVAL(sbbs->yesno(JS_GetStringBytes(js_str))); + + return(JS_TRUE); +} + +static JSBool +js_noyes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + *rval = BOOLEAN_TO_JSVAL(sbbs->noyes(JS_GetStringBytes(js_str))); + + return(JS_TRUE); +} + +static JSBool +js_mnemonics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + sbbs->mnemonics(JS_GetStringBytes(js_str)); + + return(JS_TRUE); +} + static JSBool -js_cls(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +js_clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { sbbs_t* sbbs; @@ -154,6 +436,19 @@ js_cls(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return(JS_TRUE); } +static JSBool +js_clearline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->clearline(); + + return(JS_TRUE); +} + static JSBool js_crlf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -200,6 +495,24 @@ js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) JSString* str; sbbs_t* sbbs; + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + sbbs->bputs(JS_GetStringBytes(str)); + + return(JS_TRUE); +} + +static JSBool +js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString* str; + sbbs_t* sbbs; + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) return(JS_FALSE); @@ -212,6 +525,144 @@ js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return(JS_TRUE); } +static JSBool +js_putmsg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + long mode=0; + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + if(argc>1 && JSVAL_IS_INT(argv[1])) + mode=JSVAL_TO_INT(argv[1]); + + sbbs->putmsg(JS_GetStringBytes(str),mode); + + return(JS_TRUE); +} + +static JSBool +js_printfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + long mode=0; + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + if(argc>1 && JSVAL_IS_INT(argv[1])) + mode=JSVAL_TO_INT(argv[1]); + + sbbs->printfile(JS_GetStringBytes(str),mode); + + return(JS_TRUE); +} + +static JSBool +js_printtail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + int lines=0; + long mode=0; + uintN i; + sbbs_t* sbbs; + JSString* js_str=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_INT(argv[i])) { + if(!lines) + lines=JSVAL_TO_INT(argv[i]); + else + mode=JSVAL_TO_INT(argv[i]); + } else if(JSVAL_IS_STRING(argv[i])) + js_str = JS_ValueToString(cx, argv[i]); + } + + if(js_str==NULL) + return(JS_FALSE); + + if(!lines) + lines=5; + + sbbs->printtail(JS_GetStringBytes(js_str),lines,mode); + + return(JS_TRUE); +} + +static JSBool +js_menu(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + sbbs->menu(JS_GetStringBytes(str)); + + return(JS_TRUE); +} + +static JSBool +js_uselect(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uintN i; + int num=0; + char* title; + char* item; + char* ar_str; + uchar* ar; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(!argc) { + *rval = INT_TO_JSVAL(sbbs->uselect(0,0,NULL,NULL,NULL)); + return(JS_TRUE); + } + + for(i=0;i<argc;i++) { + if(!JSVAL_IS_STRING(argv[i])) { + num = JSVAL_TO_INT(argv[i]); + continue; + } + if((js_str=JS_ValueToString(cx, argv[i]))==NULL) + return(JS_FALSE); + + if(title==NULL) + title=JS_GetStringBytes(js_str); + else if(item==NULL) + item=JS_GetStringBytes(js_str); + else { + ar_str=JS_GetStringBytes(js_str); + ar=arstr(NULL,ar_str,&sbbs->cfg); + } + } + + *rval = INT_TO_JSVAL(sbbs->uselect(1, num, title, item, ar)); + + return(JS_TRUE); +} + static JSBool js_center(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -383,14 +834,31 @@ js_ansi_getlines(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *r } static JSFunctionSpec js_console_functions[] = { - {"cls", js_cls, 0}, /* clear screen */ - {"crlf", js_crlf, 0}, /* output cr/lf */ - {"attr", js_attr, 1}, /* set current text attribute */ - {"pause", js_pause, 0}, /* pause */ - {"print", js_print, 1}, /* display a raw string */ - {"center", js_center, 1}, /* display a string centered on the screen */ - {"saveline", js_saveline, 0}, /* save last output line */ - {"restoreline", js_restoreline, 0}, /* restore last output line */ + {"inkey", js_inkey, 0}, // get key - no wait + {"getkey", js_getkey, 0}, // get key - with wait + {"getstr", js_getstr, 0}, // get string + {"getnum", js_getnum, 0}, // get number + {"getkeys", js_getkeys, 1}, // get one of a list of keys + {"gettemplate", js_gettemplate, 1}, // get a string based on template + {"ungetstr", js_ungetstr, 1}, // put a string in the keyboard buffer + {"yesno", js_yesno, 1}, // Y/n question + {"noyes", js_noyes, 1}, // N/y question + {"mnemonics", js_mnemonics, 1}, // mnemonics input + {"clear", js_clear, 0}, // clear screen + {"clearline", js_clearline, 0}, // clear current line + {"crlf", js_crlf, 0}, // output cr/lf + {"attr", js_attr, 1}, // set current text attribute + {"pause", js_pause, 0}, // pause + {"print", js_print, 1}, // display a string (supports ^A and @-codes) + {"write", js_write, 1}, // display a raw string + {"putmsg", js_putmsg, 1}, // display message text (^A, @-codes, etc) with mode + {"center", js_center, 1}, // display a string centered on the screen + {"printfile", js_printfile, 1}, // print a file, optional mode + {"printtail", js_printtail, 2}, // print last x lines of file, optional mode + {"menu", js_menu, 1}, // print menu (auto-extension) + {"uselect", js_uselect, 0}, // user selection menu + {"saveline", js_saveline, 0}, // save last output line + {"restoreline", js_restoreline, 0}, // restore last output line {"ansi_pushxy", js_ansi_save, 0}, {"ansi_popxy", js_ansi_restore, 0}, {"ansi_gotoxy", js_ansi_gotoxy, 2}, @@ -416,22 +884,6 @@ static JSClass js_console_class = { ,JS_FinalizeStub /* finalize */ }; -#define CON_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY - -static struct JSPropertySpec js_console_properties[] = { -/* name ,tinyid ,flags ,getter,setter */ - - { "online" ,CON_PROP_ONLINE ,CON_PROP_FLAGS ,NULL,NULL}, - { "status" ,CON_PROP_STATUS ,CON_PROP_FLAGS ,NULL,NULL}, - { "line_counter" ,CON_PROP_LNCNTR ,CON_PROP_FLAGS ,NULL,NULL}, - { "top_of_screen" ,CON_PROP_TOS ,CON_PROP_FLAGS ,NULL,NULL}, - { "rows" ,CON_PROP_ROWS ,CON_PROP_FLAGS ,NULL,NULL}, - { "autoterm" ,CON_PROP_AUTOTERM ,CON_PROP_FLAGS ,NULL,NULL}, - { "timeout" ,CON_PROP_TIMEOUT ,CON_PROP_FLAGS ,NULL,NULL}, - { "timeleft_warning" ,CON_PROP_TIMELEFT_WARN ,CON_PROP_FLAGS ,NULL,NULL}, - {0} -}; - JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent) { JSObject* obj;