Skip to content
Snippets Groups Projects
term.c 69.5 KiB
Newer Older
	char *in;
	size_t out;

	if(!cachedirlen) {
		strcpy(cachedir,"file:");
		get_syncterm_filename(cachedir+5, sizeof(cachedir)-5, SYNCTERM_PATH_CACHE, FALSE);
		cachedirlen=strlen(cachedir);
		html_cleanup();
	}

	if(!memcmp(uri, cachedir, cachedirlen)) {
		/* Reading from the cache... no redirect */
		return(URL_ACTION_ISGOOD);
	}

	strncpy(buf, cachedir, bufsize);
	buf[bufsize-1]=0;
	backslash(buf);
	/* Append mangledname */
	in=(char *)uri;
	out=strlen(buf);
	while(*in && out < bufsize-1) {
		char ch;
		ch=*(in++);
		if(ch < ' ')
			ch='^';
		if(ch > 126)
			ch='~';
		switch(ch) {
			case '*':
			case '?':
			case ':':
			case '[':
			case ']':
			case '"':
			case '<':
			case '>':
			case '|':
			case '(':
			case ')':
			case '{':
			case '}':
			case '/':
			case '\\':
				buf[out++]='_';
				break;
			default:
				buf[out++]=ch;
		}
	}
	buf[out]=0;

	/* We now have the cache filename... does it already exist? */
	if(fexist(buf+5))
		return(URL_ACTION_REDIRECT);

	/* If not, we need to fetch it... convert relative URIs */
	if(strstr(uri,"://")) {
		/* Good URI */
		strncpy(uribuf, uri, uribufsize);
		uribuf[uribufsize-1]=0;
		return(URL_ACTION_DOWNLOAD);
	}

	strcpy(uribuf, "http://");
	if(html_addr)
		strcat(uribuf, html_addr);
	if(uri[0]!='/')
		strcat(uribuf, "/");
	strcat(uribuf,uri);

	return(URL_ACTION_DOWNLOAD);
deuce's avatar
deuce committed
}
deuce's avatar
deuce committed

#define OUTBUF_SIZE	2048

#ifdef WITH_WXWIDGETS
#define WRITE_OUTBUF()	\
	if(outbuf_size > 0) { \
		cterm_write(outbuf, outbuf_size, prn, sizeof(prn), &speed); \
		outbuf_size=0; \
		if(html_mode==HTML_MODE_RAISED) { \
			if(html_startx != wherex() || html_starty != wherey()) { \
				iconize_html(); \
				html_mode=HTML_MODE_ICONIZED; \
			} \
		} \
		if(prn[0]) \
			conn_send(prn, strlen(prn), 0); \
		updated=TRUE; \
	}
#else
#define WRITE_OUTBUF()	\
	if(outbuf_size > 0) { \
		cterm_write(outbuf, outbuf_size, prn, sizeof(prn), &speed); \
		outbuf_size=0; \
		if(prn[0]) \
			conn_send(prn, strlen(prn), 0); \
		updated=TRUE; \
	}
#endif

BOOL doterm(struct bbslist *bbs)
	unsigned char outbuf[OUTBUF_SIZE];
	size_t outbuf_size=0;
	unsigned char prn[ANSI_REPLY_BUFSIZE];
	BYTE zrqinit[] = { ZDLE, ZHEX, '0', '0', 0 };	/* for Zmodem auto-downloads */
	BYTE zrinit[] = { ZDLE, ZHEX, '0', '1', 0 };	/* for Zmodem auto-uploads */
deuce's avatar
deuce committed
	BYTE zrqbuf[sizeof(zrqinit)];
#ifdef GUTS_BUILTIN
	BYTE gutsinit[] = { ESC, '[', '{' };	/* For GUTS auto-transfers */
deuce's avatar
deuce committed
	BYTE gutsbuf[sizeof(gutsinit)];
deuce's avatar
deuce committed
	BYTE htmldetect[]="\2\2?HTML?";
	BYTE htmlresponse[]="\2\2!HTML!";
	BYTE htmlstart[]="\2\2<HTML>";
	BYTE htmldet[sizeof(htmldetect)];
