|
|
1.1 root 1: /* js_console.cpp */
2:
3: /* Synchronet JavaScript "Console" Object */
4:
5: /* $Id: js_console.cpp,v 1.58 2004/12/31 02:39:19 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 2003 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: sbbs->cfg.ctrlkey_passthru=val;
237: break;
238: default:
239: return(JS_TRUE);
240: }
241:
242: return(JS_TRUE);
243: }
244:
245: #define CON_PROP_FLAGS JSPROP_ENUMERATE
246:
247: static jsSyncPropertySpec js_console_properties[] = {
248: /* name ,tinyid ,flags ,ver */
249:
250: { "status" ,CON_PROP_STATUS ,CON_PROP_FLAGS ,310},
251: { "line_counter" ,CON_PROP_LNCNTR ,CON_PROP_FLAGS ,310},
252: { "attributes" ,CON_PROP_ATTR ,CON_PROP_FLAGS ,310},
253: { "top_of_screen" ,CON_PROP_TOS ,CON_PROP_FLAGS ,310},
254: { "screen_rows" ,CON_PROP_ROWS ,CON_PROP_FLAGS ,310},
255: { "screen_columns" ,CON_PROP_COLUMNS ,CON_PROP_FLAGS ,311},
256: { "autoterm" ,CON_PROP_AUTOTERM ,CON_PROP_FLAGS ,310},
257: { "terminal" ,CON_PROP_TERMINAL ,CON_PROP_FLAGS ,311},
258: { "timeout" ,CON_PROP_TIMEOUT ,CON_PROP_FLAGS ,310},
259: { "timeleft_warning" ,CON_PROP_TIMELEFT_WARN ,CON_PROP_FLAGS ,310},
260: { "aborted" ,CON_PROP_ABORTED ,CON_PROP_FLAGS ,310},
261: { "abortable" ,CON_PROP_ABORTABLE ,CON_PROP_FLAGS ,310},
262: { "telnet_mode" ,CON_PROP_TELNET_MODE ,CON_PROP_FLAGS ,310},
263: { "wordwrap" ,CON_PROP_WORDWRAP ,JSPROP_ENUMERATE|JSPROP_READONLY ,310},
264: { "question" ,CON_PROP_QUESTION ,CON_PROP_FLAGS ,310},
265: { "getstr_offset" ,CON_PROP_GETSTR_OFFSET ,CON_PROP_FLAGS ,311},
266: { "ctrlkey_passthru" ,CON_PROP_CTRLKEY_PASSTHRU ,CON_PROP_FLAGS ,310},
267: { "input_buffer_level",CON_PROP_INBUF_LEVEL ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
268: { "input_buffer_space",CON_PROP_INBUF_SPACE ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
269: { "output_buffer_level",CON_PROP_OUTBUF_LEVEL ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
270: { "output_buffer_space",CON_PROP_OUTBUF_SPACE ,JSPROP_ENUMERATE|JSPROP_READONLY, 312},
271: {0}
272: };
273:
274: #ifdef _DEBUG
275: static char* con_prop_desc[] = {
276: "status bitfield (see <tt>CON_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
277: ,"current line counter (used for automatic screen pause)"
278: ,"current display attributes (set with number or string value)"
279: ,"set to 1 if the terminal cursor is already at the top of the screen"
280: ,"number of terminal screen rows (in lines)"
281: ,"number of terminal screen columns (in character cells)"
282: ,"bitfield of automatically detected terminal settings "
283: "(see <tt>USER_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
284: ,"terminal type description (e.g. 'ANSI')"
285: ,"user inactivity timeout reference"
286: ,"low timeleft warning flag"
287: ,"input/output has been aborted"
288: ,"output can be aborted with Ctrl-C"
289: ,"current telnet mode bitfield (see <tt>TELNET_MODE_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
290: ,"word-wrap buffer (used by getstr) - <small>READ ONLY</small>"
291: ,"current yes/no question (set by yesno and noyes)"
292: ,"cursor position offset for use with <tt>getstr(K_USEOFFSET)</tt>"
293: ,"control key pass-through bitmask, set bits represent control key combinations "
294: "<i>not</i> handled by <tt>inkey()</tt> method"
295: ,"number of bytes currently in the input buffer (from the remote client) - <small>READ ONLY</small>"
296: ,"number of bytes available in the input buffer - <small>READ ONLY</small>"
297: ,"number of bytes currently in the output buffer (from the local server) - <small>READ ONLY</small>"
298: ,"number of bytes available in the output buffer - <small>READ ONLY</small>"
299: ,NULL
300: };
301: #endif
302:
303: /**************************/
304: /* Console Object Methods */
305: /**************************/
306:
307: static JSBool
308: js_inkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
309: {
310: char key[2];
311: int32 mode=0;
312: int32 timeout=0;
313: sbbs_t* sbbs;
314: JSString* js_str;
315:
316: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
317: return(JS_FALSE);
318:
319: if(argc)
320: JS_ValueToInt32(cx,argv[0],&mode);
321: if(argc>1)
322: JS_ValueToInt32(cx,argv[1],&timeout);
323: key[0]=sbbs->inkey(mode,timeout);
324: key[1]=0;
325:
326: if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
327: return(JS_FALSE);
328:
329: *rval = STRING_TO_JSVAL(js_str);
330: return(JS_TRUE);
331: }
332:
333: static JSBool
334: js_getkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
335: {
336: char key[2];
337: int32 mode=0;
338: sbbs_t* sbbs;
339: JSString* js_str;
340:
341: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
342: return(JS_FALSE);
343:
344: if(argc)
345: JS_ValueToInt32(cx,argv[0],&mode);
346: key[0]=sbbs->getkey(mode);
347: key[1]=0;
348:
349: if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
350: return(JS_FALSE);
351:
352: *rval = STRING_TO_JSVAL(js_str);
353: return(JS_TRUE);
354: }
355:
356: static JSBool
357: js_handle_ctrlkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
358: {
359: char key;
360: int32 mode=0;
361: sbbs_t* sbbs;
362: JSString* js_str;
363:
364: *rval = JSVAL_FALSE;
365:
366: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
367: return(JS_FALSE);
368:
369: if(JSVAL_IS_INT(argv[0]))
370: key=(char)JSVAL_TO_INT(argv[0]);
371: else {
372: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
373: return(JS_FALSE);
374: key=*JS_GetStringBytes(js_str);
375: }
376:
377: if(argc>1)
378: JS_ValueToInt32(cx, argv[1], &mode);
379:
380: *rval = BOOLEAN_TO_JSVAL(sbbs->handle_ctrlkey(key,mode)==0);
381: return(JS_TRUE);
382: }
383:
384: static JSBool
385: js_getstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
386: {
387: char *p;
388: long mode=0;
389: uintN i;
390: size_t maxlen=0;
391: sbbs_t* sbbs;
392: JSString* js_str=NULL;
393:
394: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
395: return(JS_FALSE);
396:
397: for(i=0;i<argc;i++) {
398: if(JSVAL_IS_NUMBER(argv[i])) {
399: if(!maxlen)
400: JS_ValueToInt32(cx,argv[i],(int32*)&maxlen);
401: else
402: JS_ValueToInt32(cx,argv[i],(int32*)&mode);
403: continue;
404: }
405: if(JSVAL_IS_STRING(argv[i])) {
406: js_str = JS_ValueToString(cx, argv[i]);
407: if (!js_str)
408: return(JS_FALSE);
409: }
410: }
411:
412: if(!maxlen) maxlen=128;
413:
414: if((p=(char *)calloc(1,maxlen+1))==NULL)
415: return(JS_FALSE);
416:
417: if(js_str!=NULL)
418: sprintf(p,"%.*s",(int)maxlen,JS_GetStringBytes(js_str));
419:
420: sbbs->getstr(p,maxlen,mode);
421:
422: js_str = JS_NewStringCopyZ(cx, p);
423:
424: free(p);
425:
426: if(js_str==NULL)
427: return(JS_FALSE);
428:
429: *rval = STRING_TO_JSVAL(js_str);
430: return(JS_TRUE);
431: }
432:
433: static JSBool
434: js_getnum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
435: {
436: ulong maxnum=~0;
437: sbbs_t* sbbs;
438:
439: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
440: return(JS_FALSE);
441:
442: if(argc && JSVAL_IS_NUMBER(argv[0]))
443: JS_ValueToInt32(cx,argv[0],(int32*)&maxnum);
444:
445: *rval = INT_TO_JSVAL(sbbs->getnum(maxnum));
446: return(JS_TRUE);
447: }
448:
449: static JSBool
450: js_getkeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
451: {
452: char key[2];
453: uintN i;
454: long val;
455: ulong maxnum=~0;
456: sbbs_t* sbbs;
457: JSString* js_str=NULL;
458:
459: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
460: return(JS_FALSE);
461:
462: for(i=0;i<argc;i++) {
463: if(JSVAL_IS_NUMBER(argv[i])) {
464: JS_ValueToInt32(cx,argv[i],(int32*)&maxnum);
465: continue;
466: }
467: if(JSVAL_IS_STRING(argv[i])) {
468: js_str = JS_ValueToString(cx, argv[i]);
469: }
470: }
471: if(js_str==NULL)
472: return(JS_FALSE);
473:
474: val=sbbs->getkeys(JS_GetStringBytes(js_str),maxnum);
475:
476: if(val==-1) { // abort
477: *rval = INT_TO_JSVAL(0);
478: } else if(val<0) { // number
479: val&=~0x80000000;
480: *rval = INT_TO_JSVAL(val);
481: } else { // key
482: key[0]=(uchar)val;
483: key[1]=0;
484: if((js_str = JS_NewStringCopyZ(cx, key))==NULL)
485: return(JS_FALSE);
486: *rval = STRING_TO_JSVAL(js_str);
487: }
488:
489: return(JS_TRUE);
490: }
491:
492: static JSBool
493: js_gettemplate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
494: {
495: char str[128];
496: long mode=0;
497: uintN i;
498: sbbs_t* sbbs;
499: JSString* js_str=NULL;
500: JSString* js_fmt=NULL;
501:
502: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
503: return(JS_FALSE);
504:
505: for(i=0;i<argc;i++) {
506: if(JSVAL_IS_STRING(argv[i])) {
507: if(js_fmt==NULL)
508: js_fmt = JS_ValueToString(cx, argv[i]);
509: else
510: js_str = JS_ValueToString(cx, argv[i]);
511: } else if(JSVAL_IS_NUMBER(argv[i]))
512: JS_ValueToInt32(cx,argv[i],(int32*)&mode);
513: }
514:
515: if(js_fmt==NULL)
516: return(JS_FALSE);
517:
518: if(js_str==NULL)
519: str[0]=0;
520: else
521: SAFECOPY(str,JS_GetStringBytes(js_str));
522:
523: sbbs->gettmplt(str,JS_GetStringBytes(js_fmt),mode);
524:
525: if((js_str=JS_NewStringCopyZ(cx, str))==NULL)
526: return(JS_FALSE);
527:
528: *rval = STRING_TO_JSVAL(js_str);
529: return(JS_TRUE);
530: }
531:
532: static JSBool
533: js_ungetstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
534: {
535: char* p;
536: sbbs_t* sbbs;
537: JSString* js_str;
538:
539: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
540: return(JS_FALSE);
541:
542: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
543: return(JS_FALSE);
544:
545: p=JS_GetStringBytes(js_str);
546:
547: while(p && *p)
548: sbbs->ungetkey(*(p++));
549: *rval=JSVAL_VOID;
550: return(JS_TRUE);
551: }
552:
553: static JSBool
554: js_yesno(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
555: {
556: sbbs_t* sbbs;
557: JSString* js_str;
558:
559: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
560: return(JS_FALSE);
561:
562: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
563: return(JS_FALSE);
564:
565: *rval = BOOLEAN_TO_JSVAL(sbbs->yesno(JS_GetStringBytes(js_str)));
566: return(JS_TRUE);
567: }
568:
569: static JSBool
570: js_noyes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
571: {
572: sbbs_t* sbbs;
573: JSString* js_str;
574:
575: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
576: return(JS_FALSE);
577:
578: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
579: return(JS_FALSE);
580:
581: *rval = BOOLEAN_TO_JSVAL(sbbs->noyes(JS_GetStringBytes(js_str)));
582: return(JS_TRUE);
583: }
584:
585: static JSBool
586: js_mnemonics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
587: {
588: sbbs_t* sbbs;
589: JSString* js_str;
590:
591: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
592: return(JS_FALSE);
593:
594: if((js_str=JS_ValueToString(cx, argv[0]))==NULL)
595: return(JS_FALSE);
596:
597: sbbs->mnemonics(JS_GetStringBytes(js_str));
598: *rval=JSVAL_VOID;
599: return(JS_TRUE);
600: }
601:
602: static JSBool
603: js_clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
604: {
605: sbbs_t* sbbs;
606:
607: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
608: return(JS_FALSE);
609:
610: sbbs->CLS;
611: *rval=JSVAL_VOID;
612: return(JS_TRUE);
613: }
614:
615: static JSBool
616: js_clearline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
617: {
618: sbbs_t* sbbs;
619:
620: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
621: return(JS_FALSE);
622:
623: sbbs->clearline();
624: *rval=JSVAL_VOID;
625: return(JS_TRUE);
626: }
627:
628: static JSBool
629: js_cleartoeol(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
630: {
631: sbbs_t* sbbs;
632:
633: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
634: return(JS_FALSE);
635:
636: sbbs->cleartoeol();
637: *rval=JSVAL_VOID;
638: return(JS_TRUE);
639: }
640:
641: static JSBool
642: js_crlf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
643: {
644: sbbs_t* sbbs;
645:
646: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
647: return(JS_FALSE);
648:
649: sbbs->outchar(CR);
650: sbbs->outchar(LF);
651: *rval=JSVAL_VOID;
652: return(JS_TRUE);
653: }
654:
655: static JSBool
656: js_pause(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
657: {
658: sbbs_t* sbbs;
659:
660: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
661: return(JS_FALSE);
662:
663: sbbs->pause();
664: *rval=JSVAL_VOID;
665: return(JS_TRUE);
666: }
667:
668: static JSBool
669: js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
670: {
671: sbbs_t* sbbs;
672: int32 i;
673: int32 count=1;
674:
675: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
676: return(JS_FALSE);
677:
678: if(argc)
679: JS_ValueToInt32(cx, argv[0], &count);
680: for(i=0;i<count;i++)
681: sbbs->outchar('\a');
682:
683: *rval=JSVAL_VOID;
684: return(JS_TRUE);
685: }
686:
687: static JSBool
688: js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
689: {
690: JSString* str;
691: sbbs_t* sbbs;
692:
693: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
694: return(JS_FALSE);
695:
696: str = JS_ValueToString(cx, argv[0]);
697: if (!str)
698: return(JS_FALSE);
699:
700: sbbs->bputs(JS_GetStringBytes(str));
701: *rval=JSVAL_VOID;
702: return(JS_TRUE);
703: }
704:
705: static JSBool
706: js_strlen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
707: {
708: JSString* str;
709:
710: if((str=JS_ValueToString(cx, argv[0]))==NULL)
711: return(JS_FALSE);
712:
713: *rval = INT_TO_JSVAL(bstrlen(JS_GetStringBytes(str)));
714: return(JS_TRUE);
715: }
716:
717: static JSBool
718: js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
719: {
720: JSString* str;
721: sbbs_t* sbbs;
722:
723: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
724: return(JS_FALSE);
725:
726: str = JS_ValueToString(cx, argv[0]);
727: if (!str)
728: return(JS_FALSE);
729:
730: sbbs->rputs(JS_GetStringBytes(str));
731: *rval=JSVAL_VOID;
732: return(JS_TRUE);
733: }
734:
735: static JSBool
736: js_putmsg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
737: {
738: long mode=0;
739: JSString* str;
740: sbbs_t* sbbs;
741:
742: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
743: return(JS_FALSE);
744:
745: str = JS_ValueToString(cx, argv[0]);
746: if (!str)
747: return(JS_FALSE);
748:
749: if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
750: JS_ValueToInt32(cx,argv[1],(int32*)&mode);
751:
752: sbbs->putmsg(JS_GetStringBytes(str),mode);
753: *rval=JSVAL_VOID;
754: return(JS_TRUE);
755: }
756:
757: static JSBool
758: js_printfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
759: {
760: long mode=0;
761: JSString* str;
762: sbbs_t* sbbs;
763:
764: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
765: return(JS_FALSE);
766:
767: str = JS_ValueToString(cx, argv[0]);
768: if (!str)
769: return(JS_FALSE);
770:
771: if(argc>1 && JSVAL_IS_NUMBER(argv[1]))
772: JS_ValueToInt32(cx,argv[1],(int32*)&mode);
773:
774: sbbs->printfile(JS_GetStringBytes(str),mode);
775: *rval=JSVAL_VOID;
776: return(JS_TRUE);
777: }
778:
779: static JSBool
780: js_printtail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
781: {
782: int lines=0;
783: long mode=0;
784: uintN i;
785: sbbs_t* sbbs;
786: JSString* js_str=NULL;
787:
788: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
789: return(JS_FALSE);
790:
791: for(i=0;i<argc;i++) {
792: if(JSVAL_IS_NUMBER(argv[i])) {
793: if(!lines)
794: JS_ValueToInt32(cx,argv[i],(int32*)&lines);
795: else
796: JS_ValueToInt32(cx,argv[i],(int32*)&mode);
797: } else if(JSVAL_IS_STRING(argv[i]))
798: js_str = JS_ValueToString(cx, argv[i]);
799: }
800:
801: if(js_str==NULL)
802: return(JS_FALSE);
803:
804: if(!lines)
805: lines=5;
806:
807: sbbs->printtail(JS_GetStringBytes(js_str),lines,mode);
808: *rval=JSVAL_VOID;
809: return(JS_TRUE);
810: }
811:
812: static JSBool
813: js_editfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
814: {
815: JSString* str;
816: sbbs_t* sbbs;
817:
818: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
819: return(JS_FALSE);
820:
821: if((str=JS_ValueToString(cx, argv[0]))==NULL)
822: return(JS_FALSE);
823:
824: sbbs->editfile(JS_GetStringBytes(str));
825: *rval=JSVAL_VOID;
826: return(JS_TRUE);
827: }
828:
829:
830: static JSBool
831: js_uselect(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
832: {
833: uintN i;
834: int32 num=0;
835: char* title=NULL;
836: char* item=NULL;
837: char* ar_str;
838: uchar* ar=NULL;
839: sbbs_t* sbbs;
840: JSString* js_str;
841:
842: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
843: return(JS_FALSE);
844:
845: if(!argc) {
846: *rval = INT_TO_JSVAL(sbbs->uselect(0,0,NULL,NULL,NULL));
847: return(JS_TRUE);
848: }
849:
850: for(i=0;i<argc;i++) {
851: if(JSVAL_IS_NUMBER(argv[i])) {
852: JS_ValueToInt32(cx,argv[i],&num);
853: continue;
854: }
855: if((js_str=JS_ValueToString(cx, argv[i]))==NULL)
856: return(JS_FALSE);
857:
858: if(title==NULL)
859: title=JS_GetStringBytes(js_str);
860: else if(item==NULL)
861: item=JS_GetStringBytes(js_str);
862: else {
863: ar_str=JS_GetStringBytes(js_str);
864: ar=arstr(NULL,ar_str,&sbbs->cfg);
865: }
866: }
867:
868: *rval = INT_TO_JSVAL(sbbs->uselect(1, num, title, item, ar));
869: return(JS_TRUE);
870: }
871:
872: static JSBool
873: js_center(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
874: {
875: JSString* str;
876: sbbs_t* sbbs;
877:
878: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
879: return(JS_FALSE);
880:
881: str = JS_ValueToString(cx, argv[0]);
882: if (!str)
883: return(JS_FALSE);
884:
885: sbbs->center(JS_GetStringBytes(str));
886: *rval=JSVAL_VOID;
887: return(JS_TRUE);
888: }
889:
890: static JSBool
891: js_saveline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
892: {
893: sbbs_t* sbbs;
894:
895: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
896: return(JS_FALSE);
897:
898: sbbs->slatr[sbbs->slcnt]=sbbs->latr;
899: sprintf(sbbs->slbuf[sbbs->slcnt<SAVE_LINES ? sbbs->slcnt++ : sbbs->slcnt]
900: ,"%.*s",sbbs->lbuflen,sbbs->lbuf);
901: sbbs->lbuflen=0;
902: *rval=JSVAL_VOID;
903: return(JS_TRUE);
904: }
905:
906: static JSBool
907: js_restoreline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
908: {
909: sbbs_t* sbbs;
910:
911: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
912: return(JS_FALSE);
913:
914: sbbs->lbuflen=0;
915: sbbs->attr(sbbs->slatr[--sbbs->slcnt]);
916: sbbs->rputs(sbbs->slbuf[sbbs->slcnt]);
917: sbbs->curatr=LIGHTGRAY;
918: *rval=JSVAL_VOID;
919: return(JS_TRUE);
920: }
921:
922: static JSBool
923: js_ansi(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
924: {
925: int32 attr=0;
926: JSString* js_str;
927: sbbs_t* sbbs;
928:
929: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
930: return(JS_FALSE);
931:
932: if(argc)
933: JS_ValueToInt32(cx,argv[0],&attr);
934: if((js_str=JS_NewStringCopyZ(cx,sbbs->ansi(attr)))==NULL)
935: return(JS_FALSE);
936:
937: *rval = STRING_TO_JSVAL(js_str);
938: return(JS_TRUE);
939: }
940:
941: static JSBool
942: js_pushxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
943: {
944: sbbs_t* sbbs;
945:
946: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
947: return(JS_FALSE);
948:
949: sbbs->ANSI_SAVE();
950: *rval=JSVAL_VOID;
951: return(JS_TRUE);
952: }
953:
954: static JSBool
955: js_popxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
956: {
957: sbbs_t* sbbs;
958:
959: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
960: return(JS_FALSE);
961:
962: sbbs->ANSI_RESTORE();
963: *rval=JSVAL_VOID;
964: return(JS_TRUE);
965: }
966:
967: static JSBool
968: js_gotoxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
969: {
970: int32 x=1,y=1;
971: jsval val;
972: sbbs_t* sbbs;
973:
974: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
975: return(JS_FALSE);
976:
977: if(JSVAL_IS_OBJECT(argv[0])) {
978: JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),"x", &val);
979: JS_ValueToInt32(cx,val,&x);
980: JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),"y", &val);
981: JS_ValueToInt32(cx,val,&y);
982: } else {
983: JS_ValueToInt32(cx,argv[0],&x);
984: JS_ValueToInt32(cx,argv[1],&y);
985: }
986:
987: sbbs->GOTOXY(x,y);
988: *rval=JSVAL_VOID;
989: return(JS_TRUE);
990: }
991:
992:
993: static JSBool
994: js_getxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
995: {
996: sbbs_t* sbbs;
997: int x,y;
998: JSObject* screen;
999:
1000: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1001: return(JS_FALSE);
1002:
1003: sbbs->ansi_getxy(&x,&y);
1004:
1005: if((screen=JS_NewObject(cx,NULL,NULL,obj))==NULL)
1006: return(JS_TRUE);
1007:
1008: JS_DefineProperty(cx, screen, "x", INT_TO_JSVAL(x)
1009: ,NULL,NULL,JSPROP_ENUMERATE);
1010: JS_DefineProperty(cx, screen, "y", INT_TO_JSVAL(y)
1011: ,NULL,NULL,JSPROP_ENUMERATE);
1012:
1013: *rval = OBJECT_TO_JSVAL(screen);
1014: return(JS_TRUE);
1015: }
1016:
1017: static JSBool
1018: js_cursor_home(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1019: {
1020: sbbs_t* sbbs;
1021:
1022: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1023: return(JS_FALSE);
1024:
1025: sbbs->cursor_home();
1026: *rval=JSVAL_VOID;
1027: return(JS_TRUE);
1028: }
1029:
1030: static JSBool
1031: js_cursor_up(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1032: {
1033: int32 val=1;
1034: sbbs_t* sbbs;
1035:
1036: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1037: return(JS_FALSE);
1038:
1039: if(argc)
1040: JS_ValueToInt32(cx,argv[0],&val);
1041: sbbs->cursor_up(val);
1042: *rval=JSVAL_VOID;
1043: return(JS_TRUE);
1044: }
1045:
1046: static JSBool
1047: js_cursor_down(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1048: {
1049: int32 val=1;
1050: sbbs_t* sbbs;
1051:
1052: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1053: return(JS_FALSE);
1054:
1055: if(argc)
1056: JS_ValueToInt32(cx,argv[0],&val);
1057: sbbs->cursor_down(val);
1058: *rval=JSVAL_VOID;
1059: return(JS_TRUE);
1060: }
1061:
1062: static JSBool
1063: js_cursor_right(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1064: {
1065: int32 val=1;
1066: sbbs_t* sbbs;
1067:
1068: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1069: return(JS_FALSE);
1070:
1071: if(argc)
1072: JS_ValueToInt32(cx,argv[0],&val);
1073: sbbs->cursor_right(val);
1074: *rval=JSVAL_VOID;
1075: return(JS_TRUE);
1076: }
1077:
1078: static JSBool
1079: js_cursor_left(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1080: {
1081: int32 val=1;
1082: sbbs_t* sbbs;
1083:
1084: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1085: return(JS_FALSE);
1086:
1087: if(argc)
1088: JS_ValueToInt32(cx,argv[0],&val);
1089: sbbs->cursor_left(val);
1090: *rval=JSVAL_VOID;
1091: return(JS_TRUE);
1092: }
1093:
1094: static JSBool
1095: js_getlines(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1096: {
1097: sbbs_t* sbbs;
1098:
1099: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1100: return(JS_FALSE);
1101:
1102: sbbs->ansi_getlines();
1103: *rval=JSVAL_VOID;
1104: return(JS_TRUE);
1105: }
1106:
1107: static JSBool
1108: js_lock_input(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1109: {
1110: sbbs_t* sbbs;
1111: JSBool lock=TRUE;
1112:
1113: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1114: return(JS_FALSE);
1115:
1116: if(argc)
1117: JS_ValueToBoolean(cx, argv[0], &lock);
1118:
1119: if(lock) {
1120: pthread_mutex_lock(&sbbs->input_thread_mutex);
1121: sbbs->input_thread_mutex_locked=true;
1122: } else if(sbbs->input_thread_mutex_locked) {
1123: pthread_mutex_unlock(&sbbs->input_thread_mutex);
1124: sbbs->input_thread_mutex_locked=false;
1125: }
1126:
1127: *rval=JSVAL_VOID;
1128: return(JS_TRUE);
1129: }
1130:
1131: static JSBool
1132: js_telnet_cmd(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1133: {
1134: sbbs_t* sbbs;
1135: int32 cmd,opt;
1136:
1137: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1138: return(JS_FALSE);
1139:
1140: JS_ValueToInt32(cx,argv[0],&cmd);
1141: JS_ValueToInt32(cx,argv[0],&opt);
1142:
1143: sbbs->send_telnet_cmd((uchar)cmd,(uchar)opt);
1144:
1145: *rval=JSVAL_VOID;
1146: return(JS_TRUE);
1147: }
1148:
1149:
1150: static jsSyncMethodSpec js_console_functions[] = {
1151: {"inkey", js_inkey, 0, JSTYPE_STRING, JSDOCSTR("[number mode] [,number timeout]")
1152: ,JSDOCSTR("get a single key with optional <i>timeout</i> in milliseconds (defaults to 0, for no wait), "
1153: "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1154: ,311
1155: },
1156: {"getkey", js_getkey, 0, JSTYPE_STRING, JSDOCSTR("[number mode]")
1157: ,JSDOCSTR("get a single key, with wait, "
1158: "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1159: ,310
1160: },
1161: {"getstr", js_getstr, 0, JSTYPE_STRING, JSDOCSTR("[string][,maxlen][,mode]")
1162: ,JSDOCSTR("get a text string from the user, "
1163: "see <tt>K_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1164: ,310
1165: },
1166: {"getnum", js_getnum, 0, JSTYPE_NUMBER, JSDOCSTR("[maxnum]")
1167: ,JSDOCSTR("get a number between 1 and <i>maxnum</i> from the user")
1168: ,310
1169: },
1170: {"getkeys", js_getkeys, 1, JSTYPE_NUMBER, JSDOCSTR("string keys [,maxnum]")
1171: ,JSDOCSTR("get one key from of a list of valid command <i>keys</i>, "
1172: "or a number between 1 and <i>maxnum</i>")
1173: ,310
1174: },
1175: {"gettemplate", js_gettemplate, 1, JSTYPE_STRING, JSDOCSTR("format [,string] [,mode]")
1176: ,JSDOCSTR("get a string based on template")
1177: ,310
1178: },
1179: {"ungetstr", js_ungetstr, 1, JSTYPE_VOID, ""
1180: ,JSDOCSTR("put a string in the keyboard buffer")
1181: ,310
1182: },
1183: {"yesno", js_yesno, 1, JSTYPE_BOOLEAN, JSDOCSTR("string question")
1184: ,JSDOCSTR("YES/no question")
1185: ,310
1186: },
1187: {"noyes", js_noyes, 1, JSTYPE_BOOLEAN, JSDOCSTR("string question")
1188: ,JSDOCSTR("NO/yes question")
1189: ,310
1190: },
1191: {"mnemonics", js_mnemonics, 1, JSTYPE_VOID, JSDOCSTR("string text")
1192: ,JSDOCSTR("print a mnemonics string")
1193: ,310
1194: },
1195: {"clear", js_clear, 0, JSTYPE_VOID, ""
1196: ,JSDOCSTR("clear screen and home cursor")
1197: ,310
1198: },
1199: {"home", js_cursor_home, 0, JSTYPE_VOID, ""
1200: ,JSDOCSTR("send cursor to home position (x,y:1,1)")
1201: ,311
1202: },
1203: {"clearline", js_clearline, 0, JSTYPE_VOID, ""
1204: ,JSDOCSTR("clear current line")
1205: ,310
1206: },
1207: {"cleartoeol", js_cleartoeol, 0, JSTYPE_VOID, ""
1208: ,JSDOCSTR("clear to end-of-line (ANSI)")
1209: ,311
1210: },
1211: {"crlf", js_crlf, 0, JSTYPE_VOID, ""
1212: ,JSDOCSTR("output a carriage-return/line-feed pair (new-line)")
1213: ,310
1214: },
1215: {"pause", js_pause, 0, JSTYPE_VOID, ""
1216: ,JSDOCSTR("display pause prompt and wait for key hit")
1217: ,310
1218: },
1219: {"beep", js_beep, 1, JSTYPE_VOID, JSDOCSTR("[number count]")
1220: ,JSDOCSTR("beep for count number of times (default count is 1)")
1221: ,311
1222: },
1223: {"print", js_print, 1, JSTYPE_VOID, JSDOCSTR("string text")
1224: ,JSDOCSTR("display a string (supports Ctrl-A codes)")
1225: ,310
1226: },
1227: {"write", js_write, 1, JSTYPE_VOID, JSDOCSTR("string text")
1228: ,JSDOCSTR("display a raw string")
1229: ,310
1230: },
1231: {"putmsg", js_putmsg, 1, JSTYPE_VOID, JSDOCSTR("string text [,number mode]")
1232: ,JSDOCSTR("display message text (Ctrl-A codes, @-codes, pipe codes, etc), "
1233: "see <tt>P_*</tt> in <tt>sbbsdefs.js</tt> for <i>mode</i> bits")
1234: ,310
1235: },
1236: {"center", js_center, 1, JSTYPE_VOID, JSDOCSTR("string text")
1237: ,JSDOCSTR("display a string centered on the screen")
1238: ,310
1239: },
1240: {"strlen", js_strlen, 1, JSTYPE_NUMBER, JSDOCSTR("string text")
1241: ,JSDOCSTR("returns the number of characters in text, excluding Ctrl-A codes")
1242: ,310
1243: },
1244: {"printfile", js_printfile, 1, JSTYPE_VOID, JSDOCSTR("string text [,number mode]")
1245: ,JSDOCSTR("print a message text file with optional mode")
1246: ,310
1247: },
1248: {"printtail", js_printtail, 2, JSTYPE_VOID, JSDOCSTR("string text, number lines [,number mode]")
1249: ,JSDOCSTR("print last x lines of file with optional mode")
1250: ,310
1251: },
1252: {"editfile", js_editfile, 1, JSTYPE_VOID, JSDOCSTR("string filename")
1253: ,JSDOCSTR("edit/create a text file using the user's preferred message editor")
1254: ,310
1255: },
1256: {"uselect", js_uselect, 0, JSTYPE_NUMBER, JSDOCSTR("[number, string title, string item, string ars]")
1257: ,JSDOCSTR("user selection menu, call for each item, then with no args to display select menu")
1258: ,312
1259: },
1260: {"saveline", js_saveline, 0, JSTYPE_VOID, ""
1261: ,JSDOCSTR("save last output line")
1262: ,310
1263: },
1264: {"restoreline", js_restoreline, 0, JSTYPE_VOID, ""
1265: ,JSDOCSTR("restore last output line")
1266: ,310
1267: },
1268: {"ansi", js_ansi, 1, JSTYPE_STRING, JSDOCSTR("number attribute")
1269: ,JSDOCSTR("returns ANSI encoding of specified attribute")
1270: ,310
1271: },
1272: {"ansi_save", js_pushxy, 0, JSTYPE_ALIAS },
1273: {"ansi_pushxy", js_pushxy, 0, JSTYPE_ALIAS },
1274: {"pushxy", js_pushxy, 0, JSTYPE_VOID, ""
1275: ,JSDOCSTR("save current cursor position (AKA ansi_save)")
1276: ,311
1277: },
1278: {"ansi_restore", js_popxy, 0, JSTYPE_ALIAS },
1279: {"ansi_popxy", js_popxy, 0, JSTYPE_ALIAS },
1280: {"popxy", js_popxy, 0, JSTYPE_VOID, ""
1281: ,JSDOCSTR("restore saved cursor position (AKA ansi_restore)")
1282: ,311
1283: },
1284: {"ansi_gotoxy", js_gotoxy, 1, JSTYPE_ALIAS },
1285: {"gotoxy", js_gotoxy, 1, JSTYPE_VOID, JSDOCSTR("number x,y")
1286: ,JSDOCSTR("Move cursor to a specific screen coordinate (ANSI), "
1287: "arguments can be separate x and y cooridinates or an object with x and y properites "
1288: "(like that returned from <tt>console.getxy()</tt>)")
1289: ,311
1290: },
1291: {"ansi_up", js_cursor_up, 0, JSTYPE_ALIAS },
1292: {"up", js_cursor_up, 0, JSTYPE_VOID, JSDOCSTR("[number rows]")
1293: ,JSDOCSTR("Move cursor up one or more rows (ANSI)")
1294: ,311
1295: },
1296: {"ansi_down", js_cursor_down, 0, JSTYPE_ALIAS },
1297: {"down", js_cursor_down, 0, JSTYPE_VOID, JSDOCSTR("[number rows]")
1298: ,JSDOCSTR("Move cursor down one or more rows (ANSI)")
1299: ,311
1300: },
1301: {"ansi_right", js_cursor_right, 0, JSTYPE_ALIAS },
1302: {"right", js_cursor_right, 0, JSTYPE_VOID, JSDOCSTR("[number columns]")
1303: ,JSDOCSTR("Move cursor right one or more columns (ANSI)")
1304: ,311
1305: },
1306: {"ansi_left", js_cursor_left, 0, JSTYPE_ALIAS },
1307: {"left", js_cursor_left, 0, JSTYPE_VOID, JSDOCSTR("[number columns]")
1308: ,JSDOCSTR("Move cursor left one or more columns (ANSI)")
1309: ,311
1310: },
1311: {"ansi_getlines", js_getlines, 0, JSTYPE_ALIAS },
1312: {"getlines", js_getlines, 0, JSTYPE_VOID, ""
1313: ,JSDOCSTR("Auto-detect the number of rows/lines on the user's terminal (ANSI)")
1314: ,311
1315: },
1316: {"ansi_getxy", js_getxy, 0, JSTYPE_ALIAS },
1317: {"getxy", js_getxy, 0, JSTYPE_OBJECT, ""
1318: ,JSDOCSTR("Returns the current cursor position as an object (with x and y properties)")
1319: ,311
1320: },
1321: {"lock_input", js_lock_input, 1, JSTYPE_VOID, JSDOCSTR("[boolean lock]")
1322: ,JSDOCSTR("Lock the user input thread (allowing direct client socket access)")
1323: ,310
1324: },
1325: {"telnet_cmd", js_telnet_cmd, 2, JSTYPE_VOID, JSDOCSTR("number cmd [,number option]")
1326: ,JSDOCSTR("Send telnet command (with optional command option) to remote client")
1327: ,310
1328: },
1329: {"handle_ctrlkey", js_handle_ctrlkey, 1, JSTYPE_BOOLEAN, JSDOCSTR("string key [,number mode]")
1330: ,JSDOCSTR("Call internal control key handler for specified control key, returns true if handled")
1331: ,311
1332: },
1333: {0}
1334: };
1335:
1336:
1337: static JSClass js_console_class = {
1338: "Console" /* name */
1339: ,0 /* flags */
1340: ,JS_PropertyStub /* addProperty */
1341: ,JS_PropertyStub /* delProperty */
1342: ,js_console_get /* getProperty */
1343: ,js_console_set /* setProperty */
1344: ,JS_EnumerateStub /* enumerate */
1345: ,JS_ResolveStub /* resolve */
1346: ,JS_ConvertStub /* convert */
1347: ,JS_FinalizeStub /* finalize */
1348: };
1349:
1350: JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent)
1351: {
1352: JSObject* obj;
1353: sbbs_t* sbbs;
1354:
1355: if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
1356: return(NULL);
1357:
1358: if((obj=JS_DefineObject(cx, parent, "console", &js_console_class, NULL
1359: ,JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
1360: return(NULL);
1361:
1362: if(!js_DefineSyncProperties(cx, obj, js_console_properties))
1363: return(NULL);
1364:
1365: if (!js_DefineSyncMethods(cx, obj, js_console_functions, FALSE))
1366: return(NULL);
1367:
1368: /* Create an array of pre-defined colors */
1369:
1370: JSObject* color_list;
1371:
1372: if((color_list=JS_NewArrayObject(cx,0,NULL))==NULL)
1373: return(NULL);
1374:
1375: if(!JS_DefineProperty(cx, obj, "color_list", OBJECT_TO_JSVAL(color_list)
1376: ,NULL, NULL, 0))
1377: return(NULL);
1378:
1379: for(uint i=0;i<sbbs->cfg.total_colors;i++) {
1380:
1381: jsval val=INT_TO_JSVAL(sbbs->cfg.color[i]);
1382: if(!JS_SetElement(cx, color_list, i, &val))
1383: return(NULL);
1384: }
1385:
1386: #ifdef _DEBUG
1387: js_DescribeSyncObject(cx,obj,"Controls the user's Telnet/RLogin terminal",310);
1388: js_CreateArrayOfStrings(cx, obj, "_property_desc_list", con_prop_desc, JSPROP_READONLY);
1389: #endif
1390:
1391: return(obj);
1392: }
1393:
1394: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.