Esempio n. 1
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;
}
Esempio n. 2
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;
}