Exemplo n.º 1
0
int
sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
    mouse_info_t *mouse;
    mouse_info_t buf;
    scr_stat *cur_scp;
    scr_stat *scp;
    struct proc *p1;
    int s;
    int f;

    scp = SC_STAT(tp);

    switch (cmd) {

    case CONS_MOUSECTL:		/* control mouse arrow */
    case OLD_CONS_MOUSECTL:

	mouse = (mouse_info_t*)data;

	random_harvest_queue(mouse, sizeof(mouse_info_t), 2, RANDOM_MOUSE);

	if (cmd == OLD_CONS_MOUSECTL) {
	    static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
	    old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;

	    mouse = &buf;
	    mouse->operation = old_mouse->operation;
	    switch (mouse->operation) {
	    case MOUSE_MODE:
		mouse->u.mode = old_mouse->u.mode;
		break;
	    case MOUSE_SHOW:
	    case MOUSE_HIDE:
		break;
	    case MOUSE_MOVEABS:
	    case MOUSE_MOVEREL:
	    case MOUSE_ACTION:
		mouse->u.data.x = old_mouse->u.data.x;
		mouse->u.data.y = old_mouse->u.data.y;
		mouse->u.data.z = 0;
		mouse->u.data.buttons = swapb[old_mouse->u.data.buttons & 0x7];
		break;
	    case MOUSE_GETINFO:
		old_mouse->u.data.x = scp->mouse_xpos;
		old_mouse->u.data.y = scp->mouse_ypos;
		old_mouse->u.data.buttons = swapb[scp->mouse_buttons & 0x7];
		return 0;
	    default:
		return EINVAL;
	    }
	}

	cur_scp = scp->sc->cur_scp;

	switch (mouse->operation) {
	case MOUSE_MODE:
	    if (ISSIGVALID(mouse->u.mode.signal)) {
		scp->mouse_signal = mouse->u.mode.signal;
		scp->mouse_proc = td->td_proc;
		scp->mouse_pid = td->td_proc->p_pid;
	    }
	    else {
		scp->mouse_signal = 0;
		scp->mouse_proc = NULL;
		scp->mouse_pid = 0;
	    }
	    return 0;

	case MOUSE_SHOW:
	    s = spltty();
	    if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
		scp->sc->flags |= SC_MOUSE_ENABLED;
		cur_scp->status &= ~MOUSE_HIDDEN;
		if (!ISGRAPHSC(cur_scp))
		    mark_all(cur_scp);
	    }
	    splx(s);
	    return 0;
	    /* NOTREACHED */

	case MOUSE_HIDE:
	    s = spltty();
	    if (scp->sc->flags & SC_MOUSE_ENABLED) {
		scp->sc->flags &= ~SC_MOUSE_ENABLED;
		sc_remove_all_mouse(scp->sc);
	    }
	    splx(s);
	    return 0;
	    /* NOTREACHED */

	case MOUSE_MOVEABS:
	    s = spltty();
	    scp->mouse_xpos = mouse->u.data.x;
	    scp->mouse_ypos = mouse->u.data.y;
	    set_mouse_pos(scp);
	    splx(s);
	    break;

	case MOUSE_MOVEREL:
	    s = spltty();
	    scp->mouse_xpos += mouse->u.data.x;
	    scp->mouse_ypos += mouse->u.data.y;
	    set_mouse_pos(scp);
	    splx(s);
	    break;

	case MOUSE_GETINFO:
	    mouse->u.data.x = scp->mouse_xpos;
	    mouse->u.data.y = scp->mouse_ypos;
	    mouse->u.data.z = 0;
	    mouse->u.data.buttons = scp->mouse_buttons;
	    return 0;

	case MOUSE_ACTION:
	case MOUSE_MOTION_EVENT:
	    /* send out mouse event on /dev/sysmouse */
#if 0
	    /* this should maybe only be settable from /dev/consolectl SOS */
	    if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
		return ENOTTY;
#endif
	    s = spltty();
	    if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
		cur_scp->mouse_xpos += mouse->u.data.x;
		cur_scp->mouse_ypos += mouse->u.data.y;
		set_mouse_pos(cur_scp);
	    }
	    f = 0;
	    if (mouse->operation == MOUSE_ACTION) {
		f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;
		cur_scp->mouse_buttons = mouse->u.data.buttons;
	    }
	    splx(s);

	    if (sysmouse_event(mouse) == 0)
		return 0;

	    /* 
	     * If any buttons are down or the mouse has moved a lot, 
	     * stop the screen saver.
	     */
	    if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
		|| (mouse->u.data.x*mouse->u.data.x
			+ mouse->u.data.y*mouse->u.data.y
			>= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
		sc_touch_scrn_saver();
	    }

	    cur_scp->status &= ~MOUSE_HIDDEN;

	    if (cur_scp->mouse_level > 0) {
	    	sc_mouse_input(scp, mouse);
		break;
	    }

	    if (cur_scp->mouse_signal && cur_scp->mouse_proc) {
    		/* has controlling process died? */
		if (cur_scp->mouse_proc != (p1 = pfind(cur_scp->mouse_pid))) {
		    	cur_scp->mouse_signal = 0;
			cur_scp->mouse_proc = NULL;
			cur_scp->mouse_pid = 0;
			if (p1)
			    PROC_UNLOCK(p1);
		} else {
		    kern_psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
		    PROC_UNLOCK(cur_scp->mouse_proc);
		    break;
		}
	    }

