⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tubttybld.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
字号:
/* *  IBM/3270 Driver -- Copyright (C) 2000 UTS Global LLC * *  tubttybld.c -- Linemode tty driver screen-building functions * * * * * *  Author:  Richard Hitt */#include "tubio.h"extern int tty3270_io(tub_t *);static void tty3270_set_status_area(tub_t *, char **);static int tty3270_next_char(tub_t *);static void tty3270_unnext_char(tub_t *, char);static void tty3270_update_log_area(tub_t *, char **);static int tty3270_update_log_area_esc(tub_t *, char **, int *);static void tty3270_clear_log_area(tub_t *, char **);static void tty3270_tub_bufadr(tub_t *, int, char **);static void tty3270_set_bufadr(tub_t *, char **, int *);/* * tty3270_clear_log_area(tub_t *tubp, char **cpp) */static voidtty3270_clear_log_area(tub_t *tubp, char **cpp){	*(*cpp)++ = TO_SBA;	TUB_BUFADR(GEOM_LOG, cpp);	*(*cpp)++ = TO_SF;	*(*cpp)++ = TF_LOG;	*(*cpp)++ = TO_RA;	TUB_BUFADR(GEOM_INPUT, cpp);	*(*cpp)++ = '\0';	tubp->tty_oucol = tubp->tty_nextlogx = 0;	*(*cpp)++ = TO_SBA;	TUB_BUFADR(tubp->tty_nextlogx, cpp);}static voidtty3270_update_log_area(tub_t *tubp, char **cpp){	int lastx = GEOM_INPUT;	int c;	int next, fill, i;	int sba_needed = 1;	char *overrun = &(*tubp->ttyscreen)[tubp->ttyscreenl - TS_LENGTH];	/* Check for possible ESC sequence work to do */	if (tubp->tty_escx != 0) {		/* If compiling new escape sequence */		if (tubp->tty_esca[0] == 0x1b) {			if (tty3270_update_log_area_esc(tubp, cpp, &sba_needed))				return;		/* If esc seq needs refreshing after a write */		} else if (tubp->tty_esca[0] == TO_SA) {			tty3270_set_bufadr(tubp, cpp, &sba_needed);			for (i = 0; i < tubp->tty_escx; i++)				*(*cpp)++ = tubp->tty_esca[i];		} else {			printk(KERN_WARNING "tty3270_update_log_area esca "			"character surprising:  %.2x\n", tubp->tty_esca[0]);		}	}	/* Place characters */	while (tubp->tty_bcb.bc_cnt != 0) {		/* Check for room.  TAB could take up to 4 chars. */		if (&(*cpp)[4] >= overrun)			break;		/* Fetch a character */		if ((c = tty3270_next_char(tubp)) == -1)			break;		switch(c) {		default:			if (tubp->tty_nextlogx >= lastx) {				if (sba_needed == 0 ||				    tubp->stat == TBS_RUNNING) {					tty3270_unnext_char(tubp, c);					tubp->stat = TBS_MORE;					tty3270_set_status_area(tubp, cpp);					tty3270_scl_settimer(tubp);				}				goto do_return;			}			tty3270_set_bufadr(tubp, cpp, &sba_needed);			/* Use blank if we don't know the character */			*(*cpp)++ = tub_ascebc[(int)(c < ' '? ' ': c)];			tubp->tty_nextlogx++;			tubp->tty_oucol++;			break;		case 0x1b:              /* ESC */			tubp->tty_escx = 0;			if (tty3270_update_log_area_esc(tubp, cpp, &sba_needed))				return;			break;		case '\r':		/* 0x0d -- Carriage Return */			tubp->tty_nextlogx -=				tubp->tty_nextlogx % GEOM_COLS;			sba_needed = 1;			break;		case '\n':		/* 0x0a -- New Line */			if (tubp->tty_oucol == GEOM_COLS) {				tubp->tty_oucol = 0;				break;			}			next = (tubp->tty_nextlogx + GEOM_COLS) /				GEOM_COLS * GEOM_COLS;			tubp->tty_nextlogx = next;			tubp->tty_oucol = 0;			sba_needed = 1;			break;		case '\t':		/* 0x09 -- Tabulate */			tty3270_set_bufadr(tubp, cpp, &sba_needed);			fill = (tubp->tty_nextlogx % GEOM_COLS) % 8;			for (; fill < 8; fill++) {				if (tubp->tty_nextlogx >= lastx)					break;				*(*cpp)++ = tub_ascebc[' '];				tubp->tty_nextlogx++;				tubp->tty_oucol++;			}			break;		case '\a':		/* 0x07 -- Alarm */			tubp->flags |= TUB_ALARM;			break;		case '\f':		/* 0x0c -- Form Feed */			tty3270_clear_log_area(tubp, cpp);			break;		case 0xf:	/* SuSE "exit alternate mode" */			break;		}	}do_return:}#define NUMQUANT 8static inttty3270_update_log_area_esc(tub_t *tubp, char **cpp, int *sba_needed){	int c;	int i, j;	int start, end, next;	int quant[NUMQUANT];	char *overrun = &(*tubp->ttyscreen)[tubp->ttyscreenl - TS_LENGTH];	char sabuf[NUMQUANT*3], *sap = sabuf, *cp;	/* If starting a sequence, stuff ESC at [0] */	if (tubp->tty_escx == 0)		tubp->tty_esca[tubp->tty_escx++] = 0x1b;	/* Now that sequence is started, see if room in buffer */	if (&(*cpp)[NUMQUANT * 3] >= overrun)		return tubp->tty_escx;	/* Gather the rest of the sequence's characters */	while (tubp->tty_escx < sizeof tubp->tty_esca) {		if ((c = tty3270_next_char(tubp)) == -1)			return tubp->tty_escx;		if (tubp->tty_escx == 1) {			switch(c) {			case '[':				tubp->tty_esca[tubp->tty_escx++] = c;				continue;			case '7':				tubp->tty_savecursor = tubp->tty_nextlogx;				goto done_return;			case '8':				next = tubp->tty_savecursor;				goto do_setcur;			default:				goto error_return;			}		}		tubp->tty_esca[tubp->tty_escx++] = c;		if (c != ';' && (c < '0' || c > '9'))			break;	}	/* Check for overrun */	if (tubp->tty_escx == sizeof tubp->tty_esca)		goto error_return;	/* Parse potentially empty string "nn;nn;nn..." */	i = -1;	j = 2;		/* skip ESC, [ */	c = ';';	do {		if (c == ';') {			if (++i == NUMQUANT)				goto error_return;			quant[i] = 0;		} else if (c < '0' || c > '9') {			break;		} else {			quant[i] = quant[i] * 10 + c - '0';		}		c = tubp->tty_esca[j];	} while (j++ < tubp->tty_escx);	/* Add 3270 data stream output to execute the sequence */	switch(c) {	case 'm':		/* Set Attribute */		for (next = 0; next <= i; next++) {			int type = -1, value = 0;			switch(quant[next]) {			case 0:		/* Reset */				next = tubp->tty_nextlogx;				tty3270_set_bufadr(tubp, cpp, sba_needed);				*(*cpp)++ = TO_SA;				*(*cpp)++ = TAT_EXTHI;				*(*cpp)++ = TAX_RESET;				*(*cpp)++ = TO_SA;				*(*cpp)++ = TAT_COLOR;				*(*cpp)++ = TAC_RESET;				tubp->tty_nextlogx = next;				*sba_needed = 1;				sap = sabuf;				break;			case 1:		/* Bright */				break;			case 2:		/* Dim */				break;			case 4:		/* Underscore */				type = TAT_EXTHI; value = TAX_UNDER;				break;			case 5:		/* Blink */				type = TAT_EXTHI; value = TAX_BLINK;				break;			case 7:		/* Reverse */				type = TAT_EXTHI; value = TAX_REVER;				break;			case 8:		/* Hidden */				break;		/* For now ... */			/* Foreground Colors */			case 30:	/* Black */				type = TAT_COLOR; value = TAC_DEFAULT;				break;			case 31:	/* Red */				type = TAT_COLOR; value = TAC_RED;				break;			case 32:	/* Green */				type = TAT_COLOR; value = TAC_GREEN;				break;			case 33:	/* Yellow */				type = TAT_COLOR; value = TAC_YELLOW;				break;			case 34:	/* Blue */				type = TAT_COLOR; value = TAC_BLUE;				break;			case 35:	/* Magenta */				type = TAT_COLOR; value = TAC_PINK;				break;			case 36:	/* Cyan */				type = TAT_COLOR; value = TAC_TURQ;				break;			case 37:	/* White */				type = TAT_COLOR; value = TAC_WHITE;				break;			case 39:	/* Black */				type = TAT_COLOR; value = TAC_DEFAULT;				break;			/* Background Colors */			case 40:	/* Black */			case 41:	/* Red */			case 42:	/* Green */			case 43:	/* Yellow */			case 44:	/* Blue */			case 45:	/* Magenta */			case 46:	/* Cyan */			case 47:	/* White */				break;		/* For now ... */			/* Oops */			default:				break;			}			if (type != -1) {				tty3270_set_bufadr(tubp, cpp, sba_needed);				*(*cpp)++ = TO_SA;				*(*cpp)++ = type;				*(*cpp)++ = value;				*sap++ = TO_SA;				*sap++ = type;				*sap++ = value;			}		}		break;	case 'H':		/* Cursor Home */	case 'f':		/* Force Cursor Position */		if (quant[0]) quant[0]--;		if (quant[1]) quant[1]--;		next = quant[0] * GEOM_COLS + quant[1];		goto do_setcur;	case 'A':		/* Cursor Up */		if (quant[i] == 0) quant[i] = 1;		next = tubp->tty_nextlogx - GEOM_COLS * quant[i];		goto do_setcur;	case 'B':		/* Cursor Down */		if (quant[i] == 0) quant[i] = 1;		next = tubp->tty_nextlogx + GEOM_COLS * quant[i];		goto do_setcur;	case 'C':		/* Cursor Forward */		if (quant[i] == 0) quant[i] = 1;		next = tubp->tty_nextlogx % GEOM_COLS;		start = tubp->tty_nextlogx - next;		next = start + MIN(next + quant[i], GEOM_COLS - 1);		goto do_setcur;	case 'D':		/* Cursor Backward */		if (quant[i] == 0) quant[i] = 1;		next = MIN(quant[i], tubp->tty_nextlogx % GEOM_COLS);		next = tubp->tty_nextlogx - next;		goto do_setcur;	case 'G':		if (quant[0]) quant[0]--;		next = tubp->tty_nextlogx / GEOM_COLS * GEOM_COLS + quant[0];do_setcur:		if (next < 0)			break;		tubp->tty_nextlogx = next;		tubp->tty_oucol = tubp->tty_nextlogx % GEOM_COLS;		*sba_needed = 1;		break;	case 'r':		/* Define scroll area */		start = quant[0];		if (start <= 0) start = 1;		if (start > GEOM_ROWS - 2) start = GEOM_ROWS - 2;		tubp->tty_nextlogx = (start - 1) * GEOM_COLS;		tubp->tty_oucol = 0;		*sba_needed = 1;		break;	case 'X':		/* Erase for n chars from cursor */		start = tubp->tty_nextlogx;		end = start + (quant[0]?: 1);		goto do_fill;	case 'J':		/* Erase to screen end from cursor */		*(*cpp)++ = TO_SBA;		TUB_BUFADR(tubp->tty_nextlogx, cpp);		*(*cpp)++ = TO_RA;		TUB_BUFADR(GEOM_INPUT, cpp);		*(*cpp)++ = tub_ascebc[' '];		*(*cpp)++ = TO_SBA;		TUB_BUFADR(tubp->tty_nextlogx, cpp);		break;	case 'K':		start = tubp->tty_nextlogx;		end = (start + GEOM_COLS) / GEOM_COLS * GEOM_COLS;do_fill:		if (start >= GEOM_INPUT)			break;		if (end > GEOM_INPUT)			end = GEOM_INPUT;		if (end <= start)			break;		*(*cpp)++ = TO_SBA;		TUB_BUFADR(start, cpp);		if (end - start > 4) {			*(*cpp)++ = TO_RA;			TUB_BUFADR(end, cpp);			*(*cpp)++ = tub_ascebc[' '];		} else while (start++ < end) {			*(*cpp)++ = tub_ascebc[' '];		}		tubp->tty_nextlogx = end;		tubp->tty_oucol = tubp->tty_nextlogx % GEOM_COLS;		*sba_needed = 1;		break;	}done_return:	tubp->tty_escx = 0;	cp = sabuf;	while (cp != sap)		tubp->tty_esca[tubp->tty_escx++] = *cp++;	return 0;error_return:	tubp->tty_escx = 0;	return 0;}static inttty3270_next_char(tub_t *tubp){	int c;	bcb_t *ib;	ib = &tubp->tty_bcb;	if (ib->bc_cnt == 0)		return -1;	c = ib->bc_buf[ib->bc_rd++];	if (ib->bc_rd == ib->bc_len)		ib->bc_rd = 0;	ib->bc_cnt--;	return c;}static voidtty3270_unnext_char(tub_t *tubp, char c){	bcb_t *ib;	ib = &tubp->tty_bcb;	if (ib->bc_rd == 0)		ib->bc_rd = ib->bc_len;	ib->bc_buf[--ib->bc_rd] = c;	ib->bc_cnt++;}static voidtty3270_clear_input_area(tub_t *tubp, char **cpp){	*(*cpp)++ = TO_SBA;	TUB_BUFADR(GEOM_INPUT, cpp);	*(*cpp)++ = TO_SF;	*(*cpp)++ = tubp->tty_inattr;	*(*cpp)++ = TO_IC;	*(*cpp)++ = TO_RA;	TUB_BUFADR(GEOM_STAT, cpp);	*(*cpp)++ = '\0';}static voidtty3270_update_input_area(tub_t *tubp, char **cpp){	int len;	*(*cpp)++ = TO_SBA;	TUB_BUFADR(GEOM_INPUT, cpp);	*(*cpp)++ = TO_SF;	*(*cpp)++ = TF_INMDT;	len = strlen(tubp->tty_input);	memcpy(*cpp, tubp->tty_input, len);	*cpp += len;	*(*cpp)++ = TO_IC;	len = GEOM_INPLEN - len;	if (len > 4) {		*(*cpp)++ = TO_RA;		TUB_BUFADR(GEOM_STAT, cpp);		*(*cpp)++ = '\0';	} else {		for (; len > 0; len--)			*(*cpp)++ = '\0';	}}/* * tty3270_set_status_area(tub_t *tubp, char **cpp) */static voidtty3270_set_status_area(tub_t *tubp, char **cpp){	char *sp;	if (tubp->stat == TBS_RUNNING)		sp = TS_RUNNING;	else if (tubp->stat == TBS_MORE)		sp = TS_MORE;	else if (tubp->stat == TBS_HOLD)		sp = TS_HOLD;	else		sp = "Linux Whatstat";	*(*cpp)++ = TO_SBA;	TUB_BUFADR(GEOM_STAT, cpp);	*(*cpp)++ = TO_SF;	*(*cpp)++ = TF_STAT;	memcpy(*cpp, sp, sizeof TS_RUNNING);	TUB_ASCEBC(*cpp, sizeof TS_RUNNING);	*cpp += sizeof TS_RUNNING;}/* * tty3270_build() -- build an output stream */inttty3270_build(tub_t *tubp){	char *cp, *startcp;	int chancmd;	int writecc = TW_KR;	int force = 0;	if (tubp->mode == TBM_FS)		return 0;	cp = startcp = *tubp->ttyscreen + 1;	switch(tubp->cmd) {	default:		printk(KERN_WARNING "tty3270_build unknown command %d\n", tubp->cmd);		return 0;	case TBC_OPEN:tbc_open:		tubp->flags &= ~TUB_INPUT_HACK;		chancmd = TC_EWRITEA;		tty3270_clear_input_area(tubp, &cp);		tty3270_set_status_area(tubp, &cp);		tty3270_clear_log_area(tubp, &cp);		break;	case TBC_UPDLOG:		if (tubp->flags & TUB_INPUT_HACK)			goto tbc_open;		chancmd = TC_WRITE;		writecc = TW_NONE;		tty3270_update_log_area(tubp, &cp);		break;	case TBC_KRUPDLOG:		chancmd = TC_WRITE;		force = 1;		tty3270_update_log_area(tubp, &cp);		break;	case TBC_CLRUPDLOG:		chancmd = TC_WRITE;		tty3270_set_status_area(tubp, &cp);		tty3270_clear_log_area(tubp, &cp);		tty3270_update_log_area(tubp, &cp);		break;	case TBC_UPDATE:		chancmd = TC_EWRITEA;		tubp->tty_oucol = tubp->tty_nextlogx = 0;		tty3270_clear_input_area(tubp, &cp);		tty3270_set_status_area(tubp, &cp);		tty3270_update_log_area(tubp, &cp);		break;	case TBC_UPDSTAT:		chancmd = TC_WRITE;		tty3270_set_status_area(tubp, &cp);		break;	case TBC_CLRINPUT:		chancmd = TC_WRITE;		tty3270_clear_input_area(tubp, &cp);		break;	case TBC_UPDINPUT:		chancmd = TC_WRITE;		tty3270_update_input_area(tubp, &cp);		break;	}	/* Set Write Control Character and start I/O */	if (force == 0 && cp == startcp &&	    (tubp->flags & TUB_ALARM) == 0)		return 0;	if (tubp->flags & TUB_ALARM) {		tubp->flags &= ~TUB_ALARM;		writecc |= TW_PLUSALARM;	}	**tubp->ttyscreen = writecc;	tubp->ttyccw.cmd_code = chancmd;	tubp->ttyccw.flags = CCW_FLAG_SLI;	tubp->ttyccw.cda = virt_to_phys(*tubp->ttyscreen);	tubp->ttyccw.count = cp - *tubp->ttyscreen;	tty3270_io(tubp);	return 1;}static voidtty3270_tub_bufadr(tub_t *tubp, int adr, char **cpp){	if (tubp->tty_14bitadr) {		*(*cpp)++ = (adr >> 8) & 0x3f;		*(*cpp)++ = adr & 0xff;	} else {		*(*cpp)++ = tub_ebcgraf[(adr >> 6) & 0x3f];		*(*cpp)++ = tub_ebcgraf[adr & 0x3f];	}}static voidtty3270_set_bufadr(tub_t *tubp, char **cpp, int *sba_needed){	if (!*sba_needed)		return;	if (tubp->tty_nextlogx >= GEOM_INPUT) {		tubp->tty_nextlogx = GEOM_INPUT - 1;		tubp->tty_oucol = tubp->tty_nextlogx % GEOM_COLS;	}	*(*cpp)++ = TO_SBA;	TUB_BUFADR(tubp->tty_nextlogx, cpp);	*sba_needed = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -