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