#ifndef SC_NO_CUTPASTE
	    if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
		break;

	    if ((mouse->operation == MOUSE_ACTION) && f) {
		/* process button presses */
		if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
		    mouse_cut_start(cur_scp);
		else
		    mouse_cut_end(cur_scp);
		if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
		    cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
		    sc_mouse_paste(cur_scp);
	    }
#endif /* SC_NO_CUTPASTE */
	    break;

	case MOUSE_BUTTON_EVENT:
	    if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
		return EINVAL;
	    if (mouse->u.event.value < 0)
		return EINVAL;
#if 0
	    /* this should maybe only be settable from /dev/consolectl SOS */
	    if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
		return ENOTTY;
#endif
	    if (mouse->u.event.value > 0)
		cur_scp->mouse_buttons |= mouse->u.event.id;
	    else
		cur_scp->mouse_buttons &= ~mouse->u.event.id;

	    if (sysmouse_event(mouse) == 0)
		return 0;

	    /* if a button is held down, stop the screen saver */
	    if (mouse->u.event.value > 0)
		sc_touch_scrn_saver();

	    cur_scp->status &= ~MOUSE_HIDDEN;

	    if (cur_scp->mouse_level > 0) {
	    	sc_mouse_input(scp, mouse);
		break;
	    }

	    if (cur_scp->mouse_signal && cur_scp->mouse_proc) {
		if (cur_scp->mouse_proc != (p1 = pfind(cur_scp->mouse_pid))){
		    	cur_scp->mouse_signal = 0;
			cur_scp->mouse_proc = NULL;
			cur_scp->mouse_pid = 0;
			if (p1)
			    PROC_UNLOCK(p1);
		} else {
		    kern_psignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
		    PROC_UNLOCK(cur_scp->mouse_proc);
		    break;
		}
	    }

#ifndef SC_NO_CUTPASTE
	    if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
		break;

	    switch (mouse->u.event.id) {
	    case MOUSE_BUTTON1DOWN:
	        switch (mouse->u.event.value % 4) {
		case 0:	/* up */
		    mouse_cut_end(cur_scp);
		    break;
		case 1: /* single click: start cut operation */
		    mouse_cut_start(cur_scp);
		    break;
		case 2:	/* double click: cut a word */
		    mouse_cut_word(cur_scp);
		    mouse_cut_end(cur_scp);
		    break;
		case 3:	/* triple click: cut a line */
		    mouse_cut_line(cur_scp);
		    mouse_cut_end(cur_scp);
		    break;
		}
		break;
	    case SC_MOUSE_PASTEBUTTON:
	        switch (mouse->u.event.value) {
		case 0:	/* up */
		    break;
		default:
		    sc_mouse_paste(cur_scp);
		    break;
		}
		break;
	    case SC_MOUSE_EXTENDBUTTON:
	        switch (mouse->u.event.value) {
		case 0:	/* up */
		    if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
		        mouse_cut_end(cur_scp);
		    break;
		default:
		    mouse_cut_extend(cur_scp);
		    break;
		}
		break;
	    }