deuce's avatar
deuce committed
	long double nextchar=0;
	long double lastchar=0;
	long double thischar=0;
deuce's avatar
deuce committed
	int	oldmc;
	int	updated=FALSE;
deuce's avatar
deuce committed
	BOOL	sleep;
	int 	emulation=CTERM_EMULATION_ANSI_BBS;
	struct text_info txtinfo;
#ifndef WITHOUT_OOII
	BYTE ooii_buf[256];
deuce's avatar
deuce committed
	BYTE ooii_init1[] = "\xdb\b \xdb\b \xdb\b[\xdb\b[\xdb\b \xdb\bM\xdb\ba\xdb\bi\xdb\bn\xdb\bt\xdb\be\xdb\bn\xdb\ba\xdb\bn\xdb\bc\xdb\be\xdb\b \xdb\bC\xdb\bo\xdb\bm\xdb\bp\xdb\bl\xdb\be\xdb\bt\xdb\be\xdb\b \xdb\b]\xdb\b]\xdb\b \b\r\n\r\n\r\n\x1b[0;0;36mDo you have the Overkill Ansiterm installed? (y/N)  \xe9 ";	/* for OOII auto-enable */
	BYTE ooii_init2[] = "\xdb\b \xdb\b \xdb\b[\xdb\b[\xdb\b \xdb\bM\xdb\ba\xdb\bi\xdb\bn\xdb\bt\xdb\be\xdb\bn\xdb\ba\xdb\bn\xdb\bc\xdb\be\xdb\b \xdb\bC\xdb\bo\xdb\bm\xdb\bp\xdb\bl\xdb\be\xdb\bt\xdb\be\xdb\b \xdb\b]\xdb\b]\xdb\b \b\r\n\r\n\x1b[0m\x1b[2J\r\n\r\n\x1b[0;1;30mHX Force retinal scan in progress ... \x1b[0;0;30m";	/* for OOII auto-enable */
deuce's avatar
deuce committed
	int ooii_mode=0;
	recv_byte_buffer_len=recv_byte_buffer_pos=0;
	gettextinfo(&txtinfo);
	if(bbs->conn_type == CONN_TYPE_SERIAL)
