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