#endif /* SC_NO_CUTPASTE */
	    break;

	case MOUSE_MOUSECHAR:
	    if (mouse->u.mouse_char < 0) {
		mouse->u.mouse_char = scp->sc->mouse_char;
	    } else {
		if (mouse->u.mouse_char > UCHAR_MAX - 3)
		    return EINVAL;
		s = spltty();
		sc_remove_all_mouse(scp->sc);
#ifndef SC_NO_FONT_LOADING
		if (ISTEXTSC(cur_scp) && (cur_scp->font != NULL))
		    sc_load_font(cur_scp, 0, cur_scp->font_size,
				 cur_scp->font_width,
				 cur_scp->font + cur_scp->font_size
				 * cur_scp->sc->mouse_char,
				 cur_scp->sc->mouse_char, 4);
#endif
		scp->sc->mouse_char = mouse->u.mouse_char;
		splx(s);
	    }
	    break;

	default:
	    return EINVAL;
	}

	return 0;
    }

    return ENOIOCTL;
}
Exemplo n.º 2
0
int
sc_mouse_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag)
{
    mouse_info_t *mouse;
    scr_stat *cur_scp;
    scr_stat *scp;
    struct proc *oproc;
    int f;

    scp = SC_STAT(tp->t_dev);

    switch (cmd) {

    case CONS_MOUSECTL:		/* control mouse arrow */
	mouse = (mouse_info_t*)data;
	cur_scp = scp->sc->cur_scp;

	switch (mouse->operation) {
	case MOUSE_MODE:
	    if (ISSIGVALID(mouse->u.mode.signal)) {
		oproc = scp->mouse_proc;
		scp->mouse_signal = mouse->u.mode.signal;
		scp->mouse_proc = curproc;
		scp->mouse_pid = curproc->p_pid;
		PHOLD(curproc);
	    } else {
		oproc = scp->mouse_proc;
		scp->mouse_signal = 0;
		scp->mouse_proc = NULL;
		scp->mouse_pid = 0;
	    }
	    if (oproc) {
		    PRELE(oproc);
		    oproc = NULL;
	    }
	    return 0;

	case MOUSE_SHOW:
	    crit_enter();
	    if (!(scp->sc->flags & SC_MOUSE_ENABLED)) {
		scp->sc->flags |= SC_MOUSE_ENABLED;
		cur_scp->status &= ~MOUSE_HIDDEN;
		if (!ISGRAPHSC(cur_scp))
		    mark_all(cur_scp);
		crit_exit();
		return 0;
	    } else {
		crit_exit();
		return EINVAL;
	    }
	    break;

	case MOUSE_HIDE:
	    crit_enter();
	    if (scp->sc->flags & SC_MOUSE_ENABLED) {
		scp->sc->flags &= ~SC_MOUSE_ENABLED;
		sc_remove_all_mouse(scp->sc);
		crit_exit();
		return 0;
	    } else {
		crit_exit();
		return EINVAL;
	    }
	    break;

	case MOUSE_MOVEABS:
	    crit_enter();
	    scp->mouse_xpos = mouse->u.data.x;
	    scp->mouse_ypos = mouse->u.data.y;
	    set_mouse_pos(scp);
	    crit_exit();
	    break;

	case MOUSE_MOVEREL:
	    crit_enter();
	    scp->mouse_xpos += mouse->u.data.x;
	    scp->mouse_ypos += mouse->u.data.y;
	    set_mouse_pos(scp);
	    crit_exit();
	    break;

	case MOUSE_GETINFO:
	    mouse->u.data.x = scp->mouse_xpos;
	    mouse->u.data.y = scp->mouse_ypos;
	    mouse->u.data.z = 0;
	    mouse->u.data.buttons = scp->mouse_buttons;
	    return 0;

	case MOUSE_ACTION:
	case MOUSE_MOTION_EVENT:
	    /* send out mouse event on /dev/sysmouse */
#if 0
	    /* this should maybe only be settable from /dev/consolectl SOS */
	    if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
		return ENOTTY;
#endif
	    crit_enter();
	    if (mouse->u.data.x != 0 || mouse->u.data.y != 0) {
		cur_scp->mouse_xpos += mouse->u.data.x;
		cur_scp->mouse_ypos += mouse->u.data.y;
		set_mouse_pos(cur_scp);
	    }
	    f = 0;
	    if (mouse->operation == MOUSE_ACTION) {
		f = cur_scp->mouse_buttons ^ mouse->u.data.buttons;
		cur_scp->mouse_buttons = mouse->u.data.buttons;
	    }
	    crit_exit();

	    if (sysmouse_event(mouse) == 0)
		return 0;

	    /* 
	     * If any buttons are down or the mouse has moved a lot, 
	     * stop the screen saver.
	     */
	    if (((mouse->operation == MOUSE_ACTION) && mouse->u.data.buttons)
		|| (mouse->u.data.x*mouse->u.data.x
			+ mouse->u.data.y*mouse->u.data.y
			>= SC_WAKEUP_DELTA*SC_WAKEUP_DELTA)) {
		sc_touch_scrn_saver();
	    }

	    cur_scp->status &= ~MOUSE_HIDDEN;

	    if (cur_scp->mouse_signal) {
    		/* has controlling process died? */
		if (cur_scp->mouse_proc && 
		    (cur_scp->mouse_proc != pfindn(cur_scp->mouse_pid))){
			oproc = cur_scp->mouse_proc;
		    	cur_scp->mouse_signal = 0;
			cur_scp->mouse_proc = NULL;
			cur_scp->mouse_pid = 0;
			if (oproc)
				PRELE(oproc);
		} else {
		    ksignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
		    break;
		}
	    }

	    if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
		break;

#ifndef SC_NO_CUTPASTE
	    if ((mouse->operation == MOUSE_ACTION) && f) {
		/* process button presses */
		if (cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN)
		    mouse_cut_start(cur_scp);
		else
		    mouse_cut_end(cur_scp);
		if (cur_scp->mouse_buttons & MOUSE_BUTTON2DOWN ||
		    cur_scp->mouse_buttons & MOUSE_BUTTON3DOWN)
		    mouse_paste(cur_scp);
	    }
#endif /* SC_NO_CUTPASTE */
	    break;

	case MOUSE_BUTTON_EVENT:
	    if ((mouse->u.event.id & MOUSE_BUTTONS) == 0)
		return EINVAL;
	    if (mouse->u.event.value < 0)
		return EINVAL;
#if 0
	    /* this should maybe only be settable from /dev/consolectl SOS */
	    if (SC_VTY(tp->t_dev) != SC_CONSOLECTL)
		return ENOTTY;
#endif
	    if (mouse->u.event.value > 0)
		cur_scp->mouse_buttons |= mouse->u.event.id;
	    else
		cur_scp->mouse_buttons &= ~mouse->u.event.id;

	    if (sysmouse_event(mouse) == 0)
		return 0;

	    /* if a button is held down, stop the screen saver */
	    if (mouse->u.event.value > 0)
		sc_touch_scrn_saver();

	    cur_scp->status &= ~MOUSE_HIDDEN;

	    if (cur_scp->mouse_signal) {
		if (cur_scp->mouse_proc && 
		    (cur_scp->mouse_proc != pfindn(cur_scp->mouse_pid))){
			oproc = cur_scp->mouse_proc;
		    	cur_scp->mouse_signal = 0;
			cur_scp->mouse_proc = NULL;
			cur_scp->mouse_pid = 0;
			if (oproc)
				PRELE(oproc);
		} else {
		    ksignal(cur_scp->mouse_proc, cur_scp->mouse_signal);
		    break;
		}
	    }

	    if (ISGRAPHSC(cur_scp) || (cut_buffer == NULL))
		break;

#ifndef SC_NO_CUTPASTE
	    switch (mouse->u.event.id) {
	    case MOUSE_BUTTON1DOWN:
	        switch (mouse->u.event.value % 4) {
		case 0:	/* up */
		    mouse_cut_end(cur_scp);
		    break;
		case 1: /* single click: start cut operation */
		    mouse_cut_start(cur_scp);
		    break;
		case 2:	/* double click: cut a word */
		    mouse_cut_word(cur_scp);
		    mouse_cut_end(cur_scp);
		    break;
		case 3:	/* triple click: cut a line */
		    mouse_cut_line(cur_scp);
		    mouse_cut_end(cur_scp);
		    break;
		}
		break;
	    case SC_MOUSE_PASTEBUTTON:
	        switch (mouse->u.event.value) {
		case 0:	/* up */
		    break;
		default:
		    mouse_paste(cur_scp);
		    break;
		}
		break;
	    case SC_MOUSE_EXTENDBUTTON:
	        switch (mouse->u.event.value) {
		case 0:	/* up */
		    if (!(cur_scp->mouse_buttons & MOUSE_BUTTON1DOWN))
		        mouse_cut_end(cur_scp);
		    break;
		default:
		    mouse_cut_extend(cur_scp);
		    break;
		}
		break;
	    }
#endif /* SC_NO_CUTPASTE */
	    break;

	case MOUSE_MOUSECHAR:
	    if (mouse->u.mouse_char < 0) {
		mouse->u.mouse_char = scp->sc->mouse_char;
	    } else {
		if (mouse->u.mouse_char >= (unsigned char)-1 - 4)
		    return EINVAL;
		crit_enter();
		sc_remove_all_mouse(scp->sc);
#ifndef SC_NO_FONT_LOADING
		if (ISTEXTSC(cur_scp) && (cur_scp->font != NULL))
		    sc_load_font(cur_scp, 0, cur_scp->font_size, cur_scp->font,
				 cur_scp->sc->mouse_char, 4);
#endif
		scp->sc->mouse_char = mouse->u.mouse_char;
		crit_exit();
	    }
	    break;

	default:
	    return EINVAL;
	}

	return 0;
    }

    return ENOIOCTL;
}
Exemplo n.º 3
0
int
sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
{
    scr_stat *scp;
    video_adapter_t *adp;
    video_info_t info;
    video_adapter_info_t adp_info;
    int error;
    int s;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    int ival;
#endif

    scp = SC_STAT(tp);
    if (scp == NULL)		/* tp == SC_MOUSE */
        return ENOIOCTL;
    adp = scp->sc->adp;
    if (adp == NULL)		/* shouldn't happen??? */
        return ENODEV;

    switch (cmd) {

    case CONS_CURRENTADP:	/* get current adapter index */
    case FBIO_ADAPTER:
        return fb_ioctl(adp, FBIO_ADAPTER, data);

    case CONS_CURRENT:  	/* get current adapter type */
    case FBIO_ADPTYPE:
        return fb_ioctl(adp, FBIO_ADPTYPE, data);

    case OLD_CONS_ADPINFO:	/* adapter information (old interface) */
        if (((old_video_adapter_t *)data)->va_index >= 0) {
            adp = vid_get_adapter(((old_video_adapter_t *)data)->va_index);
            if (adp == NULL)
                return ENODEV;
        }
        ((old_video_adapter_t *)data)->va_index = adp->va_index;
        ((old_video_adapter_t *)data)->va_type = adp->va_type;
        ((old_video_adapter_t *)data)->va_flags = adp->va_flags;
        ((old_video_adapter_t *)data)->va_crtc_addr = adp->va_crtc_addr;
        ((old_video_adapter_t *)data)->va_window = adp->va_window;
        ((old_video_adapter_t *)data)->va_window_size = adp->va_window_size;
        ((old_video_adapter_t *)data)->va_window_gran = adp->va_window_gran;
        ((old_video_adapter_t *)data)->va_buffer = adp->va_buffer;
        ((old_video_adapter_t *)data)->va_buffer_size = adp->va_buffer_size;
        ((old_video_adapter_t *)data)->va_mode = adp->va_mode;
        ((old_video_adapter_t *)data)->va_initial_mode = adp->va_initial_mode;
        ((old_video_adapter_t *)data)->va_initial_bios_mode
            = adp->va_initial_bios_mode;
        return 0;

    case OLD_CONS_ADPINFO2:	/* adapter information (yet another old I/F) */
        adp_info.va_index = ((old_video_adapter_info_t *)data)->va_index;
        if (adp_info.va_index >= 0) {
            adp = vid_get_adapter(adp_info.va_index);
            if (adp == NULL)
                return ENODEV;
        }
        error = fb_ioctl(adp, FBIO_ADPINFO, &adp_info);
        if (error == 0)
            bcopy(&adp_info, data, sizeof(old_video_adapter_info_t));
        return error;

    case CONS_ADPINFO:		/* adapter information */
    case FBIO_ADPINFO:
        if (((video_adapter_info_t *)data)->va_index >= 0) {
            adp = vid_get_adapter(((video_adapter_info_t *)data)->va_index);
            if (adp == NULL)
                return ENODEV;
        }
        return fb_ioctl(adp, FBIO_ADPINFO, data);

    case CONS_GET:      	/* get current video mode */
    case FBIO_GETMODE:
        *(int *)data = scp->mode;
        return 0;

#ifndef SC_NO_MODE_CHANGE
    case FBIO_SETMODE:		/* set video mode */
        if (!(adp->va_flags & V_ADP_MODECHANGE))
            return ENODEV;
        info.vi_mode = *(int *)data;
        error = fb_ioctl(adp, FBIO_MODEINFO, &info);
        if (error)
            return error;
        if (info.vi_flags & V_INFO_GRAPHICS)
            return sc_set_graphics_mode(scp, tp, *(int *)data);
        else
            return sc_set_text_mode(scp, tp, *(int *)data, 0, 0, 0, 0);
#endif /* SC_NO_MODE_CHANGE */

    case OLD_CONS_MODEINFO:	/* get mode information (old infterface) */
        info.vi_mode = ((old_video_info_t *)data)->vi_mode;
        error = fb_ioctl(adp, FBIO_MODEINFO, &info);
        if (error == 0)
            bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t));
        return error;

    case CONS_MODEINFO:		/* get mode information */
    case FBIO_MODEINFO:
        return fb_ioctl(adp, FBIO_MODEINFO, data);

    case OLD_CONS_FINDMODE:	/* find a matching video mode (old interface) */
        bzero(&info, sizeof(info));
        bcopy((old_video_info_t *)data, &info, sizeof(old_video_info_t));
        error = fb_ioctl(adp, FBIO_FINDMODE, &info);
        if (error == 0)
            bcopy(&info, (old_video_info_t *)data, sizeof(old_video_info_t));
        return error;

    case CONS_FINDMODE:		/* find a matching video mode */
    case FBIO_FINDMODE:
        return fb_ioctl(adp, FBIO_FINDMODE, data);

