Enscript Output

extractedLnx/linux/drivers/char/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;

#if CONFIG_AP1000
        ap_write(1,buf,count);
        return(count);
#endif

	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();

	if (from_user) {
		/* just to make sure that noone lurks at places he shouldn't see. */
		if (verify_area(VERIFY_READ, buf, count))
			return 0; /* ?? are error codes legal here ?? */
	}

	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);

				/* One reason for the -4 can be that we just
				   did a clear_unimap();
				   try at least to show something. */
				if (tc == -4)
				     tc = c;
                        } 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);
			}

                        /* 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) {
				char   *p     = putcs_buf;
				int putcs_count  = 1;
				ushort nextx  = x + 1;

				*p++ = tc;
				scr_writew((attr << 8) + tc,
					   (unsigned short *)pos);
				pos+=2;

				if (nextx == video_num_columns) {
					sw->con_putc(vc_cons[currcons].d,
						     *putcs_buf, y, x);
					pos-=2;
					need_wrap = decawm;
					continue;
				}

				/* TAB TAB TAB - Arghh!!!! */

				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;
					scr_writew((attr << 8) + tc,
						   (unsigned short *)pos);
					pos+=2;
					++putcs_count;
					++nextx;
					if (nextx == video_num_columns ||
					    putcs_count == sizeof (putcs_buf))
						break;
				}

				sw->con_putcs(vc_cons[currcons].d,
					      putcs_buf, putcs_count, y, x);
				if (nextx == video_num_columns) {
					pos-=2;
					x         = video_num_columns-1;
					need_wrap = decawm;
				} else
					x += putcs_count;
				continue;
                        }

                        /* DPC: End of putcs support */

			if (decim)
				insert_char(currcons, 1);
			scr_writew( video_mode_512ch ?
			   ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
			   (tc & 0x0ff) : (attr << 8) + tc,
			   (unsigned short *) pos);
			if (currcons == fg_console)
				sw->con_putc(vc_cons[currcons].d, tc, y, x);

			if (x == video_num_columns - 1)
				need_wrap = decawm;
			else {
				x++;
				pos+=2;
			}
			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 << 1);
				while (x < video_num_columns - 1) {
					x++;
					if (tab_stop[x >> 5] & (1 << (x & 31)))
						break;
				}
				pos += (x << 1);
				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 'c':
						if (par[0])
							cursor_type = par[0] | (par[1]<<8) | (par[2]<<16);
						else
							cursor_type = CUR_DEFAULT;
						set_cursor(currcons);
						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] = video_num_lines;
						/* Minimum allowed region is 2 lines */
						if (par[0] < par[1] &&
						    par[1] <= video_num_lines) {
							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.