deuce's avatar
deuce committed
		speed = 0;
	else
		speed = bbs->bpsrate;
	log_level = bbs->xfer_loglevel;
	conn_api.log_level = bbs->telnet_loglevel;
	setup_mouse_events();
	p=(unsigned char *)realloc(scrollback_buf, term.width*2*settings.backlines);
	if(p != NULL) {
		scrollback_buf=p;
deuce's avatar
deuce committed
		memset(scrollback_buf,0,term.width*2*settings.backlines);
	}
	else
		FREE_AND_NULL(scrollback_buf);
	scrollback_lines=0;
	scrollback_mode=txtinfo.currmode;
	switch(bbs->screen_mode) {
		case SCREEN_MODE_C64:
		case SCREEN_MODE_C128_40:
		case SCREEN_MODE_C128_80:
			emulation = CTERM_EMULATION_PETASCII;
			break;
		case SCREEN_MODE_ATARI:
		case SCREEN_MODE_ATARI_XEP80:
			emulation = CTERM_EMULATION_ATASCII;
			break;
	cterm_init(term.height,term.width,term.x-1,term.y-1,settings.backlines,scrollback_buf, emulation);
	scrollback_cols=term.width;
	cterm.music_enable=bbs->music;
	zrqbuf[0]=0;
#ifndef WITHOUT_OOII
	ooii_buf[0]=0;
#endif
#ifdef GUTS_BUILTIN
	gutsbuf[0]=0;
#endif
deuce's avatar
deuce committed
	htmldet[0]=0;
deuce's avatar
deuce committed
	oldmc=hold_update;
	showmouse();
deuce's avatar
deuce committed
		hold_update=TRUE;
		if(!term.nostatus)
			update_status(bbs, (bbs->conn_type == CONN_TYPE_SERIAL)?bbs->bpsrate:speed, ooii_mode);
		for(remain=count_data_waiting() /* Hack for connection check */ + (!is_connected(NULL)); remain; remain--) {
deuce's avatar
deuce committed
			if(speed)
				thischar=xp_timer();

			if((!speed) || thischar < lastchar /* Wrapped */ || thischar >= nextchar) {
				/* Get remote input */
				inch=recv_byte(NULL, 0);

				switch(inch) {
					case -1:
						if(!is_connected(NULL)) {
							hold_update=oldmc;
							if(html_mode != HTML_MODE_HIDDEN) {
								hide_html();
								html_cleanup();
							uifcmsg("Disconnected","`Disconnected`\n\nRemote host dropped connection");
							cterm_clearscreen(cterm.attr);	/* Clear screen into scrollback */
							scrollback_lines=cterm.backpos;
							cterm_end();
							conn_close();
							hidemouse();
							return(FALSE);
						}
						break;
					default:
						if(speed) {
							lastchar = xp_timer();
							nextchar = lastchar + 1/(long double)(speed/10);
						}

#ifdef GUTS_BUILTIN
deuce's avatar
deuce committed
						j=strlen(gutsbuf);
						if(inch == gutsinit[j]) {
							gutsbuf[j]=inch;
							gutsbuf[++j]=0;
							if(j==sizeof(gutsinit)) { /* Have full sequence */
deuce's avatar
deuce committed
								guts_transfer(bbs);
								remain=1;
deuce's avatar
deuce committed
						else
							gutsbuf[0]=0;
deuce's avatar
deuce committed
						if(html_mode==HTML_MODE_READING) {
deuce's avatar
deuce committed
							if(inch==2) {
								html_startx=wherex();
								html_starty=wherey();
								html_commit();
deuce's avatar
deuce committed
								html_mode=HTML_MODE_RAISED;
deuce's avatar
deuce committed
							}
							else {
deuce's avatar
deuce committed
								add_html_char(inch);
deuce's avatar
deuce committed
						j=strlen(htmldet);
						if(inch == htmldetect[j] || toupper(inch)==htmlstart[j]) {
							htmldet[j]=inch;
							htmldet[++j]=0;
							if(j==sizeof(htmldetect)-1) {
deuce's avatar
deuce committed
								if(!strcmp(htmldet, htmldetect)) {
									if(html_supported==HTML_SUPPORT_UNKNOWN) {
										int width,height,xpos,ypos;
										html_addr=bbs->addr;

										get_window_info(&width, &height, &xpos, &ypos);
										if(!run_html(width, height, xpos, ypos, html_send, html_urlredirect))
											html_supported=HTML_SUPPORTED;
										else
											html_supported=HTML_NOTSUPPORTED;
deuce's avatar
deuce committed
									}
deuce's avatar
deuce committed
									if(html_supported==HTML_SUPPORTED) {
										conn_send(htmlresponse, sizeof(htmlresponse)-1, 0);
										hide_html();
deuce's avatar
deuce committed
								else {
									show_html("");
									html_mode=HTML_MODE_READING;
								}
								htmldet[0]=0;
deuce's avatar
deuce committed
						else
							htmldet[0]=0;
deuce's avatar
deuce committed
						j=strlen(zrqbuf);
						if(inch == zrqinit[j] || inch == zrinit[j]) {
							zrqbuf[j]=inch;
							zrqbuf[++j]=0;
							if(j==sizeof(zrqinit)-1) {	/* Have full sequence (Assumes zrinit and zrqinit are same length */
deuce's avatar
deuce committed
								if(!strcmp(zrqbuf, zrqinit))
									zmodem_download(bbs);
								else
									begin_upload(bbs, TRUE, inch);
								zrqbuf[0]=0;
								remain=1;
deuce's avatar
deuce committed
						else
							zrqbuf[0]=0;
#ifndef WITHOUT_OOII
						if(ooii_mode) {
							if(ooii_buf[0]==0) {
								if(inch == 0xab) {
									ooii_buf[0]=inch;
									ooii_buf[1]=0;
									continue;
								}
							}
							else { /* Already have the start of the sequence */
								j=strlen(ooii_buf);
								if(j+1 >= sizeof(ooii_buf))
									j--;
								ooii_buf[j++]=inch;
								ooii_buf[j]=0;
								if(inch == '|') {
									if(handle_ooii_code(ooii_buf, &ooii_mode, prn, sizeof(prn))) {
deuce's avatar
deuce committed
										ooii_mode=0;
deuce's avatar
deuce committed
									if(prn[0])
										conn_send(prn,strlen(prn),0);
deuce's avatar
deuce committed
							if(inch==ooii_init1[j]) {
								ooii_buf[j++]=inch;
								ooii_buf[j]=0;
								if(ooii_init1[j]==0) {
									if(strcmp(ooii_buf, ooii_init1)==0) {
deuce's avatar
deuce committed
										ooii_mode=1;
deuce's avatar
deuce committed
									ooii_buf[0]=0;
								}
							}
							else if(inch==ooii_init2[j]) {
								ooii_buf[j++]=inch;
								ooii_buf[j]=0;
deuce's avatar
deuce committed
								if(ooii_init2[j]==0) {
									if(strcmp(ooii_buf, ooii_init2)==0) {
deuce's avatar
deuce committed
										ooii_mode=2;
deuce's avatar
deuce committed
									ooii_buf[0]=0;
								}
deuce's avatar
deuce committed
							else
								ooii_buf[0]=0;
						if(outbuf_size >= sizeof(outbuf))
							WRITE_OUTBUF();
						outbuf[outbuf_size++]=inch;
		if(updated) {
deuce's avatar
deuce committed
			hold_update=FALSE;
deuce's avatar
deuce committed
			gotoxy(wherex(), wherey());
deuce's avatar
deuce committed
		}
deuce's avatar
deuce committed
		hold_update=oldmc;
		while(kbhit()) {
deuce's avatar
deuce committed
			struct mouse_event mevent;
deuce's avatar
deuce committed
			updated=TRUE;
			gotoxy(wherex(), wherey());
deuce's avatar
deuce committed
			if(key==0 || key==0xff) {
				if(cterm.doorway_mode && ((key & 0xff) == 0) && key != 0x2c00 /* ALT-Z */) {
deuce's avatar
deuce committed
					ch[0]=0;
					ch[1]=key>>8;
					conn_send(ch,2,0);
					key=0;
deuce's avatar
deuce committed
					continue;
				}
			}
deuce's avatar
deuce committed

			/* These keys are SyncTERM control keys */
			/* key is set to zero if consumed */
				case CIO_KEY_MOUSE:
					getmouse(&mevent);
					switch(mevent.event) {
						case CIOLIB_BUTTON_1_DRAG_START:
deuce's avatar
deuce committed
							mousedrag(scrollback_buf);
deuce's avatar
deuce committed
							key = 0;
						case CIOLIB_BUTTON_2_CLICK:
						case CIOLIB_BUTTON_3_CLICK:
							p=getcliptext();
							if(p!=NULL) {
								for(p2=p; *p2; p2++) {
									if(*p2=='\n') {
										/* If previous char was not \r, send a \r */
										if(p2==p || *(p2-1)!='\r')
											conn_send("\r",1,0);
									}
									else
										conn_send(p2,1,0);
								}
deuce's avatar
deuce committed
							key = 0;
deuce's avatar
deuce committed
					key = 0;
				case 0x3000:	/* ALT-B - Scrollback */
					viewscroll();
					showmouse();
deuce's avatar
deuce committed
					key = 0;
					break;
				case 0x2e00:	/* ALT-C - Capture */
					capture_control(bbs);
					showmouse();
deuce's avatar
deuce committed
					key = 0;
					break;
				case 0x2000:	/* ALT-D - Download */
deuce's avatar
deuce committed
					begin_download(bbs);
					showmouse();
deuce's avatar
deuce committed
					key = 0;
				case 0x1200:	/* ALT-E */
					{
						p=(char *)malloc(txtinfo.screenheight*txtinfo.screenwidth*2);
						if(p) {
							gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
							show_bbslist(bbs->name, TRUE);
							uifcbail();
							setup_mouse_events();
							puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
							free(p);
							showmouse();
							_setcursortype(_NORMALCURSOR);
				case 0x2100:	/* ALT-F */
					font_control(bbs);
					showmouse();
deuce's avatar
deuce committed
					key = 0;
					if(bbs->conn_type != CONN_TYPE_RLOGIN && bbs->conn_type != CONN_TYPE_RLOGIN_REVERSED && bbs->conn_type != CONN_TYPE_SSH) {
						if(bbs->user[0]) {
							conn_send(bbs->user,strlen(bbs->user),0);
							conn_send(cterm.emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0);
							SLEEP(10);
						}
						if(bbs->password[0]) {
							conn_send(bbs->password,strlen(bbs->password),0);
							conn_send(cterm.emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0);
							SLEEP(10);
						}
						conn_send(bbs->syspass,strlen(bbs->syspass),0);
						conn_send(cterm.emulation==CTERM_EMULATION_ATASCII?"\x9b":"\r",1,0);
deuce's avatar
deuce committed
					key = 0;
deuce's avatar
deuce committed
				case 0x3200:	/* ALT-M */
					music_control(bbs);
					showmouse();
deuce's avatar
deuce committed
					key = 0;
deuce's avatar
deuce committed
					break;
				case 0x1600:	/* ALT-U - Upload */
					begin_upload(bbs, FALSE, inch);
					showmouse();
deuce's avatar
deuce committed
					key = 0;
deuce's avatar
deuce committed
				case 17:		/* CTRL-Q */
					if(cio_api.mode!=CIOLIB_MODE_CURSES
							&& cio_api.mode!=CIOLIB_MODE_CURSES_IBM
							&& cio_api.mode!=CIOLIB_MODE_ANSI) {
						break;
					}
					/* FALLTHROUGH for curses/ansi modes */
				case 0x2d00:	/* Alt-X - Exit */
				case 0x2300:	/* Alt-H - Hangup */
deuce's avatar
deuce committed
					{
						char *opts[3]={
										 "Yes"
										,"No"
										,""
									  };
						char *buf;

deuce's avatar
deuce committed
   						gettextinfo(&txtinfo);
						buf=(char *)alloca(txtinfo.screenheight*txtinfo.screenwidth*2);
deuce's avatar
deuce committed
						gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
						i=0;
						uifc.helpbuf="Selecting Yes closes the connection\n";
deuce's avatar
deuce committed
						if(uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,NULL,"Disconnect... Are you sure?",opts)==0) {
							if(html_mode != HTML_MODE_HIDDEN) {
								hide_html();
								html_cleanup();
deuce's avatar
deuce committed
							uifcbail();
							setup_mouse_events();
							cterm_clearscreen(cterm.attr);	/* Clear screen into scrollback */
							scrollback_lines=cterm.backpos;
deuce's avatar
deuce committed
							cterm_end();
							conn_close();
							hidemouse();
deuce's avatar
deuce committed
							hold_update=oldmc;
							return(key==0x2d00 /* Alt-X? */);
deuce's avatar
deuce committed
						}
						uifcbail();
						setup_mouse_events();
deuce's avatar
deuce committed
						puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,buf);
						window(txtinfo.winleft,txtinfo.wintop,txtinfo.winright,txtinfo.winbottom);
						textattr(txtinfo.attribute);
						gotoxy(txtinfo.curx,txtinfo.cury);
						showmouse();
deuce's avatar
deuce committed
					}
deuce's avatar
deuce committed
					key = 0;
deuce's avatar
deuce committed
					break;
					if(cio_api.mode!=CIOLIB_MODE_CURSES
							&& cio_api.mode!=CIOLIB_MODE_CURSES_IBM
							&& cio_api.mode!=CIOLIB_MODE_ANSI) {
						break;
					}
					/* FALLTHROUGH for curses/ansi modes */
				case 0x2c00:		/* ALT-Z */
					switch(syncmenu(bbs, &speed)) {
							if(html_mode != HTML_MODE_HIDDEN) {
								hide_html();
								html_cleanup();
							cterm_clearscreen(cterm.attr);	/* Clear screen into scrollback */
							scrollback_lines=cterm.backpos;
							conn_close();
							hidemouse();
deuce's avatar
deuce committed
							hold_update=oldmc;
							return(FALSE);
						case 3:
							begin_upload(bbs, FALSE, inch);
							capture_control(bbs);
							break;
						case 8:
deuce's avatar
deuce committed
							music_control(bbs);
							break;
						case 9:
deuce's avatar
deuce committed
							cterm.doorway_mode=!cterm.doorway_mode;
							break;
deuce's avatar
deuce committed
						case 11:
deuce's avatar
deuce committed
							ooii_mode++;
							if(ooii_mode > MAX_OOII_MODE) {
								xptone_close();
deuce's avatar
deuce committed
								ooii_mode=0;
							if(html_mode != HTML_MODE_HIDDEN) {
								hide_html();
								html_cleanup();
							cterm_clearscreen(cterm.attr);	/* Clear screen into scrollback */
							scrollback_lines=cterm.backpos;
							cterm_end();
							conn_close();
							hidemouse();
deuce's avatar
deuce committed
							hold_update=oldmc;
							{
								p=(char *)malloc(txtinfo.screenheight*txtinfo.screenwidth*2);
								if(p) {
									gettext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
									show_bbslist(bbs->name, TRUE);
									puttext(1,1,txtinfo.screenwidth,txtinfo.screenheight,p);
									free(p);
								}
							}
							break;
					setup_mouse_events();
					showmouse();
deuce's avatar
deuce committed
					key = 0;
				case 0x9800:	/* ALT-Up */
					if(bbs->conn_type != CONN_TYPE_SERIAL) {
						if(speed)
							speed=rates[get_rate_num(speed)+1];
						else
							speed=rates[0];
						key = 0;
					}
					break;
				case 0xa000:	/* ALT-Down */
					if(bbs->conn_type != CONN_TYPE_SERIAL) {
						i=get_rate_num(speed);
						if(i==0)
							speed=0;
						else
							speed=rates[i-1];
						key = 0;
					}
deuce's avatar
deuce committed
			}
			if(key && cterm.emulation == CTERM_EMULATION_ATASCII) {
				/* Translate keys to ATASCII */
				switch(key) {
					case '\r':
					case '\n':
						ch[0]=155;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_DOWN:
						ch[0]=29;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_DC:		/* "Delete" key */
					case '\b':				/* Backspace */
						ch[0]=126;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_RIGHT:
						ch[0]=31;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_UP:
						ch[0]=28;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_LEFT:
						ch[0]=30;
						conn_send(ch,1,0);
						break;
					case '\t':
						ch[0]=127;
						conn_send(ch,1,0);
						break;
deuce's avatar
deuce committed
					case 96:	/* No backtick */
						break;
					default:
						if(key<256) {
							/* ASCII Translation */
							if(key<32) {
								break;
							}
							else if(key<123) {
deuce's avatar
deuce committed
								ch[0]=key;
								conn_send(ch,1,0);
							}
						}
						break;
				}
			}
			else if(key && cterm.emulation == CTERM_EMULATION_PETASCII) {
deuce's avatar
deuce committed
				/* Translate keys to PETSCII */
				switch(key) {
					case '\r':
					case '\n':
						ch[0]=13;
						conn_send(ch,1,0);
						break;
deuce's avatar
deuce committed
					case CIO_KEY_DOWN:
						ch[0]=17;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_HOME:
						ch[0]=19;
						conn_send(ch,1,0);
						break;
deuce's avatar
deuce committed
					case '\b':
deuce's avatar
deuce committed
					case CIO_KEY_DC:		/* "Delete" key */
						ch[0]=20;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_RIGHT:
						ch[0]=29;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(1):
						ch[0]=133;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(3):
						ch[0]=134;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(5):
						ch[0]=135;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(7):
						ch[0]=136;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(2):
						ch[0]=137;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(4):
						ch[0]=138;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(6):
						ch[0]=139;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_F(8):
						ch[0]=140;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_UP:
						ch[0]=145;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_IC:
						ch[0]=148;
						conn_send(ch,1,0);
						break;
					case CIO_KEY_LEFT:
						ch[0]=157;
						conn_send(ch,1,0);
						break;
					default:
						if(key<256) {
							/* ASCII Translation */
							if(key<32) {
								break;
							}
							else if(key<65) {
								ch[0]=key;
								conn_send(ch,1,0);
							}
							else if(key<91) {
								ch[0]=tolower(key);
								conn_send(ch,1,0);
							}
							else if(key<96) {
								ch[0]=key;
								conn_send(ch,1,0);
							}
							else if(key==96) {
								break;
							}
							else if(key<123) {
								ch[0]=toupper(key);
								conn_send(ch,1,0);
							}
						}
						break;
				}
			}
			else if(key) {
				switch(key) {
					case CIO_KEY_LEFT:
						conn_send("\033[D",3,0);
						break;
					case CIO_KEY_RIGHT:
						conn_send("\033[C",3,0);
						break;
					case CIO_KEY_UP:
						conn_send("\033[A",3,0);
						break;
					case CIO_KEY_DOWN:
						conn_send("\033[B",3,0);
						break;
					case CIO_KEY_HOME:
						conn_send("\033[H",3,0);
						break;
					case CIO_KEY_END:
#ifdef CIO_KEY_SELECT
					case CIO_KEY_SELECT:	/* Some terminfo/termcap entries use KEY_SELECT as the END key! */
#endif
						conn_send("\033[K",3,0);
						break;
					case CIO_KEY_DC:		/* "Delete" key, send ASCII 127 (DEL) */
						conn_send("\x7f",1,0);
						break;
					case CIO_KEY_NPAGE:		/* Page down */
						conn_send("\033[U",3,0);
						break;
					case CIO_KEY_PPAGE:	/* Page up */
						conn_send("\033[V",3,0);
						break;
					case CIO_KEY_F(1):
						conn_send("\033OP",3,0);
						break;
					case CIO_KEY_F(2):
						conn_send("\033OQ",3,0);
						break;
					case CIO_KEY_F(3):
						conn_send("\033OR",3,0);
						break;
					case CIO_KEY_F(4):
						conn_send("\033OS",3,0);
						break;
					case CIO_KEY_F(5):
						conn_send("\033Ot",3,0);
						break;
					case CIO_KEY_F(6):
						conn_send("\033[17~",5,0);
						break;
					case CIO_KEY_F(7):
						conn_send("\033[18~",5,0);
						break;
					case CIO_KEY_F(8):
						conn_send("\033[19~",5,0);
						break;
					case CIO_KEY_F(9):
						conn_send("\033[20~",5,0);
						break;
					case CIO_KEY_F(10):
						conn_send("\033[21~",5,0);
						break;
					case CIO_KEY_F(11):
						conn_send("\033[23~",5,0);
						break;
					case CIO_KEY_F(12):
						conn_send("\033[24~",5,0);
						break;
					case CIO_KEY_IC:
						conn_send("\033[@",3,0);
						break;
					case 17:		/* CTRL-Q */
						conn_send(ch,1,0);
deuce's avatar
deuce committed
						break;
					case 19:	/* CTRL-S */
						ch[0]=key;
						conn_send(ch,1,0);
						break;
					case '\b':
						key='\b';
						/* FALLTHROUGH to default */
					default:
						if(key<256) {
							ch[0]=key;
							conn_send(ch,1,0);
						}
				}
deuce's avatar
deuce committed
		if(sleep)
deuce's avatar
deuce committed
			SLEEP(1);
		else
			MAYBE_YIELD();
deuce's avatar
deuce committed
/*
	hidemouse();
deuce's avatar
deuce committed
	hold_update=oldmc;
	return(FALSE);
deuce's avatar
deuce committed
 */