|
|
1.1 ! root 1: /* getkey.cpp */ ! 2: ! 3: /* Synchronet single-key console functions */ ! 4: ! 5: /* $Id: getkey.cpp,v 1.6 2000/11/28 02:41:50 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 2000 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: /****************************************************************************/ ! 41: /* Waits for remote or local user to hit a key. Inactivity timer is checked */ ! 42: /* and hangs up if inactive for 4 minutes. Returns key hit, or uppercase of */ ! 43: /* key hit if mode&K_UPPER or key out of KEY BUFFER. Does not print key. */ ! 44: /* Called from functions all over the place. */ ! 45: /****************************************************************************/ ! 46: char sbbs_t::getkey(long mode) ! 47: { ! 48: char ch,coldkey,c=0,spin=sbbs_random(5); ! 49: ! 50: if(!online || !input_thread_running) ! 51: return(0); ! 52: sys_status&=~SS_ABORT; ! 53: if((sys_status&SS_USERON || action==NODE_DFLT) && !(mode&K_GETSTR)) ! 54: mode|=(useron.misc&SPIN); ! 55: lncntr=0; ! 56: timeout=time(NULL); ! 57: if(mode&K_SPIN) ! 58: outchar(' '); ! 59: do { ! 60: checkline(); /* check to make sure remote user is still online */ ! 61: if(sys_status&SS_ABORT) { ! 62: if(mode&K_SPIN) /* back space once if on spinning cursor */ ! 63: bputs("\b \b"); ! 64: return(0); } ! 65: ! 66: if(sys_status&SS_SYSPAGE) { ! 67: sbbs_beep(sbbs_random(800),100); ! 68: } ! 69: ! 70: if(mode&K_SPIN) ! 71: switch(spin) { ! 72: case 0: ! 73: switch(c++) { ! 74: case 0: ! 75: outchar(BS); ! 76: outchar('�'); ! 77: break; ! 78: case 10: ! 79: outchar(BS); ! 80: outchar('/'); ! 81: break; ! 82: case 20: ! 83: outchar(BS); ! 84: outchar('�'); ! 85: break; ! 86: case 30: ! 87: outchar(BS); ! 88: outchar('\\'); ! 89: break; ! 90: case 40: ! 91: c=0; ! 92: break; ! 93: default: ! 94: if(!(cfg.node_misc&NM_WINOS2)) ! 95: mswait(DELAY_SPIN); ! 96: break; } ! 97: break; ! 98: case 1: ! 99: switch(c++) { ! 100: case 0: ! 101: outchar(BS); ! 102: outchar('�'); ! 103: break; ! 104: case 10: ! 105: outchar(BS); ! 106: outchar('�'); ! 107: break; ! 108: case 20: ! 109: outchar(BS); ! 110: outchar('�'); ! 111: break; ! 112: case 30: ! 113: outchar(BS); ! 114: outchar('�'); ! 115: break; ! 116: case 40: ! 117: outchar(BS); ! 118: outchar('�'); ! 119: break; ! 120: case 50: ! 121: outchar(BS); ! 122: outchar('�'); ! 123: break; ! 124: case 60: ! 125: c=0; ! 126: break; ! 127: default: ! 128: if(!(cfg.node_misc&NM_WINOS2)) ! 129: mswait(DELAY_SPIN); ! 130: break; } ! 131: break; ! 132: case 2: ! 133: switch(c++) { ! 134: case 0: ! 135: outchar(BS); ! 136: outchar('-'); ! 137: break; ! 138: case 10: ! 139: outchar(BS); ! 140: outchar('='); ! 141: break; ! 142: case 20: ! 143: outchar(BS); ! 144: outchar('�'); ! 145: break; ! 146: case 30: ! 147: outchar(BS); ! 148: outchar('='); ! 149: break; ! 150: case 40: ! 151: c=0; ! 152: break; ! 153: default: ! 154: if(!(cfg.node_misc&NM_WINOS2)) ! 155: mswait(DELAY_SPIN); ! 156: break; } ! 157: break; ! 158: case 3: ! 159: switch(c++) { ! 160: case 0: ! 161: outchar(BS); ! 162: outchar('�'); ! 163: break; ! 164: case 10: ! 165: outchar(BS); ! 166: outchar('�'); ! 167: break; ! 168: case 20: ! 169: outchar(BS); ! 170: outchar('�'); ! 171: break; ! 172: case 30: ! 173: outchar(BS); ! 174: outchar('�'); ! 175: break; ! 176: case 40: ! 177: c=0; ! 178: break; ! 179: default: ! 180: if(!(cfg.node_misc&NM_WINOS2)) ! 181: mswait(DELAY_SPIN); ! 182: break; } ! 183: break; ! 184: case 4: ! 185: switch(c++) { ! 186: case 0: ! 187: outchar(BS); ! 188: outchar('�'); ! 189: break; ! 190: case 10: ! 191: outchar(BS); ! 192: outchar('�'); ! 193: break; ! 194: case 20: ! 195: outchar(BS); ! 196: outchar('�'); ! 197: break; ! 198: case 30: ! 199: outchar(BS); ! 200: outchar('�'); ! 201: break; ! 202: case 40: ! 203: c=0; ! 204: break; ! 205: default: ! 206: if(!(cfg.node_misc&NM_WINOS2)) ! 207: mswait(DELAY_SPIN); ! 208: break; } ! 209: break; } ! 210: ! 211: ch=inkey(mode); ! 212: if(sys_status&SS_ABORT) ! 213: return(0); ! 214: now=time(NULL); ! 215: if(ch) { ! 216: if(mode&K_NUMBER && isprint(ch) && !isdigit(ch)) ! 217: continue; ! 218: if(mode&K_ALPHA && isprint(ch) && !isalpha(ch)) ! 219: continue; ! 220: if(mode&K_NOEXASC && ch&0x80) ! 221: continue; ! 222: if(mode&K_SPIN) ! 223: bputs("\b \b"); ! 224: if(mode&K_COLD && ch>SP && useron.misc&COLDKEYS) { ! 225: if(mode&K_UPPER) ! 226: outchar(toupper(ch)); ! 227: else ! 228: outchar(ch); ! 229: while((coldkey=inkey(mode))==0 && online && !(sys_status&SS_ABORT)) ! 230: checkline(); ! 231: bputs("\b \b"); ! 232: if(coldkey==BS) ! 233: continue; ! 234: if(coldkey>SP) ! 235: ungetkey(coldkey); } ! 236: if(mode&K_UPPER) ! 237: return(toupper(ch)); ! 238: return(ch); } ! 239: if(sys_status&SS_USERON && !(sys_status&SS_LCHAT)) gettimeleft(); ! 240: else if(online && ! 241: ((cfg.node_dollars_per_call && now-answertime>SEC_BILLING) ! 242: || (now-answertime>SEC_LOGON && !(sys_status&SS_LCHAT)))) { ! 243: console&=~(CON_R_ECHOX|CON_L_ECHOX); ! 244: console|=(CON_R_ECHO|CON_L_ECHO); ! 245: bputs(text[TakenTooLongToLogon]); ! 246: hangup(); } ! 247: if(sys_status&SS_USERON && online && (timeleft/60)<(5-timeleft_warn) ! 248: && !SYSOP && !(sys_status&SS_LCHAT)) { ! 249: timeleft_warn=5-(timeleft/60); ! 250: SAVELINE; ! 251: attr(LIGHTGRAY); ! 252: bprintf(text[OnlyXminutesLeft] ! 253: ,((ushort)timeleft/60)+1,(timeleft/60) ? "s" : nulstr); ! 254: RESTORELINE; } ! 255: ! 256: if(online==ON_LOCAL && cfg.node_misc&NM_NO_INACT) ! 257: timeout=now; ! 258: if(now-timeout>=cfg.sec_warn) { /* warning */ ! 259: if(sys_status&SS_USERON) { ! 260: SAVELINE; ! 261: bputs(text[AreYouThere]); } ! 262: else ! 263: bputs("\7\7"); ! 264: while(!inkey(0) && online && now-timeout>=cfg.sec_warn) { ! 265: now=time(NULL); ! 266: if(now-timeout>=cfg.sec_hangup) { ! 267: if(online==ON_REMOTE) { ! 268: console|=CON_R_ECHO; ! 269: console&=~CON_R_ECHOX; } ! 270: bputs(text[CallBackWhenYoureThere]); ! 271: logline(nulstr,"Inactive"); ! 272: hangup(); ! 273: return(0); } ! 274: mswait(100); } ! 275: if(sys_status&SS_USERON) { ! 276: bputs("\r\1n\1>"); ! 277: RESTORELINE; } ! 278: timeout=now; } ! 279: ! 280: } while(online); ! 281: return(0); ! 282: } ! 283: ! 284: ! 285: /****************************************************************************/ ! 286: /* Outputs a string highlighting characters preceeded by a tilde */ ! 287: /****************************************************************************/ ! 288: void sbbs_t::mnemonics(char *str) ! 289: { ! 290: char *ctrl_a_codes; ! 291: long l; ! 292: ! 293: if(!strchr(str,'~')) { ! 294: mnestr=str; ! 295: bputs(str); ! 296: return; } ! 297: ctrl_a_codes=strchr(str,1); ! 298: if(!ctrl_a_codes) { ! 299: if(str[0]=='@' && str[strlen(str)-1]=='@' && !strchr(str,SP)) { ! 300: mnestr=str; ! 301: bputs(str); ! 302: return; } ! 303: attr(cfg.color[clr_mnelow]); } ! 304: l=0L; ! 305: while(str[l]) { ! 306: if(str[l]=='~' && str[l+1]) { ! 307: if(!(useron.misc&ANSI)) ! 308: outchar('('); ! 309: l++; ! 310: if(!ctrl_a_codes) ! 311: attr(cfg.color[clr_mnehigh]); ! 312: outchar(str[l]); ! 313: l++; ! 314: if(!(useron.misc&ANSI)) ! 315: outchar(')'); ! 316: if(!ctrl_a_codes) ! 317: attr(cfg.color[clr_mnelow]); } ! 318: else { ! 319: if(str[l]==1) { /* ctrl-a */ ! 320: ctrl_a(str[++l]); /* skip the ctrl-a */ ! 321: l++; } /* skip the attribute code */ ! 322: else ! 323: outchar(str[l++]); } } ! 324: if(!ctrl_a_codes) ! 325: attr(cfg.color[clr_mnecmd]); ! 326: } ! 327: ! 328: /****************************************************************************/ ! 329: /* Prompts user for Y or N (yes or no) and CR is interpreted as a Y */ ! 330: /* Returns 1 for Y or 0 for N */ ! 331: /* Called from quite a few places */ ! 332: /****************************************************************************/ ! 333: bool sbbs_t::yesno(char *str) ! 334: { ! 335: char ch; ! 336: ! 337: strcpy(question,str); ! 338: SYNC; ! 339: if(useron.misc&WIP) { ! 340: strip_ctrl(question); ! 341: menu("yesno"); } ! 342: else ! 343: bprintf(text[YesNoQuestion],str); ! 344: while(online) { ! 345: if(sys_status&SS_ABORT) ! 346: ch=text[YN][1]; ! 347: else ! 348: ch=getkey(K_UPPER|K_COLD); ! 349: if(ch==text[YN][0] || ch==CR) { ! 350: if(bputs(text[Yes])) ! 351: CRLF; ! 352: lncntr=0; ! 353: return(true); } ! 354: if(ch==text[YN][1]) { ! 355: if(bputs(text[No])) ! 356: CRLF; ! 357: lncntr=0; ! 358: return(false); } } ! 359: return(true); ! 360: } ! 361: ! 362: /****************************************************************************/ ! 363: /* Prompts user for N or Y (no or yes) and CR is interpreted as a N */ ! 364: /* Returns 1 for N or 0 for Y */ ! 365: /* Called from quite a few places */ ! 366: /****************************************************************************/ ! 367: bool sbbs_t::noyes(char *str) ! 368: { ! 369: char ch; ! 370: ! 371: strcpy(question,str); ! 372: SYNC; ! 373: if(useron.misc&WIP) { ! 374: strip_ctrl(question); ! 375: menu("noyes"); } ! 376: else ! 377: bprintf(text[NoYesQuestion],str); ! 378: while(online) { ! 379: if(sys_status&SS_ABORT) ! 380: ch=text[YN][1]; ! 381: else ! 382: ch=getkey(K_UPPER|K_COLD); ! 383: if(ch==text[YN][1] || ch==CR) { ! 384: if(bputs(text[No])) ! 385: CRLF; ! 386: lncntr=0; ! 387: return(true); } ! 388: if(ch==text[YN][0]) { ! 389: if(bputs(text[Yes])) ! 390: CRLF; ! 391: lncntr=0; ! 392: return(false); } } ! 393: return(true); ! 394: } ! 395: ! 396: /****************************************************************************/ ! 397: /* Waits for remote or local user to hit a key that is contained inside str.*/ ! 398: /* 'str' should contain uppercase characters only. When a valid key is hit, */ ! 399: /* it is echoed (upper case) and is the return value. */ ! 400: /* Called from quite a few functions */ ! 401: /****************************************************************************/ ! 402: long sbbs_t::getkeys(char *keys, ulong max) ! 403: { ! 404: char str[81]; ! 405: uchar ch,n=0,c; ! 406: ulong i=0; ! 407: ! 408: sprintf(str,"%.*s",sizeof(str)-1,keys); ! 409: strupr(str); ! 410: while(online) { ! 411: ch=getkey(K_UPPER); ! 412: if(max && ch>0x7f) /* extended ascii chars are digits to isdigit() */ ! 413: continue; ! 414: if(sys_status&SS_ABORT) { /* return -1 if Ctrl-C hit */ ! 415: attr(LIGHTGRAY); ! 416: CRLF; ! 417: lncntr=0; ! 418: return(-1); } ! 419: if(ch && !n && (strchr(str,ch))) { /* return character if in string */ ! 420: outchar(ch); ! 421: if(useron.misc&COLDKEYS && ch>SP) { ! 422: while(online && !(sys_status&SS_ABORT)) { ! 423: c=getkey(0); ! 424: if(c==CR || c==BS) ! 425: break; } ! 426: if(sys_status&SS_ABORT) { ! 427: CRLF; ! 428: return(-1); } ! 429: if(c==BS) { ! 430: bputs("\b \b"); ! 431: continue; } } ! 432: attr(LIGHTGRAY); ! 433: CRLF; ! 434: lncntr=0; ! 435: return(ch); } ! 436: if(ch==CR && max) { /* return 0 if no number */ ! 437: attr(LIGHTGRAY); ! 438: CRLF; ! 439: lncntr=0; ! 440: if(n) ! 441: return(i|0x80000000L); /* return number plus high bit */ ! 442: return(0); } ! 443: if(ch==BS && n) { ! 444: bputs("\b \b"); ! 445: i/=10; ! 446: n--; } ! 447: else if(max && isdigit(ch) && (i*10)+(ch&0xf)<=max && (ch!='0' || n)) { ! 448: i*=10; ! 449: n++; ! 450: i+=ch&0xf; ! 451: outchar(ch); ! 452: if(i*10>max && !(useron.misc&COLDKEYS)) { ! 453: attr(LIGHTGRAY); ! 454: CRLF; ! 455: lncntr=0; ! 456: return(i|0x80000000L); } } } ! 457: return(-1); ! 458: } ! 459: ! 460: /****************************************************************************/ ! 461: /* Prints PAUSE message and waits for a key stoke */ ! 462: /****************************************************************************/ ! 463: void sbbs_t::pause() ! 464: { ! 465: char ch; ! 466: uchar tempattrs=curatr; /* was lclatr(-1) */ ! 467: int i,j; ! 468: long l=K_UPPER; ! 469: ! 470: RIOSYNC(0); ! 471: if(sys_status&SS_ABORT) ! 472: return; ! 473: lncntr=0; ! 474: if(online==ON_REMOTE) ! 475: rioctl(IOFI); ! 476: bputs(text[Pause]); ! 477: j=bstrlen(text[Pause]); ! 478: if(sys_status&SS_USERON && !(useron.misc&NO_EXASCII) && !(useron.misc&WIP) ! 479: && !(cfg.node_misc&NM_NOPAUSESPIN)) ! 480: l|=K_SPIN; ! 481: ch=getkey(l); ! 482: if(ch==text[YN][1] || ch=='Q') ! 483: sys_status|=SS_ABORT; ! 484: else if(ch==LF) // down arrow == display one more line ! 485: lncntr=rows-2; ! 486: if(text[Pause][0]!='@') ! 487: for(i=0;i<j;i++) ! 488: bputs("\b \b"); ! 489: getnodedat(cfg.node_num,&thisnode,0); ! 490: nodesync(); ! 491: attr(tempattrs); ! 492: } ! 493: ! 494: /****************************************************************************/ ! 495: /* Puts a character into the input buffer */ ! 496: /****************************************************************************/ ! 497: void sbbs_t::ungetkey(char ch) ! 498: { ! 499: ! 500: keybuf[keybuftop++]=ch; ! 501: if(keybuftop==KEY_BUFSIZE) ! 502: keybuftop=0; ! 503: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.