|
|
1.1 root 1: /* js_console.cpp */
2:
3: /* Synchronet JavaScript "Console" Object */
4:
5: /* $Id: js_console.cpp,v 1.66 2006/12/27 09:19:26 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include "sbbs.h"
39:
40: #ifdef JAVASCRIPT
41:
42: /*****************************/
43: /* Console Object Properites */
44: /*****************************/
45: enum {
46: CON_PROP_STATUS
47: ,CON_PROP_LNCNTR
48: ,CON_PROP_ATTR
49: ,CON_PROP_TOS
50: ,CON_PROP_ROWS
51: ,CON_PROP_COLUMNS
52: ,CON_PROP_AUTOTERM
53: ,CON_PROP_TERMINAL
54: ,CON_PROP_WORDWRAP
55: ,CON_PROP_QUESTION
56: ,CON_PROP_TIMEOUT /* User inactivity timeout reference */
57: ,CON_PROP_TIMELEFT_WARN /* low timeleft warning flag */
58: ,CON_PROP_ABORTED
59: ,CON_PROP_ABORTABLE
60: ,CON_PROP_TELNET_MODE
61: ,CON_PROP_GETSTR_OFFSET
62: ,CON_PROP_CTRLKEY_PASSTHRU
63: /* read only */
64: ,CON_PROP_INBUF_LEVEL
65: ,CON_PROP_INBUF_SPACE
66: ,CON_PROP_OUTBUF_LEVEL
67: ,CON_PROP_OUTBUF_SPACE
68: };
69:
70: static JSBool js_console_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
71: {
72: ulong val;
73: jsint tiny;
74: JSString* js_str;
75: sbbs_t* sbbs;
76:
77: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
78: return(JS_FALSE);
79:
80: tiny = JSVAL_TO_INT(id);
81:
82: switch(tiny) {
83: case CON_PROP_STATUS:
84: val=sbbs->console;
85: break;
86: case CON_PROP_LNCNTR:
87: val=sbbs->lncntr;
88: break;
89: case CON_PROP_ATTR:
90: val=sbbs->curatr;
91: break;
92: case CON_PROP_TOS:
93: val=sbbs->tos;
94: break;
95: case CON_PROP_ROWS:
96: val=sbbs->rows;
97: break;
98: case CON_PROP_COLUMNS:
99: val=sbbs->cols;
100: break;
101: case CON_PROP_AUTOTERM:
102: val=sbbs->autoterm;
103: break;
104: case CON_PROP_TERMINAL:
105: if((js_str=JS_NewStringCopyZ(cx, sbbs->terminal))==NULL)
106: return(JS_FALSE);
107: *vp = STRING_TO_JSVAL(js_str);
108: return(JS_TRUE);
109: case CON_PROP_TIMEOUT:
110: val=sbbs->timeout;
111: break;
112: case CON_PROP_TIMELEFT_WARN:
113: val=sbbs->timeleft_warn;
114: break;
115: case CON_PROP_ABORTED:
116: *vp=BOOLEAN_TO_JSVAL(INT_TO_BOOL(sbbs->sys_status&SS_ABORT));
117: return(JS_TRUE);
118: case CON_PROP_ABORTABLE:
119: *vp=BOOLEAN_TO_JSVAL(INT_TO_BOOL(sbbs->rio_abortable));
120: return(JS_TRUE);
121: case CON_PROP_TELNET_MODE:
122: val=sbbs->telnet_mode;
123: break;
124: case CON_PROP_GETSTR_OFFSET:
125: val=sbbs->getstr_offset;
126: break;
127: case CON_PROP_WORDWRAP:
128: if((js_str=JS_NewStringCopyZ(cx, sbbs->wordwrap))==NULL)
129: return(JS_FALSE);
130: *vp = STRING_TO_JSVAL(js_str);
131: return(JS_TRUE);
132: case CON_PROP_QUESTION:
133: if((js_str=JS_NewStringCopyZ(cx, sbbs->question))==NULL)
134: return(JS_FALSE);
135: *vp = STRING_TO_JSVAL(js_str);
136: return(JS_TRUE);
137: case CON_PROP_CTRLKEY_PASSTHRU:
138: val=sbbs->cfg.ctrlkey_passthru;
139: break;
140: case CON_PROP_INBUF_LEVEL:
141: val=RingBufFull(&sbbs->inbuf);
142: break;
143: case CON_PROP_INBUF_SPACE:
144: val=RingBufFree(&sbbs->inbuf);
145: break;
146: case CON_PROP_OUTBUF_LEVEL:
147: val=RingBufFull(&sbbs->outbuf);
148: break;
149: case CON_PROP_OUTBUF_SPACE:
150: val=RingBufFree(&sbbs->outbuf);
151: break;
152: default:
153: return(JS_TRUE);
154: }
155:
156: *vp = INT_TO_JSVAL(val);
157:
158: return(JS_TRUE);
159: }
160:
161: static JSBool js_console_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
162: {
163: int32 val=0;
164: jsint tiny;
165: sbbs_t* sbbs;
166: JSString* str;
167:
168: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
169: return(JS_FALSE);
170:
171: tiny = JSVAL_TO_INT(id);
172:
173: if(JSVAL_IS_NUMBER(*vp) || JSVAL_IS_BOOLEAN(*vp))
174: JS_ValueToInt32(cx, *vp, &val);
175:
176: switch(tiny) {
177: case CON_PROP_STATUS:
178: sbbs->console=val;
179: break;
180: case CON_PROP_LNCNTR:
181: sbbs->lncntr=val;
182: break;
183: case CON_PROP_ATTR:
184: if(JSVAL_IS_STRING(*vp)) {
185: if((str=JS_ValueToString(cx, *vp))==NULL)
186: break;
187: val=attrstr(JS_GetStringBytes(str));
188: }
189: sbbs->attr(val);
190: break;
191: case CON_PROP_TOS:
192: sbbs->tos=val;
193: break;
194: case CON_PROP_ROWS:
195: sbbs->rows=val;
196: break;
197: case CON_PROP_COLUMNS:
198: sbbs->cols=val;
199: break;
200: case CON_PROP_AUTOTERM:
201: sbbs->autoterm=val;
202: break;
203: case CON_PROP_TERMINAL:
204: if((str=JS_ValueToString(cx, *vp))==NULL)
205: break;
206: SAFECOPY(sbbs->terminal,JS_GetStringBytes(str));
207: break;
208: case CON_PROP_TIMEOUT:
209: sbbs->timeout=val;
210: break;
211: case CON_PROP_TIMELEFT_WARN:
212: sbbs->timeleft_warn=val;
213: break;
214: case CON_PROP_ABORTED:
215: if(val)
216: sbbs->sys_status|=SS_ABORT;
217: else
218: sbbs->sys_status&=~SS_ABORT;
219: break;
220: case CON_PROP_ABORTABLE:
221: sbbs->rio_abortable=val
222: ? true:false; // This is a dumb bool conversion to make BC++ happy
223: break;
224: case CON_PROP_TELNET_MODE:
225: sbbs->telnet_mode=val;
226: break;
227: case CON_PROP_GETSTR_OFFSET:
228: sbbs->getstr_offset=val;
229: break;
230: case CON_PROP_QUESTION:
231: if((str=JS_ValueToString(cx, *vp))==NULL)
232: break;
233: SAFECOPY(sbbs->question,JS_GetStringBytes(str));
234: break;
235: case CON_PROP_CTRLKEY_PASSTHRU:
236: if(JSVAL_IS_STRING(*vp)) {
237: /* op can be 0 for replace, + for add, or - for remove */
238: int op=0;
239: char *s;
240: char ctrl;
241:
242: if((str=JS_ValueToString(cx, *vp))==NULL)
243: break;
244: val=sbbs->cfg.ctrlkey_passthru;
245: for(s=JS_GetStringBytes(str); *s; s++) {
246: if(*s=='+')
247: op=1;
248: else if(*s=='-')
249: op=2;
250: else {
251: if(!op) {
252: val=0;
253: op=1;
254: }
255: ctrl=toupper(*s);
256: ctrl&=0x1f; /* Ensure it fits */
257: switch(op) {
258: case 1: /* Add to the set */
259: val |= 1<<ctrl;
260: break;
261: case 2: /* Remove from the set */
262: val &= ~(1<<ctrl);
263: break;
264: }
265: }
266: }
267: }
268: sbbs->cfg.ctrlkey_passthru=val;
269: break;
270: default:
271: return(JS_TRUE);
272: }
273:
274: return(JS_TRUE);
275: }
276:
277: #define CON_PROP_FLAGS JSPROP_ENUMERATE
278:
279: static jsSyncPropertySpec js_console_properties[] = {
280: /* name ,tinyid ,flags ,ver */
281:
282: { "status" ,CON_PROP_STATUS ,CON_PROP_FLAGS ,310},
283: { "line_counter" ,CON_PROP_LNCNTR ,CON_PROP_FLAGS ,310},
284: { "attributes" ,CON_PROP_ATTR ,CON_PROP_FLAGS ,310},
285: { "top_of_screen" ,CON_PROP_TOS ,CON_PROP_FLAGS ,310},
286: { "screen_rows" ,CON_PROP_ROWS ,CON_PROP_FLAGS ,310},
287: { "screen_columns" ,CON_PROP_COLUMNS ,CON_PROP_FLAGS ,311},
288: { "autoterm" ,CON_PROP_AUTOTERM ,CON_PROP_FLAGS ,310},
289: { "terminal" ,CON_PROP_TERMINAL ,CON_PROP_FLAGS ,311},
290: { "timeout" ,CON_PROP_TIMEOUT ,CON_PROP_FLAGS ,310},
291: { "timeleft_warning" ,CON_PROP_TIMELEFT_WARN ,CON_PROP_FLAGS ,310},
292: { "aborted" ,CON_PROP_ABORTED ,CON_PROP_FLAGS ,310},
293: { "abortable" ,CON_PROP_ABORTABLE ,CON_PROP_FLAGS ,310},
294: { "telnet_mode" ,CON_PROP_TELNET_MODE ,CON_PROP_FLAGS ,310},
295: { "wordwrap" ,CON_PROP_WORDWRAP ,JSPROP_ENUMERATE|JSPROP_READONLY ,310},
296: { "question" ,CON_PROP_QUESTION ,CON_PROP_FLAGS ,310},
297: { "getstr_offset" ,CON_PROP_GETSTR_OFFSET ,CON_PROP_FLAGS ,311},
298: { "ctrlkey_passthru" ,CON_PROP_CTRLKEY_PASSTHRU ,CON_PROP_FLAGS ,310},
299: { "input_buffer_level",CON_PROP_INBUF_LEVEL ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
300: { "input_buffer_space",CON_PROP_INBUF_SPACE ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
301: { "output_buffer_level",CON_PROP_OUTBUF_LEVEL ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
302: { "output_buffer_space",CON_PROP_OUTBUF_SPACE ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
303: {0}
304: };
305:
306: #ifdef BUILD_JSDOCS
307: static char* con_prop_desc[] = {
308: "status bitfield (see <tt>CON_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
309: ,"current line counter (used for automatic screen pause)"
310: ,"current display attributes (set with number or string value)"
311: ,"set to 1 if the terminal cursor is already at the top of the screen"
312: ,"number of terminal screen rows (in lines)"
313: ,"number of terminal screen columns (in character cells)"
314: ,"bitfield of automatically detected terminal settings "
315: "(see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
316: ,"terminal type description (e.g. 'ANSI')"
317: ,"user inactivity timeout reference"
318: ,"low timeleft warning flag"
319: ,"input/output has been aborted"
320: ,"output can be aborted with Ctrl-C"
321: ,"current telnet mode bitfield (see <tt>TELNET_MODE_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
322: ,"word-wrap buffer (used by getstr) - <small>READ ONLY</small>"
323: ,"current yes/no question (set by yesno and noyes)"
324: ,"cursor position offset for use with <tt>getstr(K_USEOFFSET)</tt>"
325: ,"control key pass-through bitmask, set bits represent control key combinations "
326: "<i>not</i> handled by <tt>inkey()</tt> method "
327: "This may optionally be specified as a string of characters. "
328: "The format of this string is [+-][@-_]. If neither plus nor minus is "
329: "the first character, the value will be replaced by one constructed "
330: "from the string. A + indicates that characters following will be "
331: "added to the set, and a - indicates they should be removed. "
332: "ex: <tt>console.ctrlkey_passthru=\"-UP+AB\"</tt> will clear CTRL-U and "
333: "CTRL-P and set CTRL-A and CTRL-B."
334: ,"number of bytes currently in the input buffer (from the remote client) - <small>READ ONLY</small>"
335: ,"number of bytes available in the input buffer - <small>READ ONLY</small>"
336: ,"number of bytes currently in the output buffer (from the local server) - <small>READ ONLY</small>"
337: ,"number of bytes available in the output buffer - <small>READ ONLY</small>"
338: ,NULL
339: };
340: #endif
341:
342: /**************************/
343: /* Console Object Methods */
344: /**************************/
345:
346: static JSBool
347: js_inkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
348: {
349: char key[2];
350: int32 mode=0;
351: int32 timeout=0;
352: sbbs_t* sbbs;
353: JSString* js_str;
354:
355: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
356: return(JS_FALSE);
357:
358: if(argc)
359: JS_ValueToInt32(cx,argv[0],&mode);
360: if(argc>1)
361: JS_ValueToInt32(cx,argv[1],&timeout);
362: key[0]=sbbs->inkey(mode,timeout);
363: key[1]=0;
364:
365: if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
366: return(JS_FALSE);
367:
368: *rval = STRING_TO_JSVAL(js_str);
369: return(JS_TRUE);
370: }
371:
372: static JSBool
373: js_getkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
374: {
375: char key[2];
376: int32 mode=0;
377: sbbs_t* sbbs;
378: JSString* js_str;
379:
380: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
381: return(JS_FALSE);
382:
383: if(argc)
384: JS_ValueToInt32(cx,argv[0],&mode);
385: key[0]=sbbs->getkey(mode);
386: key[1]=0;
387:
388: if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
389: return(JS_FALSE);
390:
391: *rval = STRING_TO_JSVAL(js_str);
392: return(JS_TRUE);
393: }
394:
395: static JSBool
396: js_handle_ctrlkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
397: {
398: char key;
399: int32 mode=0;
400: sbbs_t* sbbs;
401: JSString* js_str;
402:
403: *rval = JSVAL_FALSE;
404:
405: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
406: return(JS_FALSE);
407:
408: if(JSVAL_IS_INT(argv[0]))
409: key=(char)JSVAL_TO_INT(argv[0]);
410: else {
411: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
412: return(JS_FALSE);
413: key=*JS_GetStringBytes(js_str);
414: }
415:
416: if(argc>1)
417: JS_ValueToInt32(cx, argv[1], &mode);
418:
419: *rval = BOOLEAN_TO_JSVAL(sbbs->handle_ctrlkey(key,mode)==0);
420: return(JS_TRUE);
421: }
422:
423: static JSBool
424: js_getstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
425: {
426: char *p;
427: long mode=0;
428: uintN i;
429: size_t maxlen=0;
430: sbbs_t* sbbs;
431: JSString* js_str=NULL;
432:
433: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
434: return(JS_FALSE);
435:
436: for(i=0;i<argc;i++) {
437: if(JSVAL_IS_NUMBER(argv[i])) {
438: if(!maxlen)
439: JS_ValueToInt32(cx,argv[i],(int32*)&maxlen);
440: else
441: JS_ValueToInt32(cx,argv[i],(int32*)&mode);
442: continue;
443: }
444: if(JSVAL_IS_STRING(argv[i])) {
445: js_str = JS_ValueToString(cx, argv[i]);
446: if (!js_str)
447: return(JS_FALSE);
448: }
449: }
450:
451: if(!maxlen) maxlen=128;
452:
453: if((p=(char *)calloc(1,maxlen+1))==NULL)
454: return(JS_FALSE);
455:
456: if(js_str!=NULL)
457: sprintf(p,"%.*s",(int)maxlen,JS_GetStringBytes(js_str));
458:
459: sbbs->getstr(p,maxlen,mode);
460:
461: js_str = JS_NewStringCopyZ(cx, p);
462:
463: free(p);
464:
465: if(js_str==NULL)
466: return(JS_FALSE);
467:
468: *rval = STRING_TO_JSVAL(js_str);
469: return(JS_TRUE);
470: }
471:
472: static JSBool
473: js_getnum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
474: {
475: ulong maxnum=~0;
476: sbbs_t* sbbs;
477:
478: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
479: return(JS_FALSE);
480:
481: if(argc && JSVAL_IS_NUMBER(argv[0]))
482: JS_ValueToInt32(cx,argv[0],(int32*)&maxnum);
483:
484: *rval = INT_TO_JSVAL(sbbs->getnum(maxnum));
485: return(JS_TRUE);
486: }
487:
488: static JSBool
489: js_getkeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
490: {
491: char key[2];
492: uintN i;
493: long val;
494: ulong maxnum=~0;
495: sbbs_t* sbbs;
496: JSString* js_str=NULL;
497:
498: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
499: return(JS_FALSE);
500:
501: for(i=0;i<argc;i++) {
502: if(JSVAL_IS_NUMBER(argv[i])) {
503: JS_ValueToInt32(cx,argv[i],(int32*)&maxnum);
504: continue;
505: }
506: if(JSVAL_IS_STRING(argv[i])) {
507: js_str = JS_ValueToString(cx, argv[i]);
508: }
509: }
510: if(js_str==NULL)
511: return(JS_FALSE);
512:
513: val=sbbs->getkeys(JS_GetStringBytes(js_str),maxnum);
514:
515: if(val==-1) { // abort
516: *rval = INT_TO_JSVAL(0);
517: } else if(val<0) { // number
518: val&=~0x80000000;
519: *rval = INT_TO_JSVAL(val);
520: } else { // key
521: key[0]=(uchar)val;
522: key[1]=0;
523: if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
524: return(JS_FALSE);
525: *rval = STRING_TO_JSVAL(js_str);
526: }
527:
528: return(JS_TRUE);
529: }
530:
531: static JSBool
532: js_gettemplate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
533: {
534: char str[128];
535: long mode=0;
536: uintN i;
537: sbbs_t* sbbs;
538: JSString* js_str=NULL;
539: JSString* js_fmt=NULL;
540:
541: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
542: return(JS_FALSE);
543:
544: for(i=0;i<argc;i++) {
545: if(JSVAL_IS_STRING(argv[i])) {
546: if(js_fmt==NULL)
547: js_fmt = JS_ValueToString(cx, argv[i]);
548: else
549: js_str = JS_ValueToString(cx, argv[i]);
550: } else if(JSVAL_IS_NUMBER(argv[i]))
551: JS_ValueToInt32(cx,argv[i],(int32*)&mode);
552: }
553:
554: if(js_fmt==NULL)
555: return(JS_FALSE);
556:
557: if(js_str==NULL)
558: str[0]=0;
559: else
560: SAFECOPY(str,JS_GetStringBytes(js_str));
561:
562: sbbs->gettmplt(str,JS_GetStringBytes(js_fmt),mode);
563:
564: if((js_str=JS_NewStringCopyZ(cx, str))==NULL)
565: return(JS_FALSE);
566:
567: *rval = STRING_TO_JSVAL(js_str);
568: return(JS_TRUE);
569: }
570:
571: static JSBool
572: js_ungetstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
573: {
574: char* p;
575: sbbs_t* sbbs;
576: JSString* js_str;
577:
578: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
579: return(JS_FALSE);
580:
581: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
582: return(JS_FALSE);
583:
584: p=JS_GetStringBytes(js_str);
585:
586: while(p && *p)
587: sbbs->ungetkey(*(p++));
588: return(JS_TRUE);
589: }
590:
591: static JSBool
592: js_yesno(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
593: {
594: sbbs_t* sbbs;
595: JSString* js_str;
596:
597: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
598: return(JS_FALSE);
599:
600: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
601: return(JS_FALSE);
602:
603: *rval = BOOLEAN_TO_JSVAL(sbbs->yesno(JS_GetStringBytes(js_str)));
604: return(JS_TRUE);
605: }
606:
607: static JSBool
608: js_noyes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
609: {
610: sbbs_t* sbbs;
611: JSString* js_str;
612:
613: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
614: return(JS_FALSE);
615:
616: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
617: return(JS_FALSE);
618:
619: *rval = BOOLEAN_TO_JSVAL(sbbs->noyes(JS_GetStringBytes(js_str)));
620: return(JS_TRUE);
621: }
622:
623: static JSBool
624: js_mnemonics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
625: {
626: sbbs_t* sbbs;
627: JSString* js_str;
628:
629: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
630: return(JS_FALSE);
631:
632: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
633: return(JS_FALSE);
634:
635: sbbs->mnemonics(JS_GetStringBytes(js_str));
636: return(JS_TRUE);
637: }
638:
639: static void
640: js_set_attr(JSContext* cx, sbbs_t* sbbs, jsval val)
641: {
642: int32 attr;
643:
644: if(JSVAL_IS_STRING(val))
645: attr=attrstr(js_ValueToStringBytes(cx,val,NULL));
646: else
647: JS_ValueToInt32(cx, val, &attr);
648:
649: sbbs->attr(attr);
650: }
651:
652: static JSBool
653: js_clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
654: {
655: sbbs_t* sbbs;
656:
657: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
658: return(JS_FALSE);
659:
660: if(argc)
661: js_set_attr(cx, sbbs, argv[0]);
662:
663: sbbs->CLS;
664: return(JS_TRUE);
665: }
666:
667: static JSBool
668: js_clearline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
669: {
670: sbbs_t* sbbs;
671:
672: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
673: return(JS_FALSE);
674:
675: if(argc)
676: js_set_attr(cx, sbbs, argv[0]);
677:
678: sbbs->clearline();
679: return(JS_TRUE);
680: }
681:
682: static JSBool
683: js_cleartoeol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
684: {
685: sbbs_t* sbbs;
686:
687: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
688: return(JS_FALSE);
689:
690: if(argc)
691: js_set_attr(cx, sbbs, argv[0]);
692:
693: sbbs->cleartoeol();
694: return(JS_TRUE);
695: }
696:
697: static JSBool
698: js_crlf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
699: {
700: sbbs_t* sbbs;
701:
702: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
703: return(JS_FALSE);
704:
705: sbbs->outchar(CR);
706: sbbs->outchar(LF);
707: return(JS_TRUE);
708: }
709:
710: static JSBool
711: js_pause(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
712: {
713: sbbs_t* sbbs;
714:
715: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
716: return(JS_FALSE);
717:
718: sbbs->pause();
719: return(JS_TRUE);
720: }
721:
722: static JSBool
723: js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
724: {
725: sbbs_t* sbbs;
726: int32 i;
727: int32 count=1;
728:
729: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
730: return(JS_FALSE);
731:
732: if(argc)
733: JS_ValueToInt32(cx, argv[0], &count);
734: for(i=0;i<count;i++)
735: sbbs->outchar('\a');
736:
737: return(JS_TRUE);
738: }
739:
740: static JSBool
741: js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
742: {
743: JSString* str;
744: sbbs_t* sbbs;
745:
746: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
747: return(JS_FALSE);
748:
749: str = JS_ValueToString(cx, argv[0]);
750: if (!str)
751: return(JS_FALSE);
752:
753: sbbs->bputs(JS_GetStringBytes(str));
754: return(JS_TRUE);
755: }
756:
757: static JSBool
758: js_strlen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
759: {
760: JSString* str;
761:
762: if((str=JS_ValueToString(cx, argv[0]))==NULL)
763: return(JS_FALSE);
764:
765: *rval = INT_TO_JSVAL(bstrlen(JS_GetStringBytes(str)));
766: return(JS_TRUE);
767: }
768:
769: static JSBool
770: js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
771: {
772: JSString* str;
773: sbbs_t* sbbs;
774:
775: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
776: return(JS_FALSE);
777:
778: str = JS_ValueToString(cx, argv[0]);
779: if (!str)
780: return(JS_FALSE);
781:
782: sbbs->rputs(JS_GetStringBytes(str));
783: return(JS_TRUE);
784: }
785:
786: static JSBool
787: js_putmsg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
788: {
789: long mode=0;
790: JSString* str;
791: sbbs_t* sbbs;
792:
793: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
794: return(JS_FALSE);
795:
796: str = JS_ValueToString(cx, argv[0]);
797: if (!str)
798: return(JS_FALSE);
799:
800: if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
801: JS_ValueToInt32(cx,argv[1],(int32*)&mode);
802:
803: sbbs->putmsg(JS_GetStringBytes(str),mode);
804: return(JS_TRUE);
805: }
806:
807: static JSBool
808: js_printfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
809: {
810: long mode=0;
811: JSString* str;
812: sbbs_t* sbbs;
813:
814: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
815: return(JS_FALSE);
816:
817: str = JS_ValueToString(cx, argv[0]);
818: if (!str)
819: return(JS_FALSE);
820:
821: if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
822: JS_ValueToInt32(cx,argv[1],(int32*)&mode);
823:
824: sbbs->printfile(JS_GetStringBytes(str),mode);
825: return(JS_TRUE);
826: }
827:
828: static JSBool
829: js_printtail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
830: {
831: int lines=0;
832: long mode=0;
833: uintN i;
834: sbbs_t* sbbs;
835: JSString* js_str=NULL;
836:
837: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
838: return(JS_FALSE);
839:
840: for(i=0;i<argc;i++) {
841: if(JSVAL_IS_NUMBER(argv[i])) {
842: if(!lines)
843: JS_ValueToInt32(cx,argv[i],(int32*)&lines);
844: else
845: JS_ValueToInt32(cx,argv[i],(int32*)&mode);
846: } else if(JSVAL_IS_STRING(argv[i]))
847: js_str = JS_ValueToString(cx, argv[i]);
848: }
849:
850: if(js_str==NULL)
851: return(JS_FALSE);
852:
853: if(!lines)
854: lines=5;
855:
856: sbbs->printtail(JS_GetStringBytes(js_str),lines,mode);
857: return(JS_TRUE);
858: }
859:
860: static JSBool
861: js_editfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
862: {
863: JSString* str;
864: sbbs_t* sbbs;
865:
866: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
867: return(JS_FALSE);
868:
869: if((str=JS_ValueToString(cx, argv[0]))==NULL)
870: return(JS_FALSE);
871:
872: sbbs->editfile(JS_GetStringBytes(str));
873: return(JS_TRUE);
874: }
875:
876:
877: static JSBool
878: js_uselect(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
879: {
880: uintN i;
881: int32 num=0;
882: char* title=NULL;
883: char* item=NULL;
884: char* ar_str;
885: uchar* ar=NULL;
886: sbbs_t* sbbs;
887: JSString* js_str;
888:
889: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
890: return(JS_FALSE);
891:
892: if(!argc) {
893: *rval = INT_TO_JSVAL(sbbs->uselect(0,0,NULL,NULL,NULL));
894: return(JS_TRUE);
895: }
896:
897: for(i=0;i<argc;i++) {
898: if(JSVAL_IS_NUMBER(argv[i])) {
899: JS_ValueToInt32(cx,argv[i],&num);
900: continue;
901: }
902: if((js_str=JS_ValueToString(cx, argv[i]))==NULL)
903: return(JS_FALSE);
904:
905: if(title==NULL)
906: title=JS_GetStringBytes(js_str);
907: else if(item==NULL)
908: item=JS_GetStringBytes(js_str);
909: else {
910: ar_str=JS_GetStringBytes(js_str);
911: ar=arstr(NULL,ar_str,&sbbs->cfg);
912: }
913: }
914:
915: *rval = INT_TO_JSVAL(sbbs->uselect(1, num, title, item, ar));
916: return(JS_TRUE);
917: }
918:
919: static JSBool
920: js_center(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
921: {
922: JSString* str;
923: sbbs_t* sbbs;
924:
925: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
926: return(JS_FALSE);
927:
928: str = JS_ValueToString(cx, argv[0]);
929: if (!str)
930: return(JS_FALSE);
931:
932: sbbs->center(JS_GetStringBytes(str));
933: return(JS_TRUE);
934: }
935:
936: static JSBool
937: js_saveline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
938: {
939: sbbs_t* sbbs;
940:
941: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
942: return(JS_FALSE);
943:
944: sbbs->slatr[sbbs->slcnt]=sbbs->latr;
945: sprintf(sbbs->slbuf[sbbs->slcnt<SAVE_LINES ? sbbs->slcnt++ : sbbs->slcnt]
946: ,"%.*s",sbbs->lbuflen,sbbs->lbuf);
947: sbbs->lbuflen=0;
948: return(JS_TRUE);
949: }
950:
951: static JSBool
952: js_restoreline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
953: {
954: sbbs_t* sbbs;
955:
956: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
957: return(JS_FALSE);
958:
959: sbbs->lbuflen=0;
960: sbbs->attr(sbbs->slatr[--sbbs->slcnt]);
961: sbbs->rputs(sbbs->slbuf[sbbs->slcnt]);
962: sbbs->curatr=LIGHTGRAY;
963: return(JS_TRUE);
964: }
965:
966: static JSBool
967: js_ansi(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
968: {
969: int32 attr=0;
970: JSString* js_str;
971: sbbs_t* sbbs;
972:
973: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
974: return(JS_FALSE);
975:
976: if(argc)
977: JS_ValueToInt32(cx,argv[0],&attr);
978: if((js_str=JS_NewStringCopyZ(cx,sbbs->ansi(attr)))==NULL)
979: return(JS_FALSE);
980:
981: *rval = STRING_TO_JSVAL(js_str);
982: return(JS_TRUE);
983: }
984:
985: static JSBool
986: js_pushxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
987: {
988: sbbs_t* sbbs;
989:
990: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
991: return(JS_FALSE);
992:
993: sbbs->ANSI_SAVE();
994: return(JS_TRUE);
995: }
996:
997: static JSBool
998: js_popxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
999: {
1000: sbbs_t* sbbs;
1001:
1002: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1003: return(JS_FALSE);
1004:
1005: sbbs->ANSI_RESTORE();
1006: return(JS_TRUE);
1007: }
1008:
1009: static JSBool
1010: js_gotoxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1011: {
1012: int32 x=1,y=1;
1013: jsval val;
1014: sbbs_t* sbbs;
1015:
1016: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1017: return(JS_FALSE);
1018:
1019: if(JSVAL_IS_OBJECT(argv[0])) {
1020: JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),"x", &val);
1021: JS_ValueToInt32(cx,val,&x);
1022: JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),"y", &val);
1023: JS_ValueToInt32(cx,val,&y);
1024: } else {
1025: JS_ValueToInt32(cx,argv[0],&x);
1026: JS_ValueToInt32(cx,argv[1],&y);
1027: }
1028:
1029: sbbs->GOTOXY(x,y);
1030: return(JS_TRUE);
1031: }
1032:
1033:
1034: static JSBool
1035: js_getxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1036: {
1037: sbbs_t* sbbs;
1038: int x,y;
1039: JSObject* screen;
1040:
1041: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1042: return(JS_FALSE);
1043:
1044: sbbs->ansi_getxy(&x,&y);
1045:
1046: if((screen=JS_NewObject(cx,NULL,NULL,obj))==NULL)
1047: return(JS_TRUE);
1048:
1049: JS_DefineProperty(cx, screen, "x", INT_TO_JSVAL(x)
1050: ,NULL,NULL,JSPROP_ENUMERATE);
1051: JS_DefineProperty(cx, screen, "y", INT_TO_JSVAL(y)
1052: ,NULL,NULL,JSPROP_ENUMERATE);
1053:
1054: *rval = OBJECT_TO_JSVAL(screen);
1055: return(JS_TRUE);
1056: }
1057:
1058: static JSBool
1059: js_cursor_home(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1060: {
1061: sbbs_t* sbbs;
1062:
1063: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1064: return(JS_FALSE);
1065:
1066: sbbs->cursor_home();
1067: return(JS_TRUE);
1068: }
1069:
1070: static JSBool
1071: js_cursor_up(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1072: {
1073: int32 val=1;
1074: sbbs_t* sbbs;
1075:
1076: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1077: return(JS_FALSE);
1078:
1079: if(argc)
1080: JS_ValueToInt32(cx,argv[0],&val);
1081: sbbs->cursor_up(val);
1082: return(JS_TRUE);
1083: }
1084:
1085: static JSBool
1086: js_cursor_down(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1087: {
1088: int32 val=1;
1089: sbbs_t* sbbs;
1090:
1091: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1092: return(JS_FALSE);
1093:
1094: if(argc)
1095: JS_ValueToInt32(cx,argv[0],&val);
1096: sbbs->cursor_down(val);
1097: return(JS_TRUE);
1098: }
1099:
1100: static JSBool
1101: js_cursor_right(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1102: {
1103: int32 val=1;
1104: sbbs_t* sbbs;
1105:
1106: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1107: return(JS_FALSE);
1108:
1109: if(argc)
1110: JS_ValueToInt32(cx,argv[0],&val);
1111: sbbs->cursor_right(val);
1112: return(JS_TRUE);
1113: }
1114:
1115: static JSBool
1116: js_cursor_left(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1117: {
1118: int32 val=1;
1119: sbbs_t* sbbs;
1120:
1121: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1122: return(JS_FALSE);
1123:
1124: if(argc)
1125: JS_ValueToInt32(cx,argv[0],&val);
1126: sbbs->cursor_left(val);
1127: return(JS_TRUE);
1128: }
1129:
1130: static JSBool
1131: js_getlines(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1132: {
1133: sbbs_t* sbbs;
1134:
1135: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1136: return(JS_FALSE);
1137:
1138: sbbs->ansi_getlines();
1139: return(JS_TRUE);
1140: }
1141:
1142: static JSBool
1143: js_lock_input(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1144: {
1145: sbbs_t* sbbs;
1146: JSBool lock=TRUE;
1147:
1148: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1149: return(JS_FALSE);
1150:
1151: if(argc)
1152: JS_ValueToBoolean(cx, argv[0], &lock);
1153:
1154: if(lock) {
1155: pthread_mutex_lock(&sbbs->input_thread_mutex);
1156: sbbs->input_thread_mutex_locked=true;
1157: } else if(sbbs->input_thread_mutex_locked) {
1158: pthread_mutex_unlock(&sbbs->input_thread_mutex);
1159: sbbs->input_thread_mutex_locked=false;
1160: }
1161:
1162: return(JS_TRUE);
1163: }
1164:
1165: static JSBool
1166: js_telnet_cmd(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1167: {
1168: sbbs_t* sbbs;
1169: int32 cmd,opt=0;
1170:
1171: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1172: return(JS_FALSE);
1173:
1174: JS_ValueToInt32(cx,argv[0],&cmd);
1175: if(argc>1)
1176: JS_ValueToInt32(cx,argv[1],&opt);
1177:
1178: sbbs->send_telnet_cmd((uchar)cmd,(uchar)opt);
1179:
1180: return(JS_TRUE);
1181: }
1182:
1183: static JSBool
1184: js_term_supports(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1185: {
1186: sbbs_t* sbbs;
1187: int32 flags;
1188:
1189: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1190: return(JS_FALSE);
1191:
1192: if(argc) {
1193: if(!JS_ValueToInt32(cx,argv[0],&flags))
1194: return(JS_FALSE);
1195: *rval = BOOLEAN_TO_JSVAL(sbbs->term_supports(flags));
1196: } else
1197: JS_NewNumberValue(cx,sbbs->term_supports(),rval);
1198:
1199: return(JS_TRUE);
1200: }
1201:
1202: static jsSyncMethodSpec js_console_functions[] = {
1203: {"inkey", js_inkey, 0, JSTYPE_STRING, JSDOCSTR("[mode=<tt>K_NONE</tt>] [,timeout=<tt>0</tt>]")
1204: ,JSDOCSTR("get a single key with optional <i>timeout</i> in milliseconds (defaults to 0, for no wait), "
1205: "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1206: ,311
1207: },
1208: {"getkey", js_getkey, 0, JSTYPE_STRING, JSDOCSTR("[mode=<tt>K_NONE</tt>]")
1209: ,JSDOCSTR("get a single key, with wait, "
1210: "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1211: ,310
1212: },
1213: {"getstr", js_getstr, 0, JSTYPE_STRING, JSDOCSTR("[string] [,maxlen=<tt>128</tt>] [,mode=<tt>K_NONE</tt>]")
1214: ,JSDOCSTR("get a text string from the user, "
1215: "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1216: ,310
1217: },
1218: {"getnum", js_getnum, 0, JSTYPE_NUMBER, JSDOCSTR("[maxnum]")
1219: ,JSDOCSTR("get a number between 1 and <i>maxnum</i> from the user")
1220: ,310
1221: },
1222: {"getkeys", js_getkeys, 1, JSTYPE_NUMBER, JSDOCSTR("string keys [,maxnum]")
1223: ,JSDOCSTR("get one key from of a list of valid command <i>keys</i>, "
1224: "or a number between 1 and <i>maxnum</i>")
1225: ,310
1226: },
1227: {"gettemplate", js_gettemplate, 1, JSTYPE_STRING, JSDOCSTR("format [,string] [,mode=<tt>0</tt>]")
1228: ,JSDOCSTR("get a string based on template")
1229: ,310
1230: },
1231: {"ungetstr", js_ungetstr, 1, JSTYPE_VOID, JSDOCSTR("")
1232: ,JSDOCSTR("put a string in the keyboard buffer")
1233: ,310
1234: },
1235: {"yesno", js_yesno, 1, JSTYPE_BOOLEAN, JSDOCSTR("question")
1236: ,JSDOCSTR("YES/no question")
1237: ,310
1238: },
1239: {"noyes", js_noyes, 1, JSTYPE_BOOLEAN, JSDOCSTR("question")
1240: ,JSDOCSTR("NO/yes question")
1241: ,310
1242: },
1243: {"mnemonics", js_mnemonics, 1, JSTYPE_VOID, JSDOCSTR("text")
1244: ,JSDOCSTR("print a mnemonics string, command keys highlighted with tilde (~) characters")
1245: ,310
1246: },
1247: {"clear", js_clear, 0, JSTYPE_VOID, JSDOCSTR("[attribute]")
1248: ,JSDOCSTR("clear screen and home cursor, "
1249: "optionally (in v3.13b+) setting current attribute first")
1250: ,310
1251: },
1252: {"home", js_cursor_home, 0, JSTYPE_VOID, JSDOCSTR("")
1253: ,JSDOCSTR("send cursor to home position (x,y:1,1)")
1254: ,311
1255: },
1256: {"clearline", js_clearline, 0, JSTYPE_VOID, JSDOCSTR("[attribute]")
1257: ,JSDOCSTR("clear current line, "
1258: "optionally (in v3.13b+) setting current attribute first")
1259: ,310
1260: },
1261: {"cleartoeol", js_cleartoeol, 0, JSTYPE_VOID, JSDOCSTR("[attribute]")
1262: ,JSDOCSTR("clear to end-of-line (ANSI), "
1263: "optionally (in v3.13b+) setting current attribute first")
1264: ,311
1265: },
1266: {"crlf", js_crlf, 0, JSTYPE_VOID, JSDOCSTR("")
1267: ,JSDOCSTR("output a carriage-return/line-feed pair (new-line)")
1268: ,310
1269: },
1270: {"pause", js_pause, 0, JSTYPE_VOID, JSDOCSTR("")
1271: ,JSDOCSTR("display pause prompt and wait for key hit")
1272: ,310
1273: },
1274: {"beep", js_beep, 1, JSTYPE_VOID, JSDOCSTR("[count=<tt>1</tt>]")
1275: ,JSDOCSTR("beep for count number of times (default count is 1)")
1276: ,311
1277: },
1278: {"print", js_print, 1, JSTYPE_VOID, JSDOCSTR("text")
1279: ,JSDOCSTR("display a string (supports Ctrl-A codes)")
1280: ,310
1281: },
1282: {"write", js_write, 1, JSTYPE_VOID, JSDOCSTR("text")
1283: ,JSDOCSTR("display a raw string")
1284: ,310
1285: },
1286: {"putmsg", js_putmsg, 1, JSTYPE_VOID, JSDOCSTR("text [,mode=<tt>P_NONE</tt>]")
1287: ,JSDOCSTR("display message text (Ctrl-A codes, @-codes, pipe codes, etc), "
1288: "see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1289: ,310
1290: },
1291: {"center", js_center, 1, JSTYPE_VOID, JSDOCSTR("text")
1292: ,JSDOCSTR("display a string centered on the screen")
1293: ,310
1294: },
1295: {"strlen", js_strlen, 1, JSTYPE_NUMBER, JSDOCSTR("text")
1296: ,JSDOCSTR("returns the number of characters in text, excluding Ctrl-A codes")
1297: ,310
1298: },
1299: {"printfile", js_printfile, 1, JSTYPE_VOID, JSDOCSTR("filename [,mode=<tt>P_NONE</tt>]")
1300: ,JSDOCSTR("print a message text file with optional mode")
1301: ,310
1302: },
1303: {"printtail", js_printtail, 2, JSTYPE_VOID, JSDOCSTR("filename, lines [,mode=<tt>P_NONE</tt>]")
1304: ,JSDOCSTR("print last x lines of file with optional mode")
1305: ,310
1306: },
1307: {"editfile", js_editfile, 1, JSTYPE_VOID, JSDOCSTR("filename")
1308: ,JSDOCSTR("edit/create a text file using the user's preferred message editor")
1309: ,310
1310: },
1311: {"uselect", js_uselect, 0, JSTYPE_NUMBER, JSDOCSTR("[number, title, item] [,ars]")
1312: ,JSDOCSTR("user selection menu, call for each item, then with no args to display select menu")
1313: ,312
1314: },
1315: {"saveline", js_saveline, 0, JSTYPE_VOID, JSDOCSTR("")
1316: ,JSDOCSTR("save last output line")
1317: ,310
1318: },
1319: {"restoreline", js_restoreline, 0, JSTYPE_VOID, JSDOCSTR("")
1320: ,JSDOCSTR("restore last output line")
1321: ,310
1322: },
1323: {"ansi", js_ansi, 1, JSTYPE_STRING, JSDOCSTR("attribute_number")
1324: ,JSDOCSTR("returns ANSI encoding of specified <i>attribute_number</i>")
1325: ,310
1326: },
1327: {"ansi_save", js_pushxy, 0, JSTYPE_ALIAS },
1328: {"ansi_pushxy", js_pushxy, 0, JSTYPE_ALIAS },
1329: {"pushxy", js_pushxy, 0, JSTYPE_VOID, JSDOCSTR("")
1330: ,JSDOCSTR("save current cursor position (AKA ansi_save)")
1331: ,311
1332: },
1333: {"ansi_restore", js_popxy, 0, JSTYPE_ALIAS },
1334: {"ansi_popxy", js_popxy, 0, JSTYPE_ALIAS },
1335: {"popxy", js_popxy, 0, JSTYPE_VOID, JSDOCSTR("")
1336: ,JSDOCSTR("restore saved cursor position (AKA ansi_restore)")
1337: ,311
1338: },
1339: {"ansi_gotoxy", js_gotoxy, 1, JSTYPE_ALIAS },
1340: {"gotoxy", js_gotoxy, 1, JSTYPE_VOID, JSDOCSTR("[x,y] or [object { x,y }]")
1341: ,JSDOCSTR("move cursor to a specific screen coordinate (ANSI), "
1342: "arguments can be separate x and y cooridinates or an object with x and y properites "
1343: "(like that returned from <tt>console.getxy()</tt>)")
1344: ,311
1345: },
1346: {"ansi_up", js_cursor_up, 0, JSTYPE_ALIAS },
1347: {"up", js_cursor_up, 0, JSTYPE_VOID, JSDOCSTR("[rows=<tt>1</tt>]")
1348: ,JSDOCSTR("move cursor up one or more rows (ANSI)")
1349: ,311
1350: },
1351: {"ansi_down", js_cursor_down, 0, JSTYPE_ALIAS },
1352: {"down", js_cursor_down, 0, JSTYPE_VOID, JSDOCSTR("[rows=<tt>1</tt>]")
1353: ,JSDOCSTR("move cursor down one or more rows (ANSI)")
1354: ,311
1355: },
1356: {"ansi_right", js_cursor_right, 0, JSTYPE_ALIAS },
1357: {"right", js_cursor_right, 0, JSTYPE_VOID, JSDOCSTR("[columns=<tt>1</tt>]")
1358: ,JSDOCSTR("move cursor right one or more columns (ANSI)")
1359: ,311
1360: },
1361: {"ansi_left", js_cursor_left, 0, JSTYPE_ALIAS },
1362: {"left", js_cursor_left, 0, JSTYPE_VOID, JSDOCSTR("[columns=<tt>1</tt>]")
1363: ,JSDOCSTR("move cursor left one or more columns (ANSI)")
1364: ,311
1365: },
1366: {"ansi_getlines", js_getlines, 0, JSTYPE_ALIAS },
1367: {"getlines", js_getlines, 0, JSTYPE_VOID, JSDOCSTR("")
1368: ,JSDOCSTR("auto-detect the number of rows/lines on the user's terminal (ANSI)")
1369: ,311
1370: },
1371: {"ansi_getxy", js_getxy, 0, JSTYPE_ALIAS },
1372: {"getxy", js_getxy, 0, JSTYPE_OBJECT, JSDOCSTR("")
1373: ,JSDOCSTR("returns the current cursor position as an object (with x and y properties)")
1374: ,311
1375: },
1376: {"lock_input", js_lock_input, 1, JSTYPE_VOID, JSDOCSTR("[lock=<tt>true</tt>]")
1377: ,JSDOCSTR("lock the user input thread (allowing direct client socket access)")
1378: ,310
1379: },
1380: {"telnet_cmd", js_telnet_cmd, 2, JSTYPE_VOID, JSDOCSTR("command [,option=<tt>0</tt>]")
1381: ,JSDOCSTR("send Telnet command (with optional command option) to remote client")
1382: ,310
1383: },
1384: {"handle_ctrlkey", js_handle_ctrlkey, 1, JSTYPE_BOOLEAN, JSDOCSTR("key [,mode=<tt>K_NONE</tt>]")
1385: ,JSDOCSTR("call internal control key handler for specified control key, returns <tt>true</tt> if handled")
1386: ,311
1387: },
1388: {"term_supports", js_term_supports, 1, JSTYPE_BOOLEAN, JSDOCSTR("[terminal_flags]")
1389: ,JSDOCSTR("either returns <i>bool</i>, indicating whether or not the current user/client "
1390: "supports all the specified <i>terminal_flags</i>, or returns the current user/client's "
1391: "<i>terminal_flags</i> (numeric bit-field) if no <i>terminal_flags</i> were specified")
1392: ,314
1393: },
1394: {0}
1395: };
1396:
1397:
1398: static JSClass js_console_class = {
1399: "Console" /* name */
1400: ,0 /* flags */
1401: ,JS_PropertyStub /* addProperty */
1402: ,JS_PropertyStub /* delProperty */
1403: ,js_console_get /* getProperty */
1404: ,js_console_set /* setProperty */
1405: ,JS_EnumerateStub /* enumerate */
1406: ,JS_ResolveStub /* resolve */
1407: ,JS_ConvertStub /* convert */
1408: ,JS_FinalizeStub /* finalize */
1409: };
1410:
1411: JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent)
1412: {
1413: JSObject* obj;
1414: sbbs_t* sbbs;
1415:
1416: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1417: return(NULL);
1418:
1419: if((obj=JS_DefineObject(cx, parent, "console", &js_console_class, NULL
1420: ,JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
1421: return(NULL);
1422:
1423: if(!js_DefineSyncProperties(cx, obj, js_console_properties))
1424: return(NULL);
1425:
1426: if (!js_DefineSyncMethods(cx, obj, js_console_functions, FALSE))
1427: return(NULL);
1428:
1429: /* Create an array of pre-defined colors */
1430:
1431: JSObject* color_list;
1432:
1433: if((color_list=JS_NewArrayObject(cx,0,NULL))==NULL)
1434: return(NULL);
1435:
1436: if(!JS_DefineProperty(cx, obj, "color_list", OBJECT_TO_JSVAL(color_list)
1437: ,NULL, NULL, 0))
1438: return(NULL);
1439:
1440: for(uint i=0;i<sbbs->cfg.total_colors;i++) {
1441:
1442: jsval val=INT_TO_JSVAL(sbbs->cfg.color[i]);
1443: if(!JS_SetElement(cx, color_list, i, &val))
1444: return(NULL);
1445: }
1446:
1447: #ifdef BUILD_JSDOCS
1448: js_DescribeSyncObject(cx,obj,"Controls the user's Telnet/RLogin terminal",310);
1449: js_CreateArrayOfStrings(cx, obj, "_property_desc_list", con_prop_desc, JSPROP_READONLY);
1450: #endif
1451:
1452: return(obj);
1453: }
1454:
1455: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.