Enscript Output

extractedLnx/linux/arch/m68k/kernel/console.c_do_con_write.c

static int do_con_write(struct tty_struct * tty, int from_user,
			const unsigned char *buf, int count)
{
	int c, tc, ok, n = 0;
	unsigned int currcons;
	struct vt_struct *vt = (struct vt_struct *)tty->driver_data;

	currcons = vt->vc_num;
	if (!vc_cons_allocated(currcons)) {
		/* could this happen? */
		static int error = 0;
		if (!error) {
			error = 1;
			printk("con_write: tty %d not allocated\n", currcons+1);
		}
		return 0;
	}

	/* undraw cursor first */
	if (currcons == fg_console)
		hide_cursor(currcons);
	
	/* clear the selection */
	if (currcons == sel_cons)
		clear_selection();

        disable_bh(CONSOLE_BH);
	while (count) {
		enable_bh(CONSOLE_BH);
		if (from_user)
			get_user(c, buf);
		else
			c = *buf;
		buf++; n++; count--;
		disable_bh(CONSOLE_BH);

		if (utf) {
		    /* Combine UTF-8 into Unicode */
		    /* Incomplete characters silently ignored */
		    if(c > 0x7f) {   
			if (utf_count > 0 && (c & 0xc0) == 0x80) {
				utf_char = (utf_char << 6) | (c & 0x3f);
				utf_count--;
				if (utf_count == 0)
				    tc = c = utf_char;
				else continue;
			} else {
				if ((c & 0xe0) == 0xc0) {
				    utf_count = 1;
				    utf_char = (c & 0x1f);
				} else if ((c & 0xf0) == 0xe0) {
				    utf_count = 2;
				    utf_char = (c & 0x0f);
				} else if ((c & 0xf8) == 0xf0) {
				    utf_count = 3;
				    utf_char = (c & 0x07);
				} else if ((c & 0xfc) == 0xf8) {
				    utf_count = 4;
				    utf_char = (c & 0x03);
				} else if ((c & 0xfe) == 0xfc) {
				    utf_count = 5;
				    utf_char = (c & 0x01);
				} else
				    utf_count = 0;
				continue;
			}
		    } else {
			tc = c;
			utf_count = 0;
		    }
		} else {	/* no utf */
		    tc = translate[toggle_meta ? (c|0x80) : c];
		}

                /* If the original code was a control character we
                 * only allow a glyph to be displayed if the code is
                 * not normally used (such as for cursor movement) or
                 * if the disp_ctrl mode has been explicitly enabled.
                 * Certain characters (as given by the CTRL_ALWAYS
                 * bitmap) are always displayed as control characters,
                 * as the console would be pretty useless without
                 * them; to display an arbitrary font position use the
                 * direct-to-font zone in UTF-8 mode.
                 */
                ok = tc && (c >= 32 ||
                            (!utf && !(((disp_ctrl ? CTRL_ALWAYS
                                         : CTRL_ACTION) >> c) & 1)))
                        && (c != 127 || disp_ctrl)
			&& (c != 128+27);

		if (vc_state == ESnormal && ok) {
			/* Now try to find out how to display it */
			tc = conv_uni_to_pc(tc);
			if ( tc == -4 ) {
                                /* If we got -4 (not found) then see if we have
                                   defined a replacement character (U+FFFD) */
                                tc = conv_uni_to_pc(0xfffd);
                        } else if ( tc == -3 ) {
                                /* Bad hash table -- hope for the best */
                                tc = c;
                        }
			if (tc & ~console_charmask)
				continue; /* Conversion failed */

			if (need_wrap) {
				cr(currcons);
				lf(currcons);
			}

#if 1 /* XXX */
                        /* DPC: 1994-04-12
                         *   Speed up overstrike mode, using new putcs.
                         *
                         * P.S. I hate 8 spaces per tab! Use Emacs!
			 */
			
			/* Only use this for the foreground console,
			   where we really draw the chars */

			if (count > 2 &&
			    !decim && !utf && currcons == fg_console) { 
				static char putcs_buf[256];
				char   *p     = putcs_buf;
				int putcs_count  = 1;
				ushort nextx  = x + 1;

				*p++ = tc;
				*pos++ = tc | (attr << 8);

				if (nextx == cols) {
					sw->con_putc(vc_cons[currcons].d,
						     *putcs_buf, y, x);
					pos--;
					need_wrap = decawm;
					continue;
				}
				
				while (count)
				{
					enable_bh(CONSOLE_BH);
					if (from_user)
						get_user(c, buf);
					else
						c = *buf;
					disable_bh(CONSOLE_BH);
					tc = translate[toggle_meta ? (c|0x80) : c];
					if (!tc ||
					    !(c >= 32
					      || !(((disp_ctrl ? CTRL_ALWAYS
						   : CTRL_ACTION) >> c) & 1)))
					  break;
					tc = conv_uni_to_pc(tc);
					if (tc == -4)
					  tc = conv_uni_to_pc(0xfffd);
					else if (tc == -3)
					  tc = c;

					buf++; n++; count--;
					if (tc & ~console_charmask)
					  continue; /* Conversion failed */

					*p++ = tc;
					*pos++ = tc | (attr << 8);
					++putcs_count;
					++nextx;
					if (nextx == cols || 
					    putcs_count == sizeof (putcs_buf))
						break;
				}
				
				sw->con_putcs(vc_cons[currcons].d,
					      putcs_buf, putcs_count, y, x);
				if (nextx == cols) {
					pos--;
					x         = cols-1;
					need_wrap = decawm;
				} else
					x += putcs_count;
				continue;
                        }
			
                        /* DPC: End of putcs support */
#endif
			
			if (decim)
				insert_char(currcons);
			*pos = (attr << 8) + tc;
			if (currcons == fg_console)
				sw->con_putc(vc_cons[currcons].d,tc,y,x);
			if (x == cols - 1)
				need_wrap = decawm;
			else {
				pos++;
				x++;
			}
			continue;
		}

		/*
		 *  Control characters can be used in the _middle_
		 *  of an escape sequence.
		 */
		switch (c) {
		    case 0:
			continue;
		    case 7:
			if (bell_duration)
			    kd_mksound(bell_pitch, bell_duration);
			continue;
		    case 8:
			bs(currcons);
			continue;
		    case 9:
			pos -= x;
			while (x < cols - 1) {
				x++;
				if (tab_stop[x >> 5] & (1 << (x & 31)))
					break;
			}
			pos += x;
			continue;
		    case 10: case 11: case 12:
			lf(currcons);
			if (!is_kbd(lnm))
				continue;
		    case 13:
			cr(currcons);
			continue;
  			case 14:
			charset = 1;
			translate = set_translate(G1_charset);
			disp_ctrl = 1;
			continue;
		    case 15:
			charset = 0;
			translate = set_translate(G0_charset);
			disp_ctrl = 0;
			continue;
		    case 24: case 26:
			vc_state = ESnormal;
			continue;
		    case 27:
			vc_state = ESesc;
			continue;
		    case 127:
			del(currcons);
			continue;
		    case 128+27:
			vc_state = ESsquare;
			continue;
		}
		switch(vc_state) {
		    case ESesc:
			vc_state = ESnormal;
			switch (c) {
			    case '[':
				vc_state = ESsquare;
				continue;
			    case ']':
				vc_state = ESnonstd;
				continue;
			    case '%':
				vc_state = ESpercent;
				continue;
			    case 'E':
				cr(currcons);
				lf(currcons);
				continue;
			    case 'M':
				ri(currcons);
				continue;
			    case 'D':
				lf(currcons);
				continue;
			    case 'H':
				tab_stop[x >> 5] |= (1 << (x & 31));
				continue;
			    case 'Z':
				respond_ID(tty);
				continue;
			    case '7':
				save_cur(currcons);
				continue;
			    case '8':
				restore_cur(currcons);
				continue;
			    case '(':
				vc_state = ESsetG0;
				continue;
			    case ')':
				vc_state = ESsetG1;
				continue;
			    case '#':
				vc_state = EShash;
				continue;
			    case 'c':
				reset_terminal(currcons,1);
				continue;
			    case '>':  /* Numeric keypad */
				clr_kbd(kbdapplic);
				continue;
			    case '=':  /* Appl. keypad */
				set_kbd(kbdapplic);
				continue;
			}	
			continue;
		    case ESnonstd:
			if (c=='P') {   /* palette escape sequence */
			    for (npar=0; npar<NPAR; npar++)
				par[npar] = 0 ;
			    npar = 0 ;
			    vc_state = ESpalette;
			    continue;
			} else if (c=='R') {   /* reset palette */
			    reset_palette (currcons);
			    vc_state = ESnormal;
			} else
			    vc_state = ESnormal;
			continue;
		case ESpalette:
			if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
			    par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
			    if (npar==7) {
				int i = par[0]*3, j = 1;
				palette[i] = 16*par[j++];
				palette[i++] += par[j++];
				palette[i] = 16*par[j++];
				palette[i++] += par[j++];
				palette[i] = 16*par[j++];
				palette[i] += par[j];
				set_palette() ;
				vc_state = ESnormal;
			    }
			} else
			    vc_state = ESnormal;
			continue;
		    case ESsquare:
			for(npar = 0 ; npar < NPAR ; npar++)
				par[npar] = 0;
			npar = 0;
			vc_state = ESgetpars;
			if (c == '[') { /* Function key */
				vc_state=ESfunckey;
				continue;
			}
			ques = (c=='?');
			if (ques)
				continue;
		    case ESgetpars:
			if (c==';' && npar<NPAR-1) {
				npar++;
				continue;
			} else if (c>='0' && c<='9') {
				par[npar] *= 10;
				par[npar] += c-'0';
				continue;
			} else vc_state=ESgotpars;
		    case ESgotpars:
			vc_state = ESnormal;
			switch(c) {
			    case 'h':
				set_mode(currcons,1);
				continue;
			    case 'l':
				set_mode(currcons,0);
				continue;
			    case 'n':
				if (!ques)
					if (par[0] == 5)
						status_report(tty);
					else if (par[0] == 6)
						cursor_report(currcons,tty);
				continue;
			}
			if (ques) {
				ques = 0;
				continue;
			}
			switch(c) {
			    case 'G': case '`':
				if (par[0]) par[0]--;
				gotoxy(currcons,par[0],y);
				continue;
			    case 'A':
				if (!par[0]) par[0]++;
				gotoxy(currcons,x,y-par[0]);
				continue;
			    case 'B': case 'e':
				if (!par[0]) par[0]++;
				gotoxy(currcons,x,y+par[0]);
				continue;
			    case 'C': case 'a':
				if (!par[0]) par[0]++;
				gotoxy(currcons,x+par[0],y);
				continue;
			    case 'D':
				if (!par[0]) par[0]++;
				gotoxy(currcons,x-par[0],y);
				continue;
			    case 'E':
				if (!par[0]) par[0]++;
				gotoxy(currcons,0,y+par[0]);
				continue;
			    case 'F':
				if (!par[0]) par[0]++;
				gotoxy(currcons,0,y-par[0]);
				continue;
			    case 'd':
				if (par[0]) par[0]--;
				gotoxay(currcons,x,par[0]);
				continue;
			    case 'H': case 'f':
				if (par[0]) par[0]--;
				if (par[1]) par[1]--;
				gotoxay(currcons,par[1],par[0]);
				continue;
			    case 'J':
				csi_J(currcons,par[0]);
				continue;
			    case 'K':
				csi_K(currcons,par[0]);
				continue;
			    case 'L':
				csi_L(currcons,par[0]);
				continue;
			    case 'M':
				csi_M(currcons,par[0]);
				continue;
			    case 'P':
				csi_P(currcons,par[0]);
				continue;
			    case 'c':
				if (!par[0])
					respond_ID(tty);
				continue;
			    case 'g':
				if (!par[0])
					tab_stop[x >> 5] &= ~(1 << (x & 31));
				else if (par[0] == 3) {
					tab_stop[0] =
						tab_stop[1] =
							tab_stop[2] =
								tab_stop[3] =
									tab_stop[4] = 0;
				}
				continue;
			    case 'm':
				csi_m(currcons);
				continue;
			    case 'q': /* DECLL - but only 3 leds */
				/* map 0,1,2,3 to 0,1,2,4 */
				if (par[0] < 4)
					setledstate(kbd_table + currcons,
						    (par[0] < 3) ? par[0] : 4);
				continue;
			    case 'r':
				if (!par[0])
					par[0]++;
				if (!par[1])
					par[1] = rows;
				/* Minimum allowed region is 2 lines */
				if (par[0] < par[1] &&
				    par[1] <= rows) {
					top=par[0]-1;
					bottom=par[1];
					gotoxay(currcons,0,0);
				}
				continue;
			    case 's':
				save_cur(currcons);
				continue;
			    case 'u':
				restore_cur(currcons);
				continue;
			    case 'X':
				csi_X(currcons, par[0]);
				continue;
			    case '@':
				csi_at(currcons,par[0]);
				continue;
			    case ']': /* setterm functions */
				setterm_command(currcons);
				continue;
			}
			continue;
		    case ESpercent:
			vc_state = ESnormal;
			switch (c) {
			    case '@':  /* defined in ISO 2022 */
				utf = 0;
				continue;
			    case 'G':  /* prelim official escape code */
			    case '8':  /* retained for compatibility */
				utf = 1;
				continue;
			}
			continue;
		    case ESfunckey:
			vc_state = ESnormal;
			continue;
		    case EShash:
			vc_state = ESnormal;
			if (c == '8') {
				/* DEC screen alignment test. kludge :-) */
				video_erase_char =
					(video_erase_char & 0xff00) | 'E';
				/* Arno:
				 * Doesn't work, because csi_J(c,2)
				 * calls con_clear and doesn't print
				 * the erase char..
				 */
				csi_J(currcons, 2);
				video_erase_char =
					(video_erase_char & 0xff00) | ' ';
			}
			continue;
		    case ESsetG0:
			if (c == '0')
				G0_charset = GRAF_MAP;
			else if (c == 'B')
				G0_charset = LAT1_MAP;
			else if (c == 'U')
				G0_charset = IBMPC_MAP;
			else if (c == 'K')
				G0_charset = USER_MAP;
			if (charset == 0)
				translate = set_translate(G0_charset);
			vc_state = ESnormal;
			continue;
		    case ESsetG1:
			if (c == '0')
				G1_charset = GRAF_MAP;
			else if (c == 'B')
				G1_charset = LAT1_MAP;
			else if (c == 'U')
				G1_charset = IBMPC_MAP;
			else if (c == 'K')
				G1_charset = USER_MAP;
			if (charset == 1)
				translate = set_translate(G1_charset);
			vc_state = ESnormal;
			continue;
		    default:
			vc_state = ESnormal;
		}
	}
	enable_bh(CONSOLE_BH);
	return n;
}

Generated by GNU enscript 1.6.4.