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

📄 vt.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    vt = vt_con_data + idx;    if ((i = vt_allocate (vt)) < 0)	return i;    tty->driver_data = vt;    if (!tty->winsize.ws_row && !tty->winsize.ws_col) {	tty->winsize.ws_row = vtdata.numrows;	tty->winsize.ws_col = vtdata.numcolumns;    }    return 0;}static void vt_vtd_flush_chars (const struct vt *vt, struct vt_struct *vtd){    unsigned long flags;    save_flags (flags);    if (vtd->xmitting)	return;    vtd->xmitting = 1;    while (1) {	int c;	cli ();	c = MIN(vtd->xmit_cnt, CON_XMIT_SIZE - vtd->xmit_out);	if (c <= 0)	    break;	restore_flags (flags);	c = vcd_write (vt, 0, vtd->xmit_buf + vtd->xmit_out, c);	cli ();	if (c <= 0)	    break;	vtd->xmit_out = (vtd->xmit_out + c) & (CON_XMIT_SIZE - 1);	vtd->xmit_cnt -= c;    }    vtd->xmitting = 0;    restore_flags (flags);    if (*vt->tty)	wake_up_interruptible (&(*vt->tty)->write_wait);}static int vt_write (struct tty_struct *tty, int from_user,			const unsigned char *buf, int count){    static unsigned long last_error = 0;    const struct vt *vt = (struct vt *)tty->driver_data;    if (vt_allocated (vt)) {	if (vt->vtd->xmit_cnt)	    vt_vtd_flush_chars (vt, vt->vtd);	return vcd_write (vt, from_user, buf, count);    }    if (jiffies > last_error + 10*HZ) {	printk ("vt_write: tty %d not allocated\n", vt->num);	last_error = jiffies;    }    return 0;}static void vt_put_char (struct tty_struct *tty, unsigned char ch){    const struct vt *vt = (struct vt *)tty->driver_data;    unsigned long flags;    if (!vt_allocated (vt))	return;    save_flags_cli (flags);    if (vt->vtd->xmit_cnt < CON_XMIT_SIZE - 1) {	vt->vtd->xmit_buf[vt->vtd->xmit_in++] = ch;	vt->vtd->xmit_in &= CON_XMIT_SIZE - 1;	vt->vtd->xmit_cnt ++;    }    restore_flags (flags);}static void vt_flush_chars (struct tty_struct *tty){    const struct vt *vt = (struct vt *)tty->driver_data;    if (!vt_allocated (vt) || !vt->vtd->xmit_cnt || tty->stopped)	return;    vt_vtd_flush_chars (vt, vt->vtd);}static int vt_write_room (struct tty_struct *tty){    const struct vt *vt = (struct vt *)tty->driver_data;    int r;    if (!vt_allocated (vt))	return 0;    r = CON_XMIT_SIZE - vt->vtd->xmit_cnt - 8; /* allow 8 char overflow */    if (r < 0)	return 0;    else	return r;}static int vt_chars_in_buffer (struct tty_struct *tty){    const struct vt *vt = (struct vt *)tty->driver_data;    if (!vt_allocated (vt))	return CON_XMIT_SIZE;    return vt->vtd->xmit_cnt;}#if 0static void vt_flush_buffer (struct tty_struct *tty){    const struct vt *vt = (struct vt *)tty->driver_data;    if (!vt_allocated (vt))	return;    cli ();    vt->vtd->xmit_cnt = vt->vtd->xmit_out = vt->vtd->xmit_in = 0;    sti ();}#endifstatic int vt_ioctl (struct tty_struct *tty, struct file *filp,			unsigned int cmd, unsigned long arg){    struct vt *vt = tty->driver_data;    int perm, i;    if (!vt_allocated (vt))	/* impossible ? */	return -ENOIOCTLCMD;    /*     * To have permissions to do most of the vt ioctls, we either     * have to be the owner of the tty, or super-user.     */    perm = 0;    if (current->tty == tty || suser ())	perm = 1;#define PERM if (!perm) return -EPERM    switch (cmd) {    case KDGETMODE:	i = verify_area (VERIFY_WRITE, (void *)arg, sizeof (unsigned long));	if (!i)	    put_user (vt->vtd->vc_mode, (unsigned long *)arg);	return i;    case KDSETMODE:	PERM;	return vt_kdsetmode (vt, arg);    case VT_GETMODE:	i = verify_area (VERIFY_WRITE, (void *)arg, sizeof (struct vt_mode));	if (i)	    return i;	memcpy_tofs ((void *)arg, &vt->vtd->vt_mode, sizeof (struct vt_mode));	return 0;    case VT_SETMODE: {	struct vt_mode vtmode;	PERM;	i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct vt_mode));	if (i)	    return i;	memcpy_fromfs (&vtmode, (void *)arg, sizeof (struct vt_mode));	return vt_setmode (vt, &vtmode);	}    case VT_GETSTATE: {	/*	 * Returns global VT state.  Note that VT 0 is always open, since	 * it's an alias for the current VT, and people can't use it here.	 * We cannot return state for more than 16 VTs, since v_state is short.	 */	struct vt_stat *vtstat = (struct vt_stat *)arg;	unsigned short state = 1, mask = 2;	i = verify_area (VERIFY_WRITE, vtstat, sizeof (struct vt_stat));	if (i)	    return i;	for (i = 0; i < MAX_NR_CONSOLES && mask; ++i, mask <<= 1)	    if (VT_IS_IN_USE(i))		state |= mask;	put_user (vtdata.fgconsole->num, &vtstat->v_active);	put_user (state, &vtstat->v_state);	return 0;	}    case VT_OPENQRY:	/*	 * Returns the first available (non-open) console	 */	i = verify_area (VERIFY_WRITE, (void *)arg, sizeof (unsigned long));	if (i)	    return i;	for (i = 0; i < MAX_NR_CONSOLES; i++)	    if (!VT_IS_IN_USE(i))		break;	if (i < MAX_NR_CONSOLES)	    put_user (i + 1, (unsigned long *)arg);	else	    put_user (-1, (unsigned long *)arg);	return 0;    case VT_ACTIVATE:	PERM;	/*	 * VT activate will cause us to switch to vt #num with num >= 1	 * (switches to vt0, our console, are not allowed, just to preserve	 * sanity)	 */	if (arg == 0 || arg > MAX_NR_CONSOLES)	    return -ENXIO;	vt = vt_con_data + (arg - 1);	i = vt_allocate (vt);	if (i)	    return i;	vt_changeconsole (vt);	return 0;    case VT_WAITACTIVE:	PERM;	/*	 * wait until the specified VT has been activated	 */	if (arg == 0 || arg > MAX_NR_CONSOLES)	    return -ENXIO;	vt = vt_con_data + (arg - 1);	while (vt != vtdata.fgconsole) {	    if (vt_waitonactivate () < 0)		return -EINTR;        }	return 0;    case VT_RELDISP:	PERM;	return vt_reldisp (vt, arg);    case VT_RESIZE: {	struct vt_sizes *vtsizes = (struct vt_sizes *)arg;	ushort ll, cc;	PERM;	i = verify_area (VERIFY_READ, (void *)vtsizes, sizeof (struct vt_sizes));	if (i)	    return i;	ll = get_user (&vtsizes->v_rows);	cc = get_user (&vtsizes->v_cols);	return vt_resize (cc, ll);	}    case KIOCSOUND:	PERM;	vt_mksound (arg, 72, 5);	return 0;    case KDMKTONE: {	unsigned int freq  = get_user ((unsigned long *)arg);	unsigned int vol   = get_user ((unsigned long *)(arg + 4));	unsigned int ticks = get_user ((unsigned long *)(arg + 8));	PERM;	/*	 * Generate the tone for the apropriate number of ticks.	 * If time is zero, turn off sound ourselves.	 */	vt_mksound (freq, vol, ticks);	return 0;	}    case VT_DISALLOCATE:	if (arg > MAX_NR_CONSOLES)	    return -ENXIO;	return vt_deallocate (arg);    case VT_GETSCRINFO:	/*	 * Get screen dimentions	 */	i = verify_area (VERIFY_WRITE, (void *)arg, 5 * sizeof (unsigned long));	if (!i) {	    put_user (0, (unsigned long *)arg);	    put_user (vtdata.numcolumns * 8, (unsigned long *)(arg + 4));	    put_user (vtdata.numrows * 8, (unsigned long *)(arg + 8));	    put_user (vtdata.screen.bitsperpix, (unsigned long *)(arg + 12)); /* bpp */#ifndef HAS_VIDC20	    put_user (4, (unsigned long *)(arg + 16)); /* depth */#else	    put_user (8, (unsigned long *)(arg + 16)); /* depth */#endif	}	return i;    case VT_LOCKSWITCH:	if (!suser())	    return -EPERM;	vt_dont_switch = 1;	return 0;    case VT_UNLOCKSWITCH:	if (!suser())	    return -EPERM;	vt_dont_switch = 0;	return 0;    case KDMAPDISP:    case KDUNMAPDISP:    case KDSKBMODE:    case KDSKBMETA:    case KDSETKEYCODE:    case KDSKBENT:    case KDSKBSENT:    case KDSKBDIACR:    case KDSKBLED:    case KDSETLED:    case KDSIGACCEPT:	PERM;    case KDGKBTYPE:    case KDADDIO:    case KDDELIO:    case KDENABIO:    case KDDISABIO:    case KDGKBMODE:    case KDGKBMETA:    case KDGETKEYCODE:    case KDGKBENT:    case KDGKBSENT:    case KDGKBDIACR:    case KDGKBLED:    case KDGETLED:	return kbd_ioctl (vt, cmd, arg);    case VT_SETPALETTE:    case PIO_FONT:    case PIO_SCRNMAP:    case PIO_UNISCRNMAP:    case PIO_UNIMAPCLR:    case PIO_UNIMAP:	PERM;    case VT_GETPALETTE:    case GIO_FONT:    case GIO_SCRNMAP:    case GIO_UNISCRNMAP:    case GIO_UNIMAP:	return vcd_ioctl (vt, cmd, arg);    }    return -ENOIOCTLCMD;}/* * Turn the Scroll-Lock LED on when the tty is stopped */static void vt_stop (struct tty_struct *tty){    if (tty) {	const struct vt *vt = (struct vt *)tty->driver_data;	if (vt_allocated (vt)) {	    set_vc_kbd_led (vt->kbd, VC_SCROLLOCK);	    set_leds ();	}    }}/* * Turn the Scroll-Lock LED off when the tty is started */static void vt_start (struct tty_struct *tty){    if (tty) {	const struct vt *vt = (struct vt *)tty->driver_data;	if (vt_allocated (vt)) {	    clr_vc_kbd_led (vt->kbd, VC_SCROLLOCK);	    set_leds ();	}	if (vt->vtd->xmit_cnt)	    vt_vtd_flush_chars (vt, vt->vtd);    }}/* * vt_throttle and vt_unthrottle are only used for * paste_selection(), which has to stuff in a large number * of characters... */static void vt_throttle (struct tty_struct *tty){}static void vt_unthrottle (struct tty_struct *tty){    const struct vt *vt = (struct vt *)tty->driver_data;    if (vt_allocated (vt))	wake_up_interruptible (&vt->vtd->paste_wait);}/* * This is the console switching bottom half handler. * * Doing console switching in a bottom half handler allows * us to do ths switches asynchronously (needed when we want * to switch due to a keyboard interrupt), while still giving * us the option to easily disable it to avoid races when we * need to write to the console. */static void console_bh(void){	if (want_console) {		if (want_console != vtdata.fgconsole) {			vt_changeconsole(want_console);			/* we only changed when the console had already			   been allocated - a new console is not created			   in an interrupt routine */		}		want_console = NULL;	}	if (do_poke_blanked_console) { /* do not unblank for a LED change */		do_poke_blanked_console = 0;		vt_pokeblankedconsole();	}}/* * We don't have kmalloc setup yet.  We just want to get enough up so that printk * can work. * * Basically, we setup the VT structures for tty1. */unsigned long vt_pre_init (unsigned long kmem){    struct vt *vt = vt_con_data;    memset (vt_con_data, 0, sizeof (vt_con_data));    vtdata.numcolumns		= ORIG_VIDEO_COLS;    vtdata.numrows		= ORIG_VIDEO_LINES;    vtdata.blanked		= NULL;    vtdata.fgconsole		= vt_con_data;    vtdata.screen.blankinterval = 10*60*HZ;    vtdata.select.vt		= NULL;    vtdata.select.start		= -1;    vtdata.select.end		= 0;    vtdata.select.buffer	= NULL;    vt->vcd		= (struct con_struct *)kmem;	kmem += sizeof (struct con_struct);    vt->kbd		= (struct kbd_struct *)kmem;	kmem += sizeof (struct kbd_struct);    vt->vtd		= (struct vt_struct *)kmem;	kmem += sizeof (struct vt_struct);    vt->vtd->xmit_buf	= (unsigned char *)kmem;	kmem += CON_XMIT_SIZE;    vt->vtd->xmitting	= vt->vtd->xmit_cnt =    vt->vtd->xmit_out	= vt->vtd->xmit_in = 0;    vt->tty = &vt_table[0];    vt->num = 1;    /*     * vcd_init is called inside vcd_pre_init     */    kbd_struct_init (vt, 0);    vt_reset (vt);    vt->allocinit = 1;    kmem = vcd_pre_init (kmem, vt);    init_bh(CONSOLE_BH, console_bh);    return kmem;}/* * This is the post initialisation.  We have kmalloc setup so we can use it... */void vt_post_init (void){    int i;    memset (&vt_driver, 0, sizeof (struct tty_driver));    vt_driver.magic		= TTY_DRIVER_MAGIC;    vt_driver.name		= "tty";    vt_driver.name_base		= 1;    vt_driver.major		= TTY_MAJOR;    vt_driver.minor_start	= 1;    vt_driver.num		= MAX_NR_CONSOLES;    vt_driver.type		= TTY_DRIVER_TYPE_CONSOLE;    vt_driver.init_termios	= tty_std_termios;    vt_driver.flags		= TTY_DRIVER_REAL_RAW;    vt_driver.refcount		= &vt_refcount;    vt_driver.table		= vt_table;    vt_driver.termios		= vt_termios;    vt_driver.termios_locked	= vt_termios_locked;    vt_driver.open		= vt_open;    vt_driver.write		= vt_write;    vt_driver.put_char		= vt_put_char;    vt_driver.flush_chars	= vt_flush_chars;    vt_driver.write_room	= vt_write_room;    vt_driver.chars_in_buffer	= vt_chars_in_buffer;#if 0    vt_driver.flush_buffer	= vt_flush_buffer;#endif    vt_driver.ioctl		= vt_ioctl;    vt_driver.stop		= vt_stop;    vt_driver.start		= vt_start;    vt_driver.throttle		= vt_throttle;    vt_driver.unthrottle	= vt_unthrottle;    for (i = 1; i < MAX_NR_CONSOLES; i++) {	struct vt *vt = vt_con_data + i;	vt->tty = &vt_table[i];	vt->num = i + 1;	vt->allocinit = 0;	if (i < MIN_NR_CONSOLES)	    vt_allocate (vt);    }    if (tty_register_driver (&vt_driver))	panic ("Couldn't register console driver");    timer_table[BLANK_TIMER].fn	= vt_blankscreen;    if (vtdata.screen.blankinterval) {	timer_table[BLANK_TIMER].expires = jiffies + vtdata.screen.blankinterval;	timer_active |= 1 << BLANK_TIMER;    } else	timer_table[BLANK_TIMER].expires = 0;}

⌨️ 快捷键说明

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