#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('c', 104):
        ival = IOCPARM_IVAL(data);
        data = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    case CONS_SETWINORG:	/* set frame buffer window origin */
    case FBIO_SETWINORG:
        if (scp != scp->sc->cur_scp)
            return ENODEV;	/* XXX */
        return fb_ioctl(adp, FBIO_SETWINORG, data);

    case FBIO_GETWINORG:	/* get frame buffer window origin */
        if (scp != scp->sc->cur_scp)
            return ENODEV;	/* XXX */
        return fb_ioctl(adp, FBIO_GETWINORG, data);

    case FBIO_GETDISPSTART:
    case FBIO_SETDISPSTART:
    case FBIO_GETLINEWIDTH:
    case FBIO_SETLINEWIDTH:
        if (scp != scp->sc->cur_scp)
            return ENODEV;	/* XXX */
        return fb_ioctl(adp, cmd, data);

    case FBIO_GETPALETTE:
    case FBIO_SETPALETTE:
    case FBIOPUTCMAP:
    case FBIOGETCMAP:
    case FBIOGTYPE:
    case FBIOGATTR:
    case FBIOSVIDEO:
    case FBIOGVIDEO:
    case FBIOSCURSOR:
    case FBIOGCURSOR:
    case FBIOSCURPOS:
    case FBIOGCURPOS:
    case FBIOGCURMAX:
        if (scp != scp->sc->cur_scp)
            return ENODEV;	/* XXX */
        return fb_ioctl(adp, cmd, data);

    case FBIO_BLANK:
        if (scp != scp->sc->cur_scp)
            return ENODEV;	/* XXX */
        return fb_ioctl(adp, cmd, data);

