|
|
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.