|
|
1.1 ! root 1: /* inkey.cpp */ ! 2: ! 3: /* Synchronet single key input function (no wait) */ ! 4: ! 5: /* $Id: inkey.cpp,v 1.28 2006/09/07 22:59:26 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: #include "sbbs.h" ! 39: ! 40: #define LAST_STAT_LINE 16 ! 41: ! 42: #define nosound() ! 43: ! 44: /****************************************************************************/ ! 45: /* Returns character if a key has been hit remotely and responds */ ! 46: /* Called from functions getkey, msgabort and main_sec */ ! 47: /****************************************************************************/ ! 48: char sbbs_t::inkey(long mode, unsigned long timeout) ! 49: { ! 50: uchar ch=0; ! 51: ! 52: if(keybuftop!=keybufbot) { ! 53: ch=keybuf[keybufbot++]; ! 54: if(keybufbot==KEY_BUFSIZE) ! 55: keybufbot=0; ! 56: } else ! 57: ch=incom(timeout); ! 58: ! 59: if(ch==0) { ! 60: // moved here from getkey() on AUG-29-2001 ! 61: if(sys_status&SS_SYSPAGE) ! 62: sbbs_beep(sbbs_random(800),100); ! 63: #if 0 ! 64: if(!(mode&K_GETSTR) || mode&K_LOWPRIO || cfg.node_misc&NM_LOWPRIO) ! 65: YIELD(); ! 66: #endif ! 67: return(0); ! 68: } ! 69: ! 70: if(cfg.node_misc&NM_7BITONLY ! 71: && (!(sys_status&SS_USERON) || useron.misc&NO_EXASCII)) ! 72: ch&=0x7f; ! 73: ! 74: timeout=time(NULL); ! 75: ! 76: /* Is this a control key */ ! 77: if(ch<' ') { ! 78: if(cfg.ctrlkey_passthru&(1<<ch)) /* flagged as passthru? */ ! 79: return(ch); /* do not handle here */ ! 80: return(handle_ctrlkey(ch,mode)); ! 81: } ! 82: ! 83: if(mode&K_UPPER) ! 84: ch=toupper(ch); ! 85: ! 86: return(ch); ! 87: } ! 88: ! 89: char sbbs_t::handle_ctrlkey(char ch, long mode) ! 90: { ! 91: char str[512]; ! 92: char tmp[512]; ! 93: uint i,j; ! 94: ! 95: if(ch==CTRL_C) { /* Ctrl-C Abort */ ! 96: sys_status|=SS_ABORT; ! 97: if(mode&K_SPIN) /* back space once if on spinning cursor */ ! 98: backspace(); ! 99: return(0); ! 100: } ! 101: if(ch==CTRL_Z && !(mode&K_MSG) ! 102: && action!=NODE_PCHT) { /* Ctrl-Z toggle raw input mode */ ! 103: if(hotkey_inside>1) /* only allow so much recursion */ ! 104: return(0); ! 105: hotkey_inside++; ! 106: if(mode&K_SPIN) ! 107: bputs("\b "); ! 108: SAVELINE; ! 109: attr(LIGHTGRAY); ! 110: CRLF; ! 111: bputs(text[RawMsgInputModeIsNow]); ! 112: if(console&CON_RAW_IN) ! 113: bputs(text[OFF]); ! 114: else ! 115: bputs(text[ON]); ! 116: console^=CON_RAW_IN; ! 117: CRLF; ! 118: CRLF; ! 119: RESTORELINE; ! 120: lncntr=0; ! 121: hotkey_inside--; ! 122: if(action!=NODE_MAIN && action!=NODE_XFER) ! 123: return(CTRL_Z); ! 124: return(0); ! 125: } ! 126: ! 127: if(console&CON_RAW_IN) /* ignore ctrl-key commands if in raw mode */ ! 128: return(ch); ! 129: ! 130: #if 0 /* experimental removal to fix Tracker1's pause module problem with down-arrow */ ! 131: if(ch==LF) /* ignore LF's if not in raw mode */ ! 132: return(0); ! 133: #endif ! 134: ! 135: /* Global hot key event */ ! 136: for(i=0;i<cfg.total_hotkeys;i++) ! 137: if(cfg.hotkey[i]->key==ch) ! 138: break; ! 139: if(i<cfg.total_hotkeys) { ! 140: if(hotkey_inside>1) /* only allow so much recursion */ ! 141: return(0); ! 142: hotkey_inside++; ! 143: if(mode&K_SPIN) ! 144: bputs("\b "); ! 145: if(!(sys_status&SS_SPLITP)) { ! 146: SAVELINE; ! 147: attr(LIGHTGRAY); ! 148: CRLF; ! 149: } ! 150: external(cmdstr(cfg.hotkey[i]->cmd,nulstr,nulstr,NULL),0); ! 151: if(!(sys_status&SS_SPLITP)) { ! 152: CRLF; ! 153: RESTORELINE; ! 154: } ! 155: lncntr=0; ! 156: hotkey_inside--; ! 157: return(0); ! 158: } ! 159: ! 160: switch(ch) { ! 161: case CTRL_O: /* Ctrl-O toggles pause temporarily */ ! 162: useron.misc^=UPAUSE; ! 163: return(0); ! 164: case CTRL_P: /* Ctrl-P Private node-node comm */ ! 165: if(!(sys_status&SS_USERON)) ! 166: return(0); /* keep from being recursive */ ! 167: if(hotkey_inside>1) /* only allow so much recursion */ ! 168: return(0); ! 169: hotkey_inside++; ! 170: if(mode&K_SPIN) ! 171: bputs("\b "); ! 172: if(!(sys_status&SS_SPLITP)) { ! 173: SAVELINE; ! 174: attr(LIGHTGRAY); ! 175: CRLF; ! 176: } ! 177: nodesync(); /* read any waiting messages */ ! 178: nodemsg(); /* send a message */ ! 179: SYNC; ! 180: if(!(sys_status&SS_SPLITP)) { ! 181: CRLF; ! 182: RESTORELINE; ! 183: } ! 184: lncntr=0; ! 185: hotkey_inside--; ! 186: return(0); ! 187: ! 188: case CTRL_U: /* Ctrl-U Users online */ ! 189: /* needs recursion checking */ ! 190: if(!(sys_status&SS_USERON)) ! 191: return(0); ! 192: if(hotkey_inside>1) /* only allow so much recursion */ ! 193: return(0); ! 194: hotkey_inside++; ! 195: if(mode&K_SPIN) ! 196: bputs("\b "); ! 197: if(!(sys_status&SS_SPLITP)) { ! 198: SAVELINE; ! 199: attr(LIGHTGRAY); ! 200: CRLF; ! 201: } ! 202: whos_online(true); /* list users */ ! 203: ASYNC; ! 204: if(!(sys_status&SS_SPLITP)) { ! 205: CRLF; ! 206: RESTORELINE; ! 207: } ! 208: lncntr=0; ! 209: hotkey_inside--; ! 210: return(0); ! 211: case CTRL_T: /* Ctrl-T Time information */ ! 212: if(sys_status&SS_SPLITP) ! 213: return(ch); ! 214: if(!(sys_status&SS_USERON)) ! 215: return(0); ! 216: if(hotkey_inside>1) /* only allow so much recursion */ ! 217: return(0); ! 218: hotkey_inside++; ! 219: if(mode&K_SPIN) ! 220: bputs("\b "); ! 221: SAVELINE; ! 222: attr(LIGHTGRAY); ! 223: now=time(NULL); ! 224: bprintf(text[TiLogon],timestr(&logontime)); ! 225: bprintf(text[TiNow],timestr(&now)); ! 226: bprintf(text[TiTimeon] ! 227: ,sectostr(now-logontime,tmp)); ! 228: bprintf(text[TiTimeLeft] ! 229: ,sectostr(timeleft,tmp)); ! 230: SYNC; ! 231: RESTORELINE; ! 232: lncntr=0; ! 233: hotkey_inside--; ! 234: return(0); ! 235: case CTRL_K: /* Ctrl-k Control key menu */ ! 236: if(sys_status&SS_SPLITP) ! 237: return(ch); ! 238: if(!(sys_status&SS_USERON)) ! 239: return(0); ! 240: if(hotkey_inside>1) /* only allow so much recursion */ ! 241: return(0); ! 242: hotkey_inside++; ! 243: if(mode&K_SPIN) ! 244: bputs("\b "); ! 245: SAVELINE; ! 246: attr(LIGHTGRAY); ! 247: lncntr=0; ! 248: bputs(text[ControlKeyMenu]); ! 249: ASYNC; ! 250: RESTORELINE; ! 251: lncntr=0; ! 252: hotkey_inside--; ! 253: return(0); ! 254: case ESC: ! 255: i=incom(mode&K_GETSTR ? 3000:1000); ! 256: if(i==NOINP) // timed-out waiting for '[' ! 257: return(ESC); ! 258: ch=i; ! 259: if(ch!='[') { ! 260: ungetkey(ch); ! 261: return(ESC); ! 262: } ! 263: i=j=0; ! 264: autoterm|=ANSI; /* <ESC>[x means they have ANSI */ ! 265: if(sys_status&SS_USERON && useron.misc&AUTOTERM && !(useron.misc&ANSI) ! 266: && useron.number) { ! 267: useron.misc|=ANSI; ! 268: putuserrec(&cfg,useron.number,U_MISC,8,ultoa(useron.misc,str,16)); ! 269: } ! 270: while(i<10 && j<30) { /* up to 3 seconds */ ! 271: ch=incom(100); ! 272: if(ch==(NOINP&0xff)) { ! 273: j++; ! 274: continue; ! 275: } ! 276: if(ch!=';' && !isdigit(ch) && ch!='R') { /* other ANSI */ ! 277: switch(ch) { ! 278: case 'A': ! 279: return(0x1e); /* ctrl-^ (up arrow) */ ! 280: case 'B': ! 281: return(LF); /* ctrl-j (dn arrow) */ ! 282: case 'C': ! 283: return(CTRL_F); /* ctrl-f (rt arrow) */ ! 284: case 'D': ! 285: return(0x1d); /* ctrl-] (lf arrow) */ ! 286: case 'H': /* ANSI: home cursor */ ! 287: return(CTRL_B); /* ctrl-b (beg line) */ ! 288: case 'F': /* Xterm: cursor preceding line */ ! 289: case 'K': /* ANSI: clear-to-end-of-line */ ! 290: return(CTRL_E); /* ctrl-e (end line) */ ! 291: } ! 292: ungetkey('['); ! 293: for(j=0;j<i;j++) ! 294: ungetkey(str[j]); ! 295: ungetkey(ch); ! 296: return(ESC); ! 297: } ! 298: if(ch=='R') { /* cursor position report */ ! 299: if(i && !(useron.rows)) { /* auto-detect rows */ ! 300: str[i]=0; ! 301: rows=atoi(str); ! 302: lprintf(LOG_DEBUG,"Node %d ANSI cursor position report: %u rows" ! 303: ,cfg.node_num, rows); ! 304: if(rows<10 || rows>99) rows=24; ! 305: } ! 306: return(0); ! 307: } ! 308: str[i++]=ch; ! 309: } ! 310: ! 311: ungetkey('['); ! 312: for(j=0;j<i;j++) ! 313: ungetkey(str[j]); ! 314: return(ESC); ! 315: } ! 316: return(ch); ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.