#ifndef SC_NO_MODE_CHANGE
    /* generic text modes */
    case SW_TEXT_80x25:
    case SW_TEXT_80x30:
    case SW_TEXT_80x43:
    case SW_TEXT_80x50:
    case SW_TEXT_80x60:
    /* FALLTHROUGH */

    /* VGA TEXT MODES */
    case SW_VGA_C40x25:
    case SW_VGA_C80x25:
    case SW_VGA_M80x25:
    case SW_VGA_C80x30:
    case SW_VGA_M80x30:
    case SW_VGA_C80x50:
    case SW_VGA_M80x50:
    case SW_VGA_C80x60:
    case SW_VGA_M80x60:
    case SW_VGA_C90x25:
    case SW_VGA_M90x25:
    case SW_VGA_C90x30:
    case SW_VGA_M90x30:
    case SW_VGA_C90x43:
    case SW_VGA_M90x43:
    case SW_VGA_C90x50:
    case SW_VGA_M90x50:
    case SW_VGA_C90x60:
    case SW_VGA_M90x60:
    case SW_B40x25:
    case SW_C40x25:
    case SW_B80x25:
    case SW_C80x25:
    case SW_ENH_B40x25:
    case SW_ENH_C40x25:
    case SW_ENH_B80x25:
    case SW_ENH_C80x25:
    case SW_ENH_B80x43:
    case SW_ENH_C80x43:
    case SW_EGAMONO80x25:

