|
|
1.1 root 1: /* js_uifc.c */
2:
3: /* Synchronet "uifc" (user interface) object */
4:
5: /* $Id: js_uifc.c,v 1.10 2006/06/14 02:34:49 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #ifndef JAVASCRIPT
39: #define JAVASCRIPT
40: #endif
41:
42: #include "sbbs.h"
43: #include "uifc.h"
44: #include "ciolib.h"
45:
46: /* Properties */
47: enum {
48: PROP_INITIALIZED /* read-only */
49: ,PROP_MODE
50: ,PROP_CHANGES
51: ,PROP_SAVNUM
52: ,PROP_SCRN_LEN
53: ,PROP_SCRN_WIDTH
54: ,PROP_ESC_DELAY
55: ,PROP_HELPBUF
56: ,PROP_HCOLOR
57: ,PROP_LCOLOR
58: ,PROP_BCOLOR
59: ,PROP_CCOLOR
60: ,PROP_LBCOLOR
61: ,PROP_LIST_HEIGHT
62: };
63:
64: static JSBool js_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
65: {
66: jsint tiny;
67: uifcapi_t* uifc;
68:
69: if((uifc=(uifcapi_t*)JS_GetPrivate(cx,obj))==NULL)
70: return(JS_FALSE);
71:
72: tiny = JSVAL_TO_INT(id);
73:
74: switch(tiny) {
75: case PROP_INITIALIZED:
76: *vp=BOOLEAN_TO_JSVAL(uifc->initialized);
77: break;
78: case PROP_MODE:
79: JS_NewNumberValue(cx,uifc->mode,vp);
80: break;
81: case PROP_CHANGES:
82: *vp=BOOLEAN_TO_JSVAL(uifc->changes);
83: break;
84: case PROP_SAVNUM:
85: *vp=INT_TO_JSVAL(uifc->savnum);
86: break;
87: case PROP_SCRN_LEN:
88: *vp=INT_TO_JSVAL(uifc->scrn_len);
89: break;
90: case PROP_SCRN_WIDTH:
91: *vp=INT_TO_JSVAL(uifc->scrn_width);
92: break;
93: case PROP_ESC_DELAY:
94: *vp=INT_TO_JSVAL(uifc->esc_delay);
95: break;
96: case PROP_HELPBUF:
97: *vp=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,uifc->helpbuf));
98: break;
99: case PROP_HCOLOR:
100: *vp=INT_TO_JSVAL(uifc->hclr);
101: break;
102: case PROP_LCOLOR:
103: *vp=INT_TO_JSVAL(uifc->lclr);
104: break;
105: case PROP_BCOLOR:
106: *vp=INT_TO_JSVAL(uifc->bclr);
107: break;
108: case PROP_CCOLOR:
109: *vp=INT_TO_JSVAL(uifc->cclr);
110: break;
111: case PROP_LBCOLOR:
112: *vp=INT_TO_JSVAL(uifc->lbclr);
113: break;
114: case PROP_LIST_HEIGHT:
115: *vp=INT_TO_JSVAL(uifc->list_height);
116: break;
117: }
118:
119: return(JS_TRUE);
120: }
121:
122: static JSBool js_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
123: {
124: jsint tiny;
125: int32 i=0;
126: uifcapi_t* uifc;
127:
128: if((uifc=(uifcapi_t*)JS_GetPrivate(cx,obj))==NULL)
129: return(JS_FALSE);
130:
131: tiny = JSVAL_TO_INT(id);
132:
133: switch(tiny) {
134: case PROP_MODE:
135: JS_ValueToInt32(cx, *vp, (int32*)&uifc->mode);
136: break;
137: case PROP_CHANGES:
138: JS_ValueToBoolean(cx,*vp,&uifc->changes);
139: break;
140: case PROP_SAVNUM:
141: JS_ValueToInt32(cx, *vp, (int32*)&uifc->savnum);
142: break;
143: case PROP_SCRN_LEN:
144: JS_ValueToInt32(cx, *vp, (int32*)&uifc->scrn_len);
145: break;
146: case PROP_SCRN_WIDTH:
147: JS_ValueToInt32(cx, *vp, (int32*)&uifc->scrn_width);
148: break;
149: case PROP_ESC_DELAY:
150: JS_ValueToInt32(cx, *vp, (int32*)&uifc->esc_delay);
151: break;
152: case PROP_HELPBUF:
153: uifc->helpbuf=js_ValueToStringBytes(cx, *vp, NULL);
154: break;
155: case PROP_LIST_HEIGHT:
156: JS_ValueToInt32(cx, *vp, (int32*)&uifc->list_height);
157: break;
158: case PROP_HCOLOR:
159: case PROP_LCOLOR:
160: case PROP_BCOLOR:
161: case PROP_CCOLOR:
162: case PROP_LBCOLOR:
163: JS_ValueToInt32(cx, *vp, &i);
164: switch(tiny) {
165: case PROP_HCOLOR:
166: uifc->hclr=(char)i;
167: break;
168: case PROP_LCOLOR:
169: uifc->lclr=(char)i;
170: break;
171: case PROP_BCOLOR:
172: uifc->bclr=(char)i;
173: break;
174: case PROP_CCOLOR:
175: uifc->cclr=(char)i;
176: break;
177: case PROP_LBCOLOR:
178: uifc->lbclr=(char)i;
179: break;
180: }
181: break;
182: }
183:
184: return(JS_TRUE);
185: }
186:
187: static jsSyncPropertySpec js_properties[] = {
188: /* name, tinyid, flags, ver */
189:
190: { "initialized", PROP_INITIALIZED, JSPROP_ENUMERATE|JSPROP_READONLY, 314 },
191: { "mode", PROP_MODE, JSPROP_ENUMERATE, 314 },
192: { "changes", PROP_CHANGES, JSPROP_ENUMERATE, 314 },
193: { "save_num", PROP_SAVNUM, JSPROP_ENUMERATE, 314 },
194: { "screen_length", PROP_SCRN_LEN, JSPROP_ENUMERATE, 314 },
195: { "screen_width", PROP_SCRN_WIDTH, JSPROP_ENUMERATE, 314 },
196: { "list_height", PROP_LIST_HEIGHT, JSPROP_ENUMERATE, 314 },
197: { "esc_delay", PROP_ESC_DELAY, JSPROP_ENUMERATE, 314 },
198: { "help_text", PROP_HELPBUF, JSPROP_ENUMERATE, 314 },
199: { "background_color", PROP_BCOLOR, JSPROP_ENUMERATE, 314 },
200: { "frame_color", PROP_HCOLOR, JSPROP_ENUMERATE, 314 },
201: { "text_color", PROP_LCOLOR, JSPROP_ENUMERATE, 314 },
202: { "inverse_color", PROP_CCOLOR, JSPROP_ENUMERATE, 314 },
203: { "lightbar_color", PROP_LBCOLOR, JSPROP_ENUMERATE, 314 },
204: {0}
205: };
206:
207: /* Convenience functions */
208: static uifcapi_t* get_uifc(JSContext *cx, JSObject *obj)
209: {
210: uifcapi_t* uifc;
211:
212: if((uifc=(uifcapi_t*)JS_GetPrivate(cx,obj))==NULL)
213: return(NULL);
214:
215: if(!uifc->initialized) {
216: JS_ReportError(cx,"UIFC not initialized");
217: return(NULL);
218: }
219:
220: return(uifc);
221: }
222:
223: /* Methods */
224:
225: static JSBool
226: js_uifc_init(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
227: {
228: int ciolib_mode=CIOLIB_MODE_AUTO;
229: char* title="Synchronet";
230: char* mode;
231: uifcapi_t* uifc;
232:
233: *rval = JSVAL_FALSE;
234:
235: if((uifc=(uifcapi_t*)JS_GetPrivate(cx,obj))==NULL)
236: return(JS_FALSE);
237:
238: if(argc && (title=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
239: return(JS_FALSE);
240:
241: if(argc>1 && (mode=js_ValueToStringBytes(cx, argv[1], NULL))!=NULL) {
242: if(!stricmp(mode,"STDIO"))
243: ciolib_mode=-1;
244: else if(!stricmp(mode,"AUTO"))
245: ciolib_mode=CIOLIB_MODE_AUTO;
246: else if(!stricmp(mode,"X"))
247: ciolib_mode=CIOLIB_MODE_X;
248: else if(!stricmp(mode,"ANSI"))
249: ciolib_mode=CIOLIB_MODE_ANSI;
250: else if(!stricmp(mode,"CONIO"))
251: ciolib_mode=CIOLIB_MODE_CONIO;
252: }
253:
254: if(ciolib_mode==-1) {
255: if(uifcinix(uifc))
256: return(JS_TRUE);
257: } else {
258: if(initciolib(ciolib_mode))
259: return(JS_TRUE);
260:
261: if(uifcini32(uifc))
262: return(JS_TRUE);
263: }
264:
265: *rval = JSVAL_TRUE;
266: uifc->scrn(title);
267: return(JS_TRUE);
268: }
269:
270: static JSBool
271: js_uifc_bail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
272: {
273: uifcapi_t* uifc;
274:
275: if((uifc=get_uifc(cx,obj))==NULL)
276: return(JS_FALSE);
277:
278: uifc->bail();
279: return(JS_TRUE);
280: }
281:
282: static JSBool
283: js_uifc_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
284: {
285: char* str;
286: uifcapi_t* uifc;
287:
288: if((uifc=get_uifc(cx,obj))==NULL)
289: return(JS_FALSE);
290:
291: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
292: return(JS_FALSE);
293:
294: uifc->msg(str);
295: return(JS_TRUE);
296: }
297:
298: static JSBool
299: js_uifc_pop(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
300: {
301: char* str=NULL;
302: uifcapi_t* uifc;
303:
304: if((uifc=get_uifc(cx,obj))==NULL)
305: return(JS_FALSE);
306:
307: if(argc)
308: str=js_ValueToStringBytes(cx, argv[0], NULL);
309:
310: uifc->pop(str);
311: return(JS_TRUE);
312: }
313:
314: static JSBool
315: js_uifc_input(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
316: {
317: char* str;
318: char* org=NULL;
319: char* prompt=NULL;
320: int32 maxlen=0;
321: int32 left=0;
322: int32 top=0;
323: int32 mode=0;
324: int32 kmode=0;
325: uifcapi_t* uifc;
326: uintN argn=0;
327:
328: if((uifc=get_uifc(cx,obj))==NULL)
329: return(JS_FALSE);
330:
331: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
332: && !JS_ValueToInt32(cx,argv[argn++],&mode))
333: return(JS_FALSE);
334: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
335: && !JS_ValueToInt32(cx,argv[argn++],&left))
336: return(JS_FALSE);
337: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
338: && !JS_ValueToInt32(cx,argv[argn++],&top))
339: return(JS_FALSE);
340: if(argn<argc && JSVAL_IS_STRING(argv[argn])
341: && (prompt=js_ValueToStringBytes(cx,argv[argn++],NULL))==NULL)
342: return(JS_FALSE);
343: if(argn<argc && JSVAL_IS_STRING(argv[argn])
344: && (org=js_ValueToStringBytes(cx,argv[argn++],NULL))==NULL)
345: return(JS_FALSE);
346: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
347: && !JS_ValueToInt32(cx,argv[argn++],&maxlen))
348: return(JS_FALSE);
349: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
350: && !JS_ValueToInt32(cx,argv[argn++],&kmode))
351: return(JS_FALSE);
352:
353: if(!maxlen)
354: maxlen=40;
355:
356: if((str=(char*)alloca(maxlen+1))==NULL)
357: return(JS_FALSE);
358:
359: memset(str,0,maxlen+1);
360:
361: if(org)
362: strncpy(str,org,maxlen);
363:
364: if(uifc->input(mode, left, top, prompt, str, maxlen, kmode)<0)
365: return(JS_TRUE);
366:
367: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,str));
368:
369: return(JS_TRUE);
370: }
371:
372: static JSBool
373: js_uifc_list(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
374: {
375: char* title=NULL;
376: int32 left=0;
377: int32 top=0;
378: int32 width=0;
379: int32 dflt=0;
380: int32 bar=0;
381: int32 mode=0;
382: JSObject* objarg;
383: uifcapi_t* uifc;
384: uintN argn=0;
385: jsval val;
386: jsuint i;
387: jsuint numopts;
388: str_list_t opts=NULL;
389:
390: if((uifc=get_uifc(cx,obj))==NULL)
391: return(JS_FALSE);
392:
393: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
394: && !JS_ValueToInt32(cx,argv[argn++],&mode))
395: return(JS_FALSE);
396: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
397: && !JS_ValueToInt32(cx,argv[argn++],&left))
398: return(JS_FALSE);
399: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
400: && !JS_ValueToInt32(cx,argv[argn++],&top))
401: return(JS_FALSE);
402: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
403: && !JS_ValueToInt32(cx,argv[argn++],&width))
404: return(JS_FALSE);
405: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
406: && !JS_ValueToInt32(cx,argv[argn++],&dflt))
407: return(JS_FALSE);
408: if(argn<argc && JSVAL_IS_NUMBER(argv[argn])
409: && !JS_ValueToInt32(cx,argv[argn++],&bar))
410: return(JS_FALSE);
411: if(argn<argc && JSVAL_IS_STRING(argv[argn])
412: && (title=js_ValueToStringBytes(cx,argv[argn++],NULL))==NULL)
413: return(JS_FALSE);
414: if(argn<argc && JSVAL_IS_OBJECT(argv[argn])) {
415: if((objarg = JSVAL_TO_OBJECT(argv[argn++]))==NULL)
416: return(JS_FALSE);
417: if(JS_IsArrayObject(cx, objarg)) {
418: if(!JS_GetArrayLength(cx, objarg, &numopts))
419: return(JS_TRUE);
420: opts=strListInit();
421: for(i=0;i<numopts;i++) {
422: if(!JS_GetElement(cx, objarg, i, &val))
423: break;
424: strListPush(&opts,js_ValueToStringBytes(cx,val,NULL));
425: }
426: }
427: }
428:
429: *rval = INT_TO_JSVAL(uifc->list(mode,left,top,width,(int*)&dflt,(int*)&bar,title,opts));
430: strListFree(&opts);
431: return(JS_TRUE);
432: }
433:
434: /* Destructor */
435:
436: static void
437: js_finalize(JSContext *cx, JSObject *obj)
438: {
439: uifcapi_t* p;
440:
441: if((p=(uifcapi_t*)JS_GetPrivate(cx,obj))==NULL)
442: return;
443:
444: free(p);
445: JS_SetPrivate(cx,obj,NULL);
446: }
447:
448: static jsSyncMethodSpec js_functions[] = {
449: {"init", js_uifc_init, 1, JSTYPE_BOOLEAN, JSDOCSTR("string title")
450: ,JSDOCSTR("initialize")
451: ,314
452: },
453: {"bail", js_uifc_bail, 0, JSTYPE_VOID, JSDOCSTR("")
454: ,JSDOCSTR("uninitialize")
455: ,314
456: },
457: {"msg", js_uifc_msg, 1, JSTYPE_VOID, JSDOCSTR("string text")
458: ,JSDOCSTR("print a message")
459: ,314
460: },
461: {"pop", js_uifc_pop, 1, JSTYPE_VOID, JSDOCSTR("[string text]")
462: ,JSDOCSTR("popup (or down) a message")
463: ,314
464: },
465: {"input", js_uifc_input, 0, JSTYPE_STRING, JSDOCSTR("[...]")
466: ,JSDOCSTR("prompt for a string input")
467: ,314
468: },
469: {"list", js_uifc_list, 0, JSTYPE_STRING, JSDOCSTR("[...]")
470: ,JSDOCSTR("select from a list of options")
471: ,314
472: },
473: {0}
474: };
475:
476:
477: static JSClass js_uifc_class = {
478: "UIFC" /* name */
479: ,JSCLASS_HAS_PRIVATE /* flags */
480: ,JS_PropertyStub /* addProperty */
481: ,JS_PropertyStub /* delProperty */
482: ,js_get /* getProperty */
483: ,js_set /* setProperty */
484: ,JS_EnumerateStub /* enumerate */
485: ,JS_ResolveStub /* resolve */
486: ,JS_ConvertStub /* convert */
487: ,js_finalize /* finalize */
488: };
489:
490: JSObject* js_CreateUifcObject(JSContext* cx, JSObject* parent)
491: {
492: JSObject* obj;
493: uifcapi_t* api;
494:
495: if((obj = JS_DefineObject(cx, parent, "uifc", &js_uifc_class, NULL
496: ,JSPROP_ENUMERATE|JSPROP_READONLY))==NULL)
497: return(NULL);
498:
499: if((api=(uifcapi_t*)malloc(sizeof(uifcapi_t)))==NULL)
500: return(NULL);
501:
502: memset(api,0,sizeof(uifcapi_t));
503: api->size=sizeof(uifcapi_t);
504: api->esc_delay=25;
505:
506: if(!JS_SetPrivate(cx, obj, api)) /* Store a pointer to uifcapi_t */
507: return(NULL);
508:
509: if(!js_DefineSyncProperties(cx, obj, js_properties)) /* expose them */
510: return(NULL);
511:
512: if(!js_DefineSyncMethods(cx, obj, js_functions, /* append? */ FALSE))
513: return(NULL);
514:
515: return(obj);
516: }
517:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.