#ifdef PC98
    /* PC98 TEXT MODES */
    case SW_PC98_80x25:
    case SW_PC98_80x30:
#endif
        if (!(adp->va_flags & V_ADP_MODECHANGE))
            return ENODEV;
        return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0, 0);

    /* GRAPHICS MODES */
    case SW_BG320:
    case SW_BG640:
    case SW_CG320:
    case SW_CG320_D:
    case SW_CG640_E:
    case SW_CG640x350:
    case SW_ENH_CG640:
    case SW_BG640x480:
    case SW_CG640x480:
    case SW_VGA_CG320:
    case SW_VGA_MODEX:
#ifdef PC98
    /* PC98 GRAPHICS MODES */
    case SW_PC98_EGC640x400:
    case SW_PC98_PEGC640x400:
    case SW_PC98_PEGC640x480:
#endif
        if (!(adp->va_flags & V_ADP_MODECHANGE))
            return ENODEV;
        return sc_set_graphics_mode(scp, tp, cmd & 0xff);
#endif /* SC_NO_MODE_CHANGE */

#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 10):
        ival = IOCPARM_IVAL(data);
        data = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    case KDSETMODE:     	/* set current mode of this (virtual) console */
        switch (*(int *)data) {
        case KD_TEXT:   	/* switch to TEXT (known) mode */
            /*
             * If scp->mode is of graphics modes, we don't know which
             * text mode to switch back to...
             */
            if (scp->status & GRAPHICS_MODE)
                return EINVAL;
            /* restore fonts & palette ! */
#if 0
#ifndef SC_NO_FONT_LOADING
            if (ISFONTAVAIL(adp->va_flags)
                    && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
                /*
                 * FONT KLUDGE
                 * Don't load fonts for now... XXX
                 */
                if (scp->sc->fonts_loaded & FONT_8)
                    sc_load_font(scp, 0, 8, 8, scp->sc->font_8, 0, 256);
            if (scp->sc->fonts_loaded & FONT_14)
                sc_load_font(scp, 0, 14, 8, scp->sc->font_14, 0, 256);
            if (scp->sc->fonts_loaded & FONT_16)
                sc_load_font(scp, 0, 16, 8, scp->sc->font_16, 0, 256);
        }
#endif /* SC_NO_FONT_LOADING */
#endif

#ifndef SC_NO_PALETTE_LOADING
        vidd_load_palette(adp, scp->sc->palette);
#endif

#ifndef PC98
        /* move hardware cursor out of the way */
        vidd_set_hw_cursor(adp, -1, -1);
#endif

    /* FALLTHROUGH */

    case KD_TEXT1:  	/* switch to TEXT (known) mode */
        /*
         * If scp->mode is of graphics modes, we don't know which
         * text/pixel mode to switch back to...
         */
        if (scp->status & GRAPHICS_MODE)
            return EINVAL;
        s = spltty();
        if ((error = sc_clean_up(scp))) {
            splx(s);
            return error;
        }
#ifndef PC98
        scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
        splx(s);
        /* no restore fonts & palette */
        if (scp == scp->sc->cur_scp)
            set_mode(scp);
        sc_clear_screen(scp);
        scp->status &= ~UNKNOWN_MODE;
#else /* PC98 */
        scp->status &= ~UNKNOWN_MODE;
        /* no restore fonts & palette */
        if (scp == scp->sc->cur_scp)
            set_mode(scp);
        sc_clear_screen(scp);
        splx(s);
#endif /* PC98 */
        return 0;

#ifdef SC_PIXEL_MODE
    case KD_PIXEL:		/* pixel (raster) display */
        if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
            return EINVAL;
        if (scp->status & GRAPHICS_MODE)
            return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
                                     scp->font_size, scp->font_width);
        s = spltty();
        if ((error = sc_clean_up(scp))) {
            splx(s);
            return error;
        }
        scp->status |= (UNKNOWN_MODE | PIXEL_MODE | MOUSE_HIDDEN);
        splx(s);
        if (scp == scp->sc->cur_scp) {
            set_mode(scp);
#ifndef SC_NO_PALETTE_LOADING
            vidd_load_palette(adp, scp->sc->palette);
#endif
        }
        sc_clear_screen(scp);
        scp->status &= ~UNKNOWN_MODE;
        return 0;
#endif /* SC_PIXEL_MODE */

    case KD_GRAPHICS:	/* switch to GRAPHICS (unknown) mode */
        s = spltty();
        if ((error = sc_clean_up(scp))) {
            splx(s);
            return error;
        }
        scp->status |= UNKNOWN_MODE | MOUSE_HIDDEN;
        splx(s);
#ifdef PC98
        if (scp == scp->sc->cur_scp)
            set_mode(scp);
#endif
        return 0;

    default:
        return EINVAL;
    }
    /* NOT REACHED */

#ifdef SC_PIXEL_MODE
case KDRASTER:		/* set pixel (raster) display mode */
    if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
        return ENODEV;
    return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
                             ((int *)data)[2], 8);
#endif /* SC_PIXEL_MODE */

case KDGETMODE:     	/* get current mode of this (virtual) console */
    /*
     * From the user program's point of view, KD_PIXEL is the same
     * as KD_TEXT...
     */
    *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
    return 0;

#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
case _IO('K', 13):
    ival = IOCPARM_IVAL(data);
    data = (caddr_t)&ival;
    /* FALLTHROUGH */
#endif
case KDSBORDER:     	/* set border color of this (virtual) console */
    scp->border = *(int *)data;
    if (scp == scp->sc->cur_scp)
        sc_set_border(scp, scp->border);
    